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

redis----zset详解

Redis 的 Zset(Sorted Set,有序集合)是一种兼具唯一性有序性的复合数据结构,在实际开发中常用于排行榜、延时任务、范围统计等场景。

核心特性

  • 元素唯一,分数排序:每个元素(member)唯一,但分数(score)可重复。Zset 会根据分数对元素进行升序排序,分数相同则按元素字典序排序。
  • 动态排序:元素的分数可随时更新,更新后 Zset 会自动重新排序,无需手动维护。
  • 高效性能:基于跳表(Skip List)和哈希表实现,插入、删除、范围查询的时间复杂度均为 O (log N),在大数据量下仍能保持高效。

常用命令

元素操作

  • ZADD:添加或更新元素及分数

    ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
    

    • NX:仅当元素不存在时添加
    • XX:仅当元素存在时更新分数
    • INCR:将分数视为增量(如积分累加)
      示例:

    redis

    ZADD rank 95 "Alice" 88 "Bob" 92 "Charlie"  # 批量添加
    ZADD rank XX 98 "Alice"                     # 更新Alice的分数
    ZADD rank INCR 5 "Bob"                      # Bob的分数加5
    
  • ZSCORE:获取元素的分数

    ZSCORE key member
    

    示例:ZSCORE rank "Alice" → 返回 "98"

有序查询

  • ZRANGE:按分数升序查询指定范围元素(0 为第一个,-1 为最后一个)

    ZRANGE key start end [WITHSCORES]
    

    示例:ZRANGE rank 0 -1 WITHSCORES → 返回带分数的元素列表

  • ZREVRANGE:按分数降序查询(适合排行榜 “从高到低”)

    ZREVRANGE key start end [WITHSCORES]
    

    示例:ZREVRANGE rank 0 1 WITHSCORES → 返回 Top 2 元素

范围统计与删除

  • ZRANGEBYSCORE:按分数区间查询元素

    ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
    

    示例:ZRANGEBYSCORE rank 90 100 → 查询分数 90-100 的元素

  • ZREM:删除指定元素

    ZREM key member [member ...]
    

    示例:ZREM rank "Bob" → 删除 Bob,返回删除数量

典型应用场景

  1. 排行榜系统:如游戏积分榜、电商销量榜,用 ZREVRANGE 快速获取 Top N,ZSCORE 实时查询用户排名。
  2. 延时任务队列:将任务 ID 作为元素,执行时间戳作为分数,定期用 ZRANGEBYSCORE 获取 “已到执行时间” 的任务。
  3. 范围统计:如统计 “分数 80-90 分的学生”“粉丝数 1 万以上的博主”,通过 ZRANGEBYSCORE 高效筛选。

注意事项

  • 分数精度:分数为 64 位浮点型,避免过度依赖高精度(如小数位数过多可能导致排序误差)。
  • 大数据量优化:若 Zset 元素超百万级,避免使用 ZRANGE 0 -1 全量查询,建议分页查询(如 ZRANGE 0 99)。
  • 内存占用:Zset 比普通 Set 内存占用稍高,若对内存敏感,需结合业务合理使用。

内部编码

Redis 中 Zset 的内部编码并非固定,会根据数据规模自动切换,核心目标是平衡「内存效率」和「操作性能」,主要包含两种编码形式:

一、ziplist(压缩列表)编码

这是 Zset 存储小规模数据时的默认编码,触发条件需同时满足以下 2 个配置阈值(可在 redis.conf 调整):

  • 元素总数量 ≤ zset-max-ziplist-entries(默认值:128)
  • 每个元素的「member(成员)」字符串长度 ≤ zset-max-ziplist-value(默认值:64 字节)

1. 存储结构

ziplist 是连续的内存块,元素按「score(分数)升序」依次存储,格式为:
[zlbytes(总长度)][zltail(尾偏移)][zllen(元素数)][score1][member1][score2][member2]...[zlend(结束标识)]

  • score:以「小端字节序的浮点型」存储(节省空间);
  • member:以原始字符串形式存储,无额外指针开销。

2. 核心特点

  • 优点:内存占用极低(连续内存 + 紧凑存储),遍历效率高(无需跳转指针);
  • 缺点:插入 / 删除元素时需移动后续内存块,时间复杂度为 O (n),数据量大时性能骤降。

二、skiplist(跳表)+ dict(哈希表)编码

当 Zset 数据规模超过 ziplist 的阈值(元素数超 128 或 member 长度超 64 字节)时,Redis 会自动转为该编码,这是 Zset 处理「大规模数据」的核心结构。

1. 结构组成(双结构协同)

两种结构共享同一份数据(通过指针关联,无冗余存储),各自负责不同场景的高效操作:

(1)skiplist(跳表)—— 维护有序性与范围操作
  • 本质:多层级链表结构,每个节点包含多个「层级指针」(类似 “高速公路 + 普通公路” 的分层索引);
  • 作用:按 score 升序存储所有元素,支持 O(log n) 复杂度的插入、删除,以及范围查询(如 ZRANGEZREVRANGEZRANGEBYSCORE 等);
  • 优势:相比平衡二叉树(如红黑树),跳表实现更简单,且范围查询效率更高。
(2)dict(哈希表)—— 快速定位元素分数
  • 本质:经典的键值对结构,「键 = member」,「值 = 对应的 score」;
  • 作用:支持 O(1) 复杂度的「根据 member 查 score」操作(如 ZSCORE 命令);
  • 优势:避开跳表的 O (log n) 查找开销,直接通过哈希映射快速定位。

三、编码转换规则

  • 单向转换:仅支持「ziplist → skiplist+dict」,一旦触发转换,后续即使删除元素使数据规模缩小,也不会再转回 ziplist;
  • 触发时机:添加元素时实时检查阈值,一旦超过立即转换(无需手动干预);
  • 配置调整:若业务中 Zset 多为小规模数据,可适当调大 zset-max-ziplist-entries 或 zset-max-ziplist-value,进一步节省内存;若多为大规模数据,可调小阈值,提前切换到高性能编码。

四、查看当前编码

通过 OBJECT ENCODING 命令可直接查看某个 Zset 的内部编码,示例:

127.0.0.1:6379> ZADD myzset 1 "a" 2 "b"  # 小规模数据,用 ziplist
(integer) 2
127.0.0.1:6379> OBJECT ENCODING myzset
"ziplist"  # 输出 ziplist127.0.0.1:6379> ZADD myzset 3 "long-long-member-more-than-64-bytes-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
(integer) 1
127.0.0.1:6379> OBJECT ENCODING myzset
"zset"  # 输出 zset,代表 skiplist+dict 编码

http://www.dtcms.com/a/359500.html

相关文章:

  • 数值分析——非线性方程与方程组的数值解法之二分法
  • 创意无界:云渲染如何让视觉创作触手可及
  • 责任链模式实践-开放银行数据保护及合规
  • 模型系列(篇三)-Llama
  • 分布式事务相关
  • 【MYSQL】从混乱到清晰:联合查询帮你打通数据孤岛
  • Python 实战:内网渗透中的信息收集自动化脚本(6)
  • React前端开发_Day11
  • Pytest+Selenium4 Web自动化测试框架(三日速通)
  • 数据中心网络实现梳理
  • 变频器实习总结14 电子元件中的内部参考电压 Type-c口对于BMS开发的优点
  • Caffeine TimerWheel时间轮 深度解析:O(1)复杂度增删和触发时间事件
  • 2025.8.31基于UDP的网络聊天室项目
  • 数值分析——非线性方程与方程组的数值解法之迭代法
  • Nginx虚拟主机配置
  • 从RNN到BERT
  • 北斗导航 | GNSS定位模式技术总结:原理、分类与应用实践
  • OpenCV 图像轮廓检测
  • Python爬虫实战:研究Subplots,构建电商平台数据采集和分析系统
  • Spark内存管理
  • C++ 登录状态机项目知识笔记
  • GitHub Spark深度体验:是革命前夜,还是又一个“大厂玩具”?
  • LVGL移植(STM32)
  • 【开题答辩全过程】以 付费自习室系统小程序为例,包含答辩的问题和答案
  • 鸿蒙Next文本组件全解析:输入框、富文本与属性字符串开发指南
  • 智能合约安全全解析:常见漏洞、真实案例与防范实践
  • Sequelize ORM - 从入门到进阶
  • LabVIEW电力系统自动化仿真实验教学系统
  • 鸿蒙Next媒体展示组件实战:Video与动态布局全解析
  • Java全栈开发面试实录:从基础到微服务的实战解析