Redis 核心数据结构:跳表实现、层高设计解析

跳表是怎么实现的?

跳表是一链表改造而来,是一种小区链表,能够快速查询元素

头节点有3个指针L0、L1、L2

L0系统有5个节点:1、2、3、4、5

L1系统有3个节点:2、3、5

L2系统有1个节点:3

eg:我想查找4,就可以从L2系统查到3再查到4,只需要操作两次

如果在很大的数据 下跳表就会在系统层级上跳来跳去实现查询,时间复杂度就为O(logN)

跳表实现多系统(层级):

这里需要看跳表的源码

cpp 复制代码
typedef struct zskiplistNode {
    //Zset 对象的元素值
    sds ele;
    //元素权重值
    double score;
    //后向指针
    struct zskiplistNode *backward;
  
    //节点的level数组,保存每层上的前向指针和跨度
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

redis中zset存储sds类型的key和double类型的score,并且每一个节点都有一个前驱指针( struct zskiplistNode *backward),能够很方便的实现倒叙

这里sds类型它是 Redis 专门设计、用于替代 C 语言原生字符串(char*)的自定义字符串类型并且可以 自动扩容,按需分配,兼顾效率和内存

多层级 就是依赖zskiplistLevel,可以存储每一个系统相邻节点之间的跨度,还有一个后继指针(truct zskiplistNode *forward)

而且层高是根据[0,1]之间生成一个随机数,若小于0.25(概率小于25%),就会添加一层,两个相邻的元素之间没有层高比例,层数最大是64

#跳表是怎么设置层高的?

层高是根据**[0,1]之间生成一个随机数,若小于0.25(概率小于25%),就会添加一层**,两个相邻的元素之间没有层高比例,层数最大是64

Redis为什么用跳表而不是用B+树?

因为Redis中跳表场景适用度更高

跳表是适用于内存优化(redis)

B+树使用于磁盘优化(减少I/O次数,mysql)

1、内存与磁盘的设计初衷(最重要的原因):

B+树是为了磁盘I/O优化的: B+树的设计核心是降低树的高度,从而减少磁盘I/O次数。

**Redis 是纯内存操作:**在内存中,没有"磁盘 I/O"的瓶颈。内存中指针跳转的速度非常快。跳表虽然比 B+ 树高(层数多),但因此在内存中多几次指针跳转的长度非常小。,B+ 树为了减少高度而设计的复杂页管理机制,在内存场景下稀疏且笨重。

2、实现复杂度与代码维护:

跳表(Skip List):本质上是"楼梯链表"。其插入、删除逻辑主要是修改指针,代码实现非常简洁(几行C代码)。

B+树:插入和删除可能会引发节点的分割(Split)和合并(Merge),甚至需要对整棵树进行重平衡。实现一个健壮、高效的B+树非常复杂,代码量大而难以调试。

结论: Redis 作者 Antirez 非常看重代码的可执行性和简洁性,跳表以相邻的代码复杂度达到了同等级别的性能 O(log N)。

3、写入性能与重平衡代价:

**B+树的读取读写:**当插入导致数据页分裂时,需要移动大量数据或改变树的结构,这会产生读写读写。

跳表的局部性: 跳表的插入和删除操作是局部的。一个节点只需要修改相对节点的指针,并根据概率随机生成层高。它不需要像红黑树或B+树那样进行全局的旋转或复杂的结构调整

redis选择跳表不选B+树就是因为:

1.内存场景下,B+树的I/O优势无法发挥

2.zset的操作(增、删),跳表能以较低的复杂度实现同等甚至更优的性能

3.高频更新场景中,跳表的的实现简单性、性能稳定性更加符合redis的要求

相关推荐
2501_945423543 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
gameboy0314 小时前
从MySQL迁移到PostgreSQL的完整指南
数据库·mysql·postgresql
xdl25995 小时前
Spring Boot中集成MyBatis操作数据库详细教程
数据库·spring boot·mybatis
回到原点的码农5 小时前
Spring Data JDBC 详解
java·数据库·spring
zb200641205 小时前
Spring Boot 实战:轻松实现文件上传与下载功能
java·数据库·spring boot
CSharp精选营5 小时前
SQL Server安装避坑:这8个奇葩报错你遇到过几个?
数据库·sql server·安装指南·避坑
一叶落4385 小时前
题目:15. 三数之和
c语言·数据结构·算法·leetcode
一勺菠萝丶5 小时前
Flowable + Spring 集成踩坑:流程结束监听器查询历史任务为空 & 获取不到审批意见
java·数据库·spring
y = xⁿ5 小时前
【LeetCodehot100】2:两数相加 19 删除链表倒数第n个节点
数据结构·链表
RDCJM6 小时前
mysql表添加索引
数据库·mysql