String
value 可以是字符串, 也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M
底层的数据结构实现主要是 int 和 SDS(简单动态字符串)
- 字符串对象的内部编码(encoding)有 3 种 :
int
、raw
和embstr
- 如果字符串对象保存的是一个字符串,长度小于等于 M 字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串,并将对象的编码设置为embstr
- 字符串的长度大于 M 字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串,并将对象的编码设置为raw
- M 在 redis 不同版本中是不一样的:
- redis 2.+ 是 32 字节
- redis 3.0-4.0 是 39 字节
- redis 5.0 是 44 字节
- embstr和raw编码都会使用SDS来保存值,但不同之处在于embstr会通过一次内存分配函数来分配一块连续的内存空间来保存redisObject和SDS,而raw编码会通过调用两次内存分配函数来分别分配两块空间来保存redisObject和SDS
应用场景:
- 缓存对象
- 常规计数
- 计算访问次数、点赞、转发、库存数量
- 分布式锁
- 共享 Session 信息
- 会话(登录)状态
List
List 类型的底层数据结构是由双向链表
或压缩列表 ziplist
实现的
- 如果列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节,Redis 会使用
压缩列表
作为 List 类型的底层数据结构;- 元素个数 512 个(默认值,可由 list-max-ziplist-entries 配置)
- 元素的值小于 64 字节(默认值,可由 list-max-ziplist-value 配置)
- 如果列表的元素不满足上面的条件,Redis 会使用双向链表作为 List 类型的底层数据结构;
- 在 Redis 3.2 版本之后,List 数据类型底层数据结构就只由
quicklist
实现了,替代了双向链表和压缩列表
应用场景:
- 消息队列
- 消息保序:使用 LPUSH + RPOP;
- 阻塞读取:使用 BRPOP;
- 重复消息处理:生产者自行实现全局唯一 ID;
- 消息的可靠性:使用 BRPOPLPUSH
- 不支持多个消费者消费同一条消息
- Stream 同样能够满足消息队列的三大需求,而且它还支持「消费组」形式的消息读取
- 实现栈和队列
- 时间线或活动流
Hash
- 如果哈希类型元素个数小于 512 个,所有值小于 64 字节的话,Redis 会使用
压缩列表
作为 Hash 类型的底层数据结构;- 元素个数 512 个(默认值,可由 hash-max-ziplist-entries 配置)
- 所有值小于 64 字节(默认值,可由 hash-max-ziplist-value 配置)
- 如果哈希类型元素不满足上面条件,Redis 会使用
哈希表
作为 Hash 类型的 底层数据结构。 - 在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由
listpack
数据结构来实现了。
应用场景:
- 缓存对象
- 购物车
Set
Set 类型的底层数据结构是由哈希表
或整数集合
实现的:
- 如果集合中的元素都是整数且元素个数小于 512个,Redis 会使用整数集合作为 Set 类型的底层数据结构;
- 元素个数小于 512 (默认值,set-maxintset-entries配置)
- 如果集合中的元素不满足上面条件,则 Redis 使用
哈希表
作为 Set 类型的底层数据结构。
应用场景:
- 点赞 (key 是文章id,value 是用户id)
- 共同关注 (支持交集运算)
- 抽奖活动 (去重功能)
Zset
Zset 类型的底层数据结构是由压缩列表
或跳表
实现的:
- 如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构;
- 如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构;
- 在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由
listpack
数据结构来实现了。