跳到主要内容

Redis底层数据结构

Redis常见的五种数据结构是String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)。

String

应用场景:

  • 缓存对象

  • 常规计数,单线程,计算访问次数、点赞、转发、库存数量等等

  • 分布式锁set key value nx px 10000

SDS

特点:

  • SDS 不仅可以保存文本数据,还可以保存二进制数据
  • SDS 获取字符串长度的时间复杂度是 O(1)
  • Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出

SDS实现原理

Hash

应用场景:

  • 缓存对象,根string差不多,但是修改容易
  • 购物车实现商品数量

底层数据结构:

  • 哈希类型元素个数小于 512 个,所有值小于 64 字节,Redis 会使用压缩列表作为 Hash 类型的底层数据结构
  • 不满足,使用哈希表

Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了

压缩列表实现原理

哈希表实现原理

List

应用场景:

  • 消息队列(消息保序、处理重复消息、消息可靠性),

    • 消息保序:使用lpush rpop实现,使用brpop代替rpop节省CPU开销。
    • 阻塞读取:brpop
    • 处理重复消息:每个消息有全局ID,消费者记录处理过的ID,ID需要自己生成
    • 消息可靠性:brpoplpush让消费者从一个List中读取,同时放到另一个List留存
    • 缺陷:不支持多个消费者消费同一消息,不支持 消费组实现

底层数据结构:

  • 如果列表的元素个数小于 512 个,每个元素的值都小于 64 字节,使用压缩列表作为 List 类型的底层数据结构
  • 不满足上面的条件,使用双向链表

Redis 3.2 版本之后,List 数据类型底层数据结构就只由 quicklist 实现了,替代了双向链表和压缩列表

压缩列表实现原理

双向链表实现原理

Set

应用场景:

  • 点赞:保证一个用户只能点一次
  • 共同关注:Set支持交集运算 ,计算共同关注,公众号等。
  • 抽奖活动:存储中奖用户,Set会去重,不会中奖2次

底层数据结构:

  • 元素个数小于 512,使用整数集合
  • 不满足,使用哈希表

整数集合实现原理

哈希表实现原理

Zset

Zset的应用场景:排行榜

Zset的底层数据结构是由压缩列表或跳表实现,7.0中压缩列表已经更换为listpack

  • 元素个数小于 128 个,每个元素的值小于 64 字节时,使用压缩列表作为 Zset 类型的底层数据结构
  • 否则,使用跳表

跳表实现原理

压缩列表实现原理