一、官网文档介绍 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis-Key Redis的一些命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 127.0.0.1:6379> keys * (empty list or set ) 127.0.0.1:6379> set name Blue OK 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> set age 1 OK 127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379> EXISTS name (integer ) 1 127.0.0.1:6379> EXISTS name1 (integer ) 0 127.0.0.1:6379> move name 1 (integer ) 1 127.0.0.1:6379> keys * 1) "age" 127.0.0.1:6379> set name qinjiang OK 127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379> clear 127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379> get name "qinjiang" 127.0.0.1:6379> EXPIRE name 10 (integer ) 1 127.0.0.1:6379> ttl name (integer ) 4 127.0.0.1:6379> ttl name (integer ) 3 127.0.0.1:6379> ttl name (integer ) 2 127.0.0.1:6379> ttl name (integer ) 1 127.0.0.1:6379> ttl name (integer ) -2 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> type name string 127.0.0.1:6379> type age string
后面如果遇到不会的命令,可以在官网查看帮助文档!
二、String(字符串) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 127.0.0.1:6379> set key1 v1 OK 127.0.0.1:6379> get key1 "v1" 127.0.0.1:6379> keys * 1) "key1" 127.0.0.1:6379> EXISTS key1 (integer ) 1 127.0.0.1:6379> APPEND key1 "hello" (integer ) 7 127.0.0.1:6379> get key1 "v1hello" 127.0.0.1:6379> STRLEN key1 (integer ) 7 127.0.0.1:6379> APPEND key1 ",Blue" (integer ) 17 127.0.0.1:6379> STRLEN key1 (integer ) 17 127.0.0.1:6379> get key1 "v1hello,Blue" 127.0.0.1:6379> set views 0 OK 127.0.0.1:6379> get views "0" 127.0.0.1:6379> incr views (integer ) 1 127.0.0.1:6379> incr views (integer ) 2 127.0.0.1:6379> get views "2" 127.0.0.1:6379> decr views (integer ) 1 127.0.0.1:6379> decr views (integer ) 0 127.0.0.1:6379> decr views (integer ) -1 127.0.0.1:6379> get views "-1" 127.0.0.1:6379> INCRBY views 10 (integer ) 9 127.0.0.1:6379> INCRBY views 10 (integer ) 19 127.0.0.1:6379> DECRBY views 5 (integer ) 14 127.0.0.1:6379> set key1 "hello,Blue" OK 127.0.0.1:6379> get key1 "hello,Blue" 127.0.0.1:6379> GETRANGE key1 0 3 "hell" 127.0.0.1:6379> GETRANGE key1 0 -1 "hello,Blue" 127.0.0.1:6379> set key2 abcdefg OK 127.0.0.1:6379> get key2 "abcdefg" 127.0.0.1:6379> SETRANGE key2 1 xx (integer ) 7 127.0.0.1:6379> get key2 "axxdefg" 127.0.0.1:6379> setex key3 30 "hello" OK 127.0.0.1:6379> ttl key3 (integer ) 26 127.0.0.1:6379> get key3 "hello" 127.0.0.1:6379> setnx mykey "redis" (integer ) 1 127.0.0.1:6379> keys * 1) "key2" 2) "mykey" 3) "key1" 127.0.0.1:6379> ttl key3 (integer ) -2 127.0.0.1:6379> setnx mykey "MongoDB" (integer ) 0 127.0.0.1:6379> get mykey "redis" mset mget 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> keys * 1) "k1" 2) "k2" 3) "k3" 127.0.0.1:6379> mget k1 k2 k3 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379> msetnx k1 v1 k4 v4 失败! (integer ) 0 127.0.0.1:6379> get k4 (nil) set user:1 {name:zhangsan,age:3} 127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2 OK 127.0.0.1:6379> mget user:1:name user:1:age 1) "zhangsan" 2) "2" getset 127.0.0.1:6379> getset db redis (nil) 127.0.0.1:6379> get db "redis" 127.0.0.1:6379> getset db mongodb "redis" 127.0.0.1:6379> get db "mongodb"
数据结构是相同的!
String类似的使用场景:value除了是我们的字符串还可以是我们的数字!
计数器
统计多单位的数量
粉丝数
对象缓存存储三、List(列表) 在redis里面,我们可以把list玩成 ,栈、队列、阻塞队列! 所有的list命令都是用l开头的,Redis不区分大小命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 127.0.0.1:6379> LPUSH list one (integer ) 1 127.0.0.1:6379> LPUSH list two (integer ) 2 127.0.0.1:6379> LPUSH list three (integer ) 3 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "two" 3) "one" 127.0.0.1:6379> LRANGE list 0 1 1) "three" 2) "two" 127.0.0.1:6379> Rpush list righr (integer ) 4 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "two" 3) "one" 4) "righr" LPOP RPOP 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "two" 3) "one" 4) "righr" 127.0.0.1:6379> Lpop list "three" 127.0.0.1:6379> Rpop list "righr" 127.0.0.1:6379> LRANGE list 0 -1 1) "two" 2) "one" Lindex 127.0.0.1:6379> LRANGE list 0 -1 1) "two" 2) "one" 127.0.0.1:6379> lindex list 1 "one" 127.0.0.1:6379> lindex list 0 "two" Llen 127.0.0.1:6379> Lpush list one (integer ) 1 127.0.0.1:6379> Lpush list two bilibili:狂神说Java (integer ) 2 127.0.0.1:6379> Lpush list three (integer ) 3 127.0.0.1:6379> Llen list (integer ) 3 移除指定的值! 取关 uid Lrem 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "three" 3) "two" 4) "one" 127.0.0.1:6379> lrem list 1 one (integer ) 1 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "three" 3) "two" 127.0.0.1:6379> lrem list 1 three (integer ) 1 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "two" 127.0.0.1:6379> Lpush list three (integer ) 3 127.0.0.1:6379> lrem list 2 three (integer ) 2 127.0.0.1:6379> LRANGE list 0 -1 1) "two" trim 修剪。; list 截断! 127.0.0.1:6379> keys * (empty list or set ) 127.0.0.1:6379> Rpush mylist "hello" (integer ) 1 127.0.0.1:6379> Rpush mylist "hello1" (integer ) 2 127.0.0.1:6379> Rpush mylist "hello2" (integer ) 3 127.0.0.1:6379> Rpush mylist "hello3" (integer ) 4 127.0.0.1:6379> ltrim mylist 1 2 只剩下截取的元素! OK 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello1" 2) "hello2" rpoplpush 127.0.0.1:6379> rpush mylist "hello" (integer ) 1 127.0.0.1:6379> rpush mylist "hello1" (integer ) 2 127.0.0.1:6379> rpush mylist "hello2" (integer ) 3 127.0.0.1:6379> rpoplpush mylist myotherlist 列表中! "hello2" 127.0.0.1:6379> lrange mylist 0 -1 1) "hello" 2) "hello1" 127.0.0.1:6379> lrange myotherlist 0 -1 1) "hello2" lset 将列表中指定下标的值替换为另外一个值,更新操作 127.0.0.1:6379> EXISTS list (integer ) 0 127.0.0.1:6379> lset list 0 item (error) ERR no such key 127.0.0.1:6379> lpush list value1 (integer ) 1 127.0.0.1:6379> LRANGE list 0 0 1) "value1" 127.0.0.1:6379> lset list 0 item OK 127.0.0.1:6379> LRANGE list 0 0 1) "item" 127.0.0.1:6379> lset list 1 other (error) ERR index out of range linsert 127.0.0.1:6379> Rpush mylist "hello" (integer ) 1 127.0.0.1:6379> Rpush mylist "world" (integer ) 2 127.0.0.1:6379> LINSERT mylist before "world" "other" (integer ) 3 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "other" 3) "world" 127.0.0.1:6379> LINSERT mylist after world new (integer ) 4 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "other" 3) "world" 4) "new"
小结
他实际上是一个链表,before Node after , left,right 都可以插入值
如果key 不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,空链表,也代表不存在!
在两边插入或者改动值,效率最高! 中间元素,相对来说效率会低一点~
消息排队!消息队列 (Lpush Rpop), 栈( Lpush Lpop)!
四、Set(集合) set中的值是不能重复的!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 127.0.0.1:6379> sadd myset "hello" (integer ) 1 127.0.0.1:6379> sadd myset "Blue" (integer ) 1 127.0.0.1:6379> sadd myset "loveBlue" (integer ) 1 127.0.0.1:6379> SMEMBERS myset 1) "hello" 2) "loveBlue" 3) "Blue" 127.0.0.1:6379> SISMEMBER myset hello (integer ) 1 127.0.0.1:6379> SISMEMBER myset world (integer ) 0 127.0.0.1:6379> scard myset (integer ) 4 rem 127.0.0.1:6379> srem myset hello (integer ) 1 127.0.0.1:6379> scard myset (integer ) 3 127.0.0.1:6379> SMEMBERS myset 1) "loveBlue2" 2) "loveBlue" 3) "Blue" set 无序不重复集合。抽随机!127.0.0.1:6379> SMEMBERS myset 1) "loveBlue2" 2) "loveBlue" 3) "Blue" 127.0.0.1:6379> SRANDMEMBER myset "Blue" 127.0.0.1:6379> SRANDMEMBER myset "Blue" 127.0.0.1:6379> SRANDMEMBER myset "Blue" 127.0.0.1:6379> SRANDMEMBER myset "Blue" 127.0.0.1:6379> SRANDMEMBER myset 2 1) "loveBlue" 2) "loveBlue2" 127.0.0.1:6379> SRANDMEMBER myset 2 1) "loveBlue" 2) "loveBlue2" 127.0.0.1:6379> SRANDMEMBER myset "loveBlue2" 删除定的key,随机删除key! 127.0.0.1:6379> SMEMBERS myset 1) "loveBlue2" 2) "loveBlue" 3) "Blue" 127.0.0.1:6379> spop myset "loveBlue2" 127.0.0.1:6379> spop myset "loveBlue" 127.0.0.1:6379> SMEMBERS myset 1) "Blue" 将一个指定的值,移动到另外一个set 集合! 127.0.0.1:6379> sadd myset "hello" (integer ) 1 127.0.0.1:6379> sadd myset "world" (integer ) 1 127.0.0.1:6379> sadd myset "Blue" (integer ) 1 127.0.0.1:6379> sadd myset2 "set2" (integer ) 1 127.0.0.1:6379> smove myset myset2 "Blue" 合! (integer ) 1 127.0.0.1:6379> SMEMBERS myset 1) "world" 2) "hello" 127.0.0.1:6379> SMEMBERS myset2 1) "Blue" 2) "set2" 微博,B站,共同关注!(并集) 数字集合类: - 差集 SDIFF - 交集 - 并集 127.0.0.1:6379> SDIFF key1 key2 1) "b" 2) "a" 127.0.0.1:6379> SINTER key1 key2 1) "c" 127.0.0.1:6379> SUNION key1 key2 1) "b" 2) "c" 3) "e" 4) "a" 5) "d"
微博,A用户将所有关注的人放在一个set集合中!将它的粉丝也放在一个集合中! 共同关注,共同爱好,二度好友,推荐好友!(六度分割理论)
五、Hash(哈希) Map集合,key-map! 时候这个值是一个map集合! 本质和String类型没有太大区别,还是一个简单的 key-vlaue!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 127.0.0.1:6379> hset myhash field1 Blue (integer ) 1 127.0.0.1:6379> hget myhash field1 "Blue" 127.0.0.1:6379> hmset myhash field1 hello field2 world OK 127.0.0.1:6379> hmget myhash field1 field2 1) "hello" 2) "world" 127.0.0.1:6379> hgetall myhash 1) "field1" 2) "hello" 3) "field2" 4) "world" 127.0.0.1:6379> hdel myhash field1 (integer ) 1 127.0.0.1:6379> hgetall myhash 1) "field2" 2) "world" hlen 127.0.0.1:6379> hmset myhash field1 hello field2 world OK 127.0.0.1:6379> HGETALL myhash 1) "field2" 2) "world" 3) "field1" 4) "hello" 127.0.0.1:6379> hlen myhash (integer ) 2 127.0.0.1:6379> HEXISTS myhash field1 (integer ) 1 127.0.0.1:6379> HEXISTS myhash field3 (integer ) 0 127.0.0.1:6379> hkeys myhash 1) "field2" 2) "field1" 127.0.0.1:6379> hvals myhash 1) "world" 2) "hello" incr decr 127.0.0.1:6379> hset myhash field3 5 (integer ) 1 127.0.0.1:6379> HINCRBY myhash field3 1 (integer ) 6 127.0.0.1:6379> HINCRBY myhash field3 -1 (integer ) 5 127.0.0.1:6379> hsetnx myhash field4 hello (integer ) 1 127.0.0.1:6379> hsetnx myhash field4 world (integer ) 0
hash变更的数据 user name age,尤其是是用户信息之类的,经常变动的信息! hash 更适合于对象的 存储,String更加适合字符串存储!
六、Zset(有序集合) 在set的基础上,增加了一个值,set k1 v1 zset k1 score1 v1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 127.0.0.1:6379> zadd myset 1 one (integer ) 1 127.0.0.1:6379> zadd myset 2 two 3 three (integer ) 2 127.0.0.1:6379> ZRANGE myset 0 -1 1) "one" 2) "two" 3) "three" 排序如何实现 127.0.0.1:6379> zadd salary 2500 xiaohong (integer ) 1 127.0.0.1:6379> zadd salary 5000 zhangsan (integer ) 1 127.0.0.1:6379> zadd salary 500 Blue (integer ) 1 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf 1) "Blue" 2) "xiaohong" 3) "zhangsan" 127.0.0.1:6379> ZREVRANGE salary 0 -1 1) "zhangsan" 2) "Blue" 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores 绩 1) "Blue" 2) "500" 3) "xiaohong" 4) "2500" 5) "zhangsan" 6) "5000" 127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores 序排序! 1) "Blue" 2) "500" 3) "xiaohong" 4) "2500" 127.0.0.1:6379> zrange salary 0 -1 1) "Blue" 2) "xiaohong" 3) "zhangsan" 127.0.0.1:6379> zrem salary xiaohong (integer ) 1 127.0.0.1:6379> zrange salary 0 -1 1) "Blue" 2) "zhangsan" 127.0.0.1:6379> zcard salary (integer ) 2 127.0.0.1:6379> zadd myset 1 hello (integer ) 1 127.0.0.1:6379> zadd myset 2 world 3 Blue (integer ) 2 127.0.0.1:6379> zcount myset 1 3 (integer ) 3 127.0.0.1:6379> zcount myset 1 2 (integer ) 2
案例思路:set 排序 存储班级成绩表,工资表排序! 普通消息,1, 重要消息 2,带权重进行判断! 排行榜应用实现。