当前位置: 首页 > news >正文

Redis ZSet 实现原理与跳表选择原因

在这里插入图片描述


一、ZSet 的底层实现

Redis 的有序集合(ZSet)采用 两种数据结构组合 实现,具体选择依据数据规模和元素大小:

  1. 压缩列表(ziplist)

    • 适用条件:元素数量 ≤ zset-max-ziplist-entries(默认 128)且每个元素大小 ≤ zset-max-ziplist-value(默认 64 字节)。
    • 存储方式:元素和分值按顺序交替存储,内存紧凑,适合小规模数据。
    • 示例:插入 [score1, member1, score2, member2],通过顺序遍历实现范围查询。
  2. 跳表(skiplist)+ 哈希表

    • 适用条件:不满足压缩列表条件时自动切换。
    • 跳表(zskiplist):负责维护元素的有序性和高效范围查询(如 ZRANGE)。
    • 哈希表(dict):存储 member→score 映射,支持 O(1) 复杂度单点查询(如 ZSCORE)。
    • 协作流程:插入或更新数据时,同时修改跳表和哈希表,确保数据一致性。

二、跳表的核心设计

  1. 跳表结构

    • 多层索引:节点随机生成层级(1~32 层),高层索引加速跨节点跳跃。
    • 节点组成:包含分值(score)、成员(member)、后退指针(backward)、层数组(level)指向后续节点。
    • 示例:查找元素时,从最高层索引逐层向下缩小范围,平均时间复杂度 O(logN)
  2. 跳表操作特性

    • 插入:随机生成层高,逐层更新前后指针,保持索引连续性。
    • 删除:定位节点后移除各层索引,调整指针。
    • 范围查询:利用有序链表特性直接遍历,复杂度 O(logN + M)(M 为结果数量)。

三、为何选择跳表而非其他数据结构?

对比维度跳表平衡树(如红黑树)B+树
实现复杂度简单(无旋转/再平衡操作)复杂(需维护平衡因子、旋转逻辑)复杂(节点分裂/合并)
范围查询效率高效(链表顺序遍历)需中序遍历,效率较低适合磁盘顺序读,内存场景冗余
内存占用较低(概率性生成层数,平均空间冗余少)较高(每个节点需存储父/子指针及颜色)高(节点分裂导致额外空间消耗)
并发优化潜力易实现无锁(CAS 操作)需复杂锁机制锁粒度大,扩展性差

核心原因总结

  1. 工程友好性:跳表代码实现简单,调试和维护成本低,适合 Redis 的高性能需求。
  2. 范围查询优势:ZSet 的 ZRANGEZREVRANGE 等操作依赖有序链表遍历,跳表天然支持。
  3. 内存效率:跳表的层级通过概率生成(如 1/2 概率升层),相比平衡树减少额外指针开销。
  4. 动态扩展性:插入/删除时无需全局重构结构,局部调整即可,适合高并发场景。

四、压缩列表与跳表的协作逻辑

  1. 小数据优化:压缩列表通过连续内存节省空间,避免跳表的索引开销。
  2. 自动切换机制
    • 当元素数量或大小超过阈值时,Redis 将压缩列表转换为跳表+哈希表结构。
    • 转换过程:遍历压缩列表,依次插入跳表和哈希表,释放旧结构内存。

五、实际应用场景

  1. 排行榜:利用 ZRANGE 快速获取 TOP N 用户,结合 ZSCORE 实时更新分数。
  2. 延迟队列:以时间戳为 score,通过 ZRANGEBYSCORE 获取到期任务。
  3. 范围统计:如统计某时间段内的活跃用户(score 为时间戳)。

总结

Redis 的 ZSet 通过 压缩列表跳表+哈希表 的混合结构,在内存效率与操作性能之间取得平衡。跳表因其 实现简单、范围查询高效、动态扩展性强 的特点,成为 ZSet 的核心数据结构,尤其适合需要高频范围操作和高并发的场景。而压缩列表在小数据量时的优化,进一步提升了 Redis 的内存利用率。

http://www.xdnf.cn/news/291025.html

相关文章:

  • Lombok 是什么?
  • Python字符串全解析:从基础操作到高级应用的技术指南
  • 36-校园反诈系统(小程序)
  • K8S node ARP 表爆满 如何优化
  • 【深度学习-Day 6】掌握 NumPy:ndarray 创建、索引、运算与性能优化指南
  • git上常用的12个月份对应的英语单词以及月份英语缩写形式
  • [machine learning] Transformer - Attention (三)
  • C++ 检查某个点是否存在于圆扇区内(Check whether a point exists in circle sector or not)
  • 2025流感疫苗指南+卫健委诊疗方案|高危人群防护+并发症处理 慢性肾脏病饮食指南2025卫健委版|低盐低磷食谱+中医调理+PDF 网盘下载 pdf下载
  • Scala day6(Class,field,Single Object)
  • EPSG:3857 和 EPSG:4326 的区别
  • 掌纹图像识别:解锁人类掌纹/生物识别的未来——技术解析与前沿数据集探索
  • 2025系统架构师---论软件的设计模式论文
  • Java按字节长度截取字符串指南
  • JVM——Java对象的内存布局
  • Hive安装与配置教程
  • 详讲viewer查看器
  • Astro Canvas 数据中心→设备一览大屏操作指南
  • 基于 HTML5 的贪吃蛇小游戏实现
  • Oracle数据库从入门到掌握基础应用能力
  • 16. Qt系统相关:事件、定时器
  • 金融的本质是智融、融资的实质是融智、投资的关键是投智,颠覆传统金融学的物质资本中心论,构建了以智力资本为核心的新范式
  • 启发式算法-禁忌搜索算法
  • Python学习之路(七)-绘画and动画
  • 使用 JavaScript 实现数据导出为 Excel 和 CSV 文件
  • Ultra7-265K 和 技嘉Z890M-AORUS-ELITE-WIFI7主板 简单开箱测评
  • 《Python星球日记》第29天:Flask进阶
  • Unity-Shader详解-其四
  • python计算shp中每个区域的面积
  • Linux 怎么使用局域网内电脑的网络访问外部