Redis 常用五种数据类型编码
转载请注明出处:
Redis 的五种数据结构
Redis 数据结构的内部编码
Redis这样设计有两个好处:
第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令。
第二,多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。
1.String
1.1 常用命令
(1)设置值
set key value [ex seconds] [px milliseconds] [nx|xx]
set命令有几个选项:
-
ex seconds:为键设置秒级过期时间。
-
px milliseconds:为键设置毫秒级过期时间。
-
nx:键必须不存在,才可以设置成功,用于添加。
-
xx:与nx相反,键必须存在,才可以设置成功,用于更新。
除了set选项,Redis还提供了setex和setnx两个命令
(2)获取值
get key
(3)批量设置值
mset key value [key value ...]
(4)批量获取值
mget key [key ...]
(5)计数
incr key
incr命令用于对值做自增操作,返回结果分为三种情况:
-
值不是整数,返回错误。
-
值是整数,返回自增后的结果。
-
键不存在,按照值为0自增,返回结果为1。
除了incr命令,Redis提供了decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数);
(6)字符串长度
strlen key
1.2 内部编码
字符串类型的内部编码有3种:
-
int:8个字节的长整型。
-
embstr:小于等于39个字节的字符串。
-
raw:大于39个字节的字符串。
Redis会根据当前值的类型和长度决定使用哪种内部编码实现。
# 小于等于39个字节的字符串:embstr
127.0.0.1:6379> set key "hello,world"
OK
127.0.0.1:6379> object encoding key
"embstr"
1.3 典型使用场景
1.缓存功能
Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
2.计数
3.共享Session
用Redis将用户的Session进行集中管理,只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。
4.限速
限制接口不被频繁访问
2. Hash
2.1 常用命令及时间复杂度
2.2 内部编码
哈希类型的内部编码有两种:
-
ziplist(压缩列表)
-
hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"
3.列表
3.1 常用命令及时间复杂度
3.2 内部编码
列表类型的内部编码有两种。
-
ziplist(压缩列表)
-
linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
127.0.0.1:6379> rpush listkey e1 e2 e3 (integer) 3 127.0.0.1:6379> object encoding listkey "ziplist"
3.3 使用场景
1.消息队列
Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
2.文章列表
每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。
4.集合
4.1 常用命令及时间复杂度
集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。
Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多实际问题。
SADD key member [member ...] //往集合key中存入元素,元素存在则忽略,若key不存在则新建
SREM key member [member ...] //从集合key中删除元素
SMEMBERS key //获取集合key中所有元素
SCARD key //获取集合key的元素个数,scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用Redis内部的变量
SISMEMBER key member //判断member元素是否存在于集合key中
SRANDMEMBER key [count] //从集合key中选出count个元素,元素不从key中删除
SPOP key [count] //从集合key中选出count个元素,元素从key中删除
Set 运算命令
SINTER key [key ...] //交集运算
SINTERSTORE destination key [key ..] //将交集结果存入新集合destination中
SUNION key [key ..] //并集运算
SUNIONSTORE destination key [key ...] //将并集结果存入新集合destination中
SDIFF key [key ...] //差集运算
SDIFFSTORE destination key [key ...] //将差集结果存入新集合destination中
4.2 内部编码
集合类型的内部编码有两种:
-
hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 4
127.0.0.1:6379> object encoding setkey
"intset"
1. 微博点赞,收藏,标签(给用户添加标签,给标签添加用户),计算用户共同感兴趣的标签
2. 微博或微信中可能认识的人,共同好友,共同关注的话题等。
5.有序集合
5.1 常用命令
它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为 排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。有序集合中的元素不能重复,但是score可以重复;有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能
ZADD key score member [[score member]…] //往有序集合key中加入带分值元素
ZREM key member [member …] //从有序集合key中删除元素
ZSCORE key member //返回有序集合key中元素member的分值
ZINCRBY key increment member //为有序集合key中元素member的分值加上increment
ZCARD key //返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES] //正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES] //倒序获取有序集合key从start下标到stop下标的元素
ZUNIONSTORE destkey numkeys key [key ...] //并集计算
ZINTERSTORE destkey numkeys key [key …] //交集计算
5.2 内部编码
有序集合类型的内部编码有两种:
-
ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。
-
skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3
(integer) 3
127.0.0.1:6379> object encoding zsetkey
"ziplist"
5.3 使用场景
榜单排名,热点排名