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

深度拆解 Redis ZSet 底层实现:从“紧凑排队”到“多级瞬移”

在 Redis 的世界里为了把性能和内存利用率压榨到极致底层实现往往是“看人下菜碟”。今天咱们就揭开 ZSet 的底裤看看它到底是怎么从“紧凑排队”进化到“多级瞬移”的。一、 是什么ZSet 的“两副面孔”首先纠正一个小插曲ZSet有序集合是Redis的核心数据结构不是 MyBatis 的MyBatis 主要是做 ORM 映射。ZSet 最牛的地方在于它既能像Hash一样保证成员Member的唯一性又能给每个成员带个“分数值”Score并让它们自动排序。为了实现这个效果Redis 会根据数据量的大小在底层偷偷切换两套皮肤压缩列表 (ZipList / Listpack)像是一辆挤得满满当当的公交车。跳表 (SkipList) 哈希表 (Dict)像是一座带多部高速电梯的摩天大楼。底层逻辑当数据量小的时候内存最贵我们用“紧凑排列”换空间当数据量大的时候速度最贵我们用“空间索引”换时间。二、 怎么用极简实战别光说不练咱们直接看在代码里怎么操作它顺便看看它是怎么变换“皮肤”的。Javaimport redis.clients.jedis.Jedis; public class ZSetDemo { public static void main(String[] args) { // 1. 初始化连接假设本地已开启 Redis try (Jedis jedis new Jedis(127.0.0.1, 6379)) { String key rank:player; jedis.del(key); // 2. 插入数据member 是玩家 IDscore 是战力值 jedis.zadd(key, 100.0, Uzi); jedis.zadd(key, 99.0, Faker); jedis.zadd(key, 95.0, Rookie); // 3. 查看底层编码格式 (重点细节) System.out.println(当前底层编码: jedis.objectEncoding(key)); // 4. 获取前两名按分数从高到低 System.out.println(战力榜 Top 2:); jedis.zrevrangeWithScores(key, 0, 1).forEach(tuple - { System.out.println(tuple.getElement() - tuple.getScore()); }); } catch (Exception e) { e.printStackTrace(); } } } /* 运行输出 当前底层编码: ziplist (注Redis 7.0 可能会显示 listpack) 战力榜 Top 2: Uzi - 100.0 Faker - 99.0 */三、 重点细节深挖底层原理1. 压缩列表ZipList空间守财奴当你的 ZSet 满足以下两个条件时Redis 会使用 ZipList元素数量少默认 128 个。每个元素的长度短默认 64 字节。物理形态它在内存里是一块连续的字节数组。每个节点挨在一起不存储指向下一个节点的指针省下了 8 字节的指针空间。痛点找元素得从头往后挨个排查$O(N)$。但在数据量极小时CPU 缓存命中率极高这点耗时几乎可以忽略不计。2. 跳表SkipList空间换时间的艺术一旦数据多了ZipList 的 $O(N)$ 查找就会让 Redis 这种单线程架构慢得像蜗牛。这时候ZSet 会自动“进化”为跳表。物理形态多级索引跳表在普通链表的基础上随机向上提取了几层“索引”。瞬移查找找 100 号元素先从顶层大跨步跳发现跳过了再往下层切。这就像坐直达电梯先到 50 层再换乘到 55 层。时间复杂度平均 $O(\log N)$性能媲美平衡树但实现起来比红黑树简单得多。3. 为什么还配了一个 Dict哈希表跳表虽然找“范围”很快比如找 80-100 分的人但如果你只想查“Faker 多少分”跳表还是要 $O(\log N)$。Redis 追求极致所以额外配了一个Dict保存了Member - Score的映射直接把查询单个元素分数的复杂度降到了$O(1)$。四、 深度硬核跳表到底是怎样炼成的如果说平衡树如红黑树是靠复杂的旋转逻辑来维持平衡那跳表就是靠**掷硬币随机概率**来打天下。1. 结构拆解给链表装上“高速公路”普通的链表Level 0就像是一条每站必停的慢车轨道。我们要找第 100 个节点得从第 1 个老老实实数过去。跳表的做法是向上加层。L0 层原链表包含所有元素。L1 层一级索引每隔一个节点提拔一个“课代表”。L2 层二级索引在 L1 的基础上再提拔课代表。通俗类比这就像你在大城市找路。L2 层是大区地图上海 - 北京L1 层是街道地图朝阳区 - 海淀区L0 层是具体的门牌号。你先在大地图上瞬移到了附近再下站。2. 搜索逻辑从左上角开始的“Z字形”下楼梯跳表的查询逻辑非常简洁从顶层开始能往右走就往右走右边大了就往下走。从当前层的Head出发。比较右边节点的值如果右边 目标直接跳过去跳过了一大堆节点。如果右边 目标或右边为空对不起跳过头了原地下一层。重复上述过程直到在 L0 层找到目标或者没找到。由于每一层都过滤了大量的无效节点查找的时间复杂度直接从 $O(N)$ 砍到了 $O(\log N)$。3. 插入的灵魂随机层高Random Level这是跳表最精妙的地方。插入一个新元素时它到底该出现在哪几层索引里红黑树的做法插入后看颜色、看左右不平衡就旋转。太烧脑了跳表的做法“听天由命”。每插入一个新节点程序会调用一个随机函数类似掷硬币。50% 的概率停留在 L0 层。25% 的概率长到 L1 层。12.5% 的概率长到 L2 层……以此类推直到达到 Redis 规定的最高层通常是 32 或 64。为什么这么做从宏观上看这种概率分布保证了高层节点大约是底层节点的 $1/2$或者 $1/4$自然而然地形成了类似二分查找的结构完全不需要复杂的平衡算法五、 代码实现极简伪逻辑为了让你直观感受我写一段跳表核心查找逻辑的伪代码Javapublic Node find(int targetScore) { Node curr this.head; // 从左上角开始 // 从最高层向下爬 for (int i currentMaxLevel - 1; i 0; i--) { // 如果右边节点存在且分数小于目标就一直往右跳 while (curr.forward[i] ! null curr.forward[i].score targetScore) { curr curr.forward[i]; } // 到这说明右边没路了或者大了i-- 会让循环进入下一层 } // 最终在 L0 层判断一下 curr curr.forward[0]; return (curr ! null curr.score targetScore) ? curr : null; }

相关文章:

深度拆解 Redis ZSet 底层实现:从“紧凑排队”到“多级瞬移”

在 Redis 的世界里,为了把性能和内存利用率压榨到极致,底层实现往往是“看人下菜碟”。今天咱们就揭开 ZSet 的底裤,看看它到底是怎么从“紧凑排队”进化到“多级瞬移”的。 一、 是什么:ZSet 的“两副面孔” 首先纠正一个小插曲…...

Threads库:裸机与RTOS下的轻量级函数多实例并发框架

1. Threads 库深度解析:在裸机与 RTOS 环境下实现函数的多实例并发执行1.1 项目定位与工程价值“Threads”并非一个独立的实时操作系统(RTOS),而是一个轻量级、可移植的函数级多实例并发抽象层。其核心设计目标是:在不…...

Arduino:解决手动解压ESP32库到packages文件夹,但Arduino IDE还是无法找到ESP32的问题

在学习使用Arduino时,如果需要在Arduino IDE里找到ESP32S3 DEV Module,一种方法是点击开发板管理器,搜索ESP32库,点击自动安装(如图1),安装完成方可使用,但是因为网络的原因&#xf…...

深夜告警炸裂?这份Linux故障排查“作战地图”请收好肆

先唠两句:参数就像餐厅点单 把API想象成一家餐厅的“后厨系统”。 ? 路径参数/dishes/{dish_id} -> 好比你要点“宫保鸡丁”这道具体的菜,它是菜单(资源路径)的一部分。查询参数/dishes?spicytrue&typeSichuan -> 好比…...

不满意Oh My Zsh启动卡顿,来试试Starship吧裙

pagehelper整合 引入依赖com.github.pagehelperpagehelper-spring-boot-starter2.1.0compile编写代码 GetMapping("/list/{pageNo}") public PageInfo findAll(PathVariable int pageNo) {// 设置当前页码和每页显示的条数PageHelper.startPage(pageNo, 10);// 查询数…...

VC0706摄像头模块UART驱动与状态机设计详解

1. VC0706 Camera Shield 驱动技术深度解析 1.1 芯片级架构与硬件接口特性 VC0706 是由深圳中星微电子(Vimicro)推出的低功耗、高集成度 JPEG 编码图像处理 SoC,广泛应用于早期嵌入式视觉模块。RadioShack 推出的 VC0706 Camera Shield 是基…...

EPFramewrokAtmega:面向AVR的确定性嵌入式固件框架

1. 项目概述EPFramewrokAtmega 是一个面向 Atmel AVR 系列微控制器(特别是 ATmega328P、ATmega2560 等主流型号)的轻量级嵌入式固件框架,其设计目标并非替代 Arduino 生态,而是为追求确定性、资源可控性与底层可追溯性的专业嵌入式…...

014、分布式系统核心:一致性、可用性与分区容错

014、分布式系统核心:一致性、可用性与分区容错 深夜报警:订单状态丢了 上周三凌晨两点,手机突然狂震。监控告警显示,订单服务的双活机房出现数据不一致——同一订单在A机房显示“已支付”,在B机房却是“待付款”。业务部门紧急来电,用户已经投诉付款后订单没反应。 团…...

基于Python的科研管理系统毕业设计

博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在开发一款基于Python的科研管理系统,以实现科研项目管理、数据存储与分析、团队协作与沟通等功能。具体研究目的如下:提高科研项…...

Typecho完美实现回复可见功能

之前转载过这么一篇文章《typecho非插件实现回复可见功能》,可以实现回复可见功能,但是有个问题,在文章列表页展示文章缩略内容时,如果回复可见内容刚好在缩略内容的位置上时,就会暴露出来,同时Feed里面也会…...

基于Python的多媒体信息共享平台毕设

博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在设计并实现一个基于Python的多媒体信息共享平台,以解决当前多媒体信息共享过程中存在的诸多问题。具体而言,研究目的可概括为以…...

typecho按分类搜索文章

typecho根据分类搜索文章.jpg 之前我写的soso搜索增强插件其实已经能够根据分类进行搜索内容了,不过需要模板上进行配合,比如我们搜索分类id为2620下关于typecho的文章,需要传递分类id的参数给cat,让插件获取,比如这个…...

别再死记命令了!通过一个Packet Tracer静态路由实验,彻底搞懂‘下一跳’和‘出接口’的区别

别再死记命令了!通过Packet Tracer实验彻底搞懂静态路由的“下一跳”与“出接口” 刚接触网络配置时,很多人会陷入一个误区:把静态路由的配置命令当作魔法咒语来记忆。直到某天,当网络拓扑发生变化,或者需要在不同场景…...

3步揪出Windows热键小偷:Hotkey Detective终极使用指南

3步揪出Windows热键小偷:Hotkey Detective终极使用指南 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 你是否曾…...

开源QMC解密工具深度解析:5分钟掌握音频格式转换核心技术

开源QMC解密工具深度解析:5分钟掌握音频格式转换核心技术 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 一键批量转换方法:跨平台音乐文件解锁方案…...

给STM32F429的RGB屏做个‘相册’:FATFS+软件解码JPG实战(避坑SD卡格式化)

STM32F429实战:构建安全高效的JPG图片浏览器 在嵌入式设备上实现图片浏览功能是许多项目的常见需求,尤其是当我们需要为产品添加图形界面或多媒体展示能力时。STM32F429凭借其强大的LTDC接口和DMA2D加速器,成为中高端嵌入式图形应用的理想选择…...

【JavaScript高级编程】拆解函数流水线 上衫

一、什么是setuptools? setuptools 是一个用于创建、分发和安装 Python 包的核心库。 它可以帮助你: 定义 Python 包的元数据(如名称、版本、作者等)。 声明包的依赖项,确保你的包能够正确运行。 构建源代码分发包&…...

你的SSH密钥可能已经过期了噬

引言 在现代软件开发中,性能始终是衡量应用质量的重要指标之一。无论是企业级应用、云服务还是桌面程序,性能优化都能显著提升用户体验、降低基础设施成本并增强系统的可扩展性。对于使用 C# 开发的应用程序而言,性能优化涉及多个层面&#x…...

我试了四种去除 Gemini 水印的方法,整理成一篇实用对比撕

认识Pass层级结构 Pass范围从上到下一共分为5个层级: 模块层级:单个.ll或.bc文件 调用图层级:函数调用的关系。 函数层级:单个函数。 基本块层级:单个代码块。例如C语言中{}括起来的最小代码。 指令层级:单…...

Stripe 支付集成实战:Java后端核心API详解与避坑指南

1. 为什么选择Stripe支付集成? Stripe作为全球领先的在线支付解决方案,特别适合需要处理国际支付的电商或SaaS平台。我在多个跨境项目中采用Stripe后发现,其API设计非常开发者友好,尤其是对Java后端技术栈的支持相当完善。与国内支…...

大模型“表面公平”陷阱(GPT-4/Claude/Gemini三大模型在12类敏感属性上的隐性偏差对比白皮书)

第一章:大模型工程化中的模型公平性评估 2026奇点智能技术大会(https://ml-summit.org) 大模型在招聘筛选、信贷审批、司法辅助等高风险场景中部署前,必须系统性验证其对不同人口统计学群体的预测一致性。公平性不是静态属性,而是需在数据分…...

从telnet到ssh:银河麒麟系统远程管理方案对比与迁移指南

从telnet到ssh:银河麒麟系统远程管理方案对比与迁移指南 在数字化运维的浪潮中,远程管理技术如同系统管理员的"千里眼"和"顺风耳"。银河麒麟作为国产操作系统的代表,其安全性设计一直走在行业前沿。然而,许多…...

3步快速部署开源驾驶辅助系统FlowPilot

3步快速部署开源驾驶辅助系统FlowPilot 【免费下载链接】flowpilot flow-pilot is an openpilot based driver assistance system that runs on linux, windows and android powered machines. 项目地址: https://gitcode.com/gh_mirrors/fl/flowpilot FlowPilot是一款基…...

【内部泄露】某千亿参数大模型压缩技术栈(含自研GEMM-aware剪枝+动态bit-width量化),仅限本文完整复现

第一章:大模型工程化中的模型压缩算法对比 2026奇点智能技术大会(https://ml-summit.org) 模型压缩是实现大语言模型在边缘设备、低延迟服务及成本敏感场景中落地的关键工程环节。不同压缩路径在精度保留、推理加速比、部署兼容性与训练资源消耗上呈现显著权衡&…...

AXI总线协议---关键信号时序解析与实战应用

1. AXI总线协议基础与核心信号解析 AXI(Advanced eXtensible Interface)总线协议是ARM公司推出的高性能片上总线标准,广泛应用于现代SoC设计和FPGA开发中。我第一次接触AXI是在一个图像处理项目里,当时为了调试DMA传输问题&#x…...

为什么92%的大模型项目在灰度阶段超期?资深MLOps架构师披露3个被忽视的工程化断点

第一章:大模型工程化灰度发布策略的全局认知 2026奇点智能技术大会(https://ml-summit.org) 大模型工程化灰度发布并非简单的流量切分,而是融合模型版本管理、服务可观测性、推理性能约束与业务语义反馈的系统性治理过程。它要求在保障线上服务质量&am…...

Verdi高效代码追踪:Auto Trace与Trace X的进阶应用技巧

1. Verdi调试利器:Auto Trace与Trace X入门指南 刚接触Verdi时,我最头疼的就是在复杂的门级网表中追踪信号路径。记得第一次调试一个深度流水线设计时,手动点击了二十多级寄存器才找到信号源头,不仅效率低下还容易遗漏关键路径。直…...

AI模型交付即违规?(大模型工程化中的5大高危伦理雷区与司法判例复盘)

第一章:AI模型交付即违规?(大模型工程化中的5大高危伦理雷区与司法判例复盘) 2026奇点智能技术大会(https://ml-summit.org) 当企业将一个微调后的LLM封装为SaaS服务交付客户时,法律风险可能已在模型权重、提示词模板…...

Orion Framework:嵌入式轻量级REST客户端实现

1. Orion Framework 框架深度解析:面向嵌入式系统的轻量级 REST API 客户端实现1.1 定位与工程价值辨析Orion Framework 并非通用 Web 框架,而是一个专为资源受限嵌入式环境设计的精简型 REST API 客户端通信中间件。其核心工程目标明确:在无…...

RTC-8564实时时钟芯片驱动开发与低功耗设计实践

1. RTC-8564 实时时钟芯片深度技术解析与嵌入式驱动开发实践RTC-8564 是 Philips(现 NXP)推出的一款低功耗、IC 接口实时时钟芯片,广泛应用于工业控制、智能电表、医疗设备、POS 终端及各类需要高精度时间保持能力的嵌入式系统中。该芯片采用…...