redis五大类型的底层数据结构和应用场景

6 阅读4分钟

String

value 可以是字符串, 也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M

底层的数据结构实现主要是 int 和 SDS(简单动态字符串)

  • 字符串对象的内部编码(encoding)有 3 种 :intrawembstr
  • 如果字符串对象保存的是一个字符串,长度小于等于 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 数据结构来实现了。

资料