Redis Zset 的内存博弈:如何支撑秒级排行榜?

95 阅读2分钟

Redis 的 Zset

回答

  • ZSet(Sorted Set)内部维护了一个有序的字典,这个字典的元素中既包括了一个成员(member),也包括了一个double类型的分值(score)。

    这种结构可以帮助用户实现记分类型的排行榜数据。

    比如:游戏分数排行榜,网站流行度排行等。

  • Redis 中的 ZSet 在实现中,有多种结构。

image-20250328112025161

  • ZSet 如何选择存储结构?

    • 当 ZSet 的元素数量比较少时,Redis会采用 ZipList(ListPack) 来存储ZSet的数据。

      ZipList(ListPack)是一种紧的列表结构,它通过连续存储元素来节约内存空间。

    • 当 ZSet 的元素数量增多时,Redis会自动将 ZipList(ListPack)转换为SkipList,以保持元素的有序性和支持范围查询操作。

      在这个转换过程中,Redis 会历 ZipList(ListPack)中的所有元素,按照元素的分数值依次将它们插入到 SkipList 中,这样就可以保持元素的有序性。

  • 在 Redis 的 ZSet 具体实现中,不仅用到了SkipList (跳表) ,还会用到 dict(字典)

image-20250328111838166

扩展

1、ZipList(ListPack)-> SkipList,如何转换的呢?
  1. 元素数量少

    集合中的元素数量必须小于某个值

    (zset-max-ziplist-entries)

    zset-max-ziplist-entries 默认是 128

  2. 元素大小小

    集合中的每个元素(包括值和分数)的大小必须小于指定的最大值

    (zset-max-ziplist-value)

    zset-max-ziplist-value 默认是 64

  3. 总体来说,当元素数量少于 128,每个元素的长度都小于 64 字节的时候,使用ZipList(ListPack),否则,使用 SkipList。

2、跳表