redis中ziplist,skiplist

article/2025/8/8 0:36:37
  • ziplist压缩表

ziplist主要是为了节约内存,他将元素存储在一块连续的内存空间中,这样在查询数据的时候也可以利用CPU的缓存访问数据,加快查询的效率

相较于数组而言。我们知道,数组要求每个元素的大小都相同,如果我们要存储不同长度的字符串,那我们就需要用最大长度的字符串大小作为元素的大小(假设是5个字节)。小于5个字节长度的字符串也会开辟5个字节,便会浪费部分存储空间,

ziplist就是根据每个节点的长度来决定占用内存大小,这样每次添加元素时就可以计算下一个节点在内存中的存储位置,从而形成一个压缩列表。

ziplist在redis中的使用

// 压缩列表 struct ziplist<T> { int32 zlbytes; // 压缩列表占用的内存字节数 int32 zltail_offset; // 记录表尾节点距离起始地址有多少个字节,用于快速定位最后一个元素 int16 zllength; // 压缩列表包含的节点数 T[] entries; // 压缩列表包含的所有节点 int8 zlend; // 特殊值0xFF,标记压缩列表结尾 } ziplist;

zlentry节点的组成

// 列表节点 struct entry { int<val> prevlen; // 前一个entry节点的长度,便于反向查找 int<val> encoding; // 节点的content属性保存的数据的类型 optional byte[] content; // 节点的值 } entry;

通过content的字节大小,可以定位下一个节点的位置,便于ziplist链表的遍历

  • skiplist跳表

跳表(skip list) 对标的是平衡树(AVL Tree),红黑树,是一种 插入/删除/搜索 都是 O(log n) 的数据结构。这两个查询效率差不多,

  • 跳表它最大的优势是原理简单、容易实现、效率更高。
  • 在并发的情况下,红黑树在插入删除的时候可能需要做数的平衡的操作,即树的左旋和右旋来保证树的平衡,会影响其他部分树的节点,而跳表只会影响局部,不会影响其他的节点

skiplist以空间换时间

跳表处理的是有序的链表(一般是双向链表),最底层就是原始数据双向链表(按照score分数从小到大排序),其他每个节点都有一个层数level[],每个层都有一个索引节点,主要为了加快查询数据的速度

skiplist的底层数据结构

typedef struct zskiplist { // 头节点,尾节点 struct zskiplistNode *header, *tail; // 节点数量 unsigned long length; // 目前表内节点的最大层数 int level; } zskiplist; typedef struct zskiplistNode { // member 对象 robj *obj; // 分值,底层是原始数据,双向链表为按照score从小到大进行排序 double score; // 后退指针 struct zskiplistNode *backward; // 层,节点创建会根据随机算法,计算出层数,就是lecel数组的大小 struct zskiplistLevel { // 前进指针,指向下一个节点 struct zskiplistNode *forward; // 这个层跨越的节点数量,在同一层中当前节点到下一个节点的距离 unsigned int span; } level[]; } zskiplistNode;

如果没有level层,即索引,查询链表时会从头到尾的遍历链表,这个查询就会比较慢

所以跳表就必须加层,加索引,提高查询效率

跳表是牺牲空间来换取时间,除了最底层是最原始的数据外(双向链表),其他的每一层,其实都相当于是一个索引(单向链表),

当查询数据的时候会从最高层,开始level3开始检索,例如搜索117,从level3开始检索,21117,就转向level2 37节点开始继续向前检索,直到找到检索的元素,(这样一层层的检索主要是因为,底层原始数据是有序的双向链表,所以每层索引节点单向链表也是有序的),

这样可以一次跳过多个节点

检索数据19,查询执行图

插入元素到跳表,一个节点要不要被索引,建几层的索引,都在节点插入时通过随机算法计算出来的,也就是层数level[]是随机的,最终会将元素插入到最底层原始数据(双向链表)中去,层数随机计算,之后每一层都会添加索引节点

119添加的节点层数level会按照随机算法进行计算得到

新添加的节点119,他的forward前进指针会指向当前层的最右边的节点,span会计算当前层当前节点和最右边节点的距离,并且119节点最左边的节点85和层节点71的forward,和span都会重新计算,

记住需要理解跳表好处,主要提高检索效率,查询接近二分查找,

例如面试官问题你,为何redis这么快,不要在说一些八股文了,

1,可以从数据结构上跟面试官分析,为什么redis五大基本数据类型,查询性能为这么高,

2,IO多路复用机制,请看后面的文章,

如果能从原理上分析,才能真真的明白redis为何这么快,redis6.0加入多线程,主要在网络IO上,

如果能输出redis的IO模型,你就很好了,


http://chatgpt.dhexx.cn/article/Ny67vGNg.shtml

相关文章

跳表-skiplist的简单实现

文章目录 1、什么是跳表-skiplist2、skiplist的效率如何保证&#xff1f;3、skiplist的实现4、skiplist跟平衡搜索树和哈希表的对比 1、什么是跳表-skiplist skiplist本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样…

跳表:Skiplist原理介绍和优缺点

skiplist介绍 不要求上下相邻两层链表之间的节点个数有严格的对应关系&#xff0c;而是为每个节点随机出一个层数(level)。比如&#xff0c;一个节点随机出的层数是3&#xff0c;那么就把它链入到第1层到第3层这三层链表中。为了表达清楚&#xff0c;下图展示了如何通过一步步的…

skiplist 跳跃表详解及其编程实现

skiplist介绍 跳表(skip List)是一种随机化的数据结构&#xff0c;基于并联的链表&#xff0c;实现简单&#xff0c;插入、删除、查找的复杂度均为O(logN)。跳表的具体定义&#xff0c; 请参考参考维基百科 点我&#xff0c;中文版。跳表是由William Pugh发明的&#xff0c;这…

浅析SkipList跳跃表原理及代码实现

转载请注明&#xff1a;http://blog.csdn.net/ict2014/article/details/17394259 SkipList在leveldb以及lucence中都广为使用&#xff0c;是比较高效的数据结构。由于它的代码以及原理实现的简单性&#xff0c;更为人们所接受。我们首先看看SkipList的定义&#xff0c;为什么叫…

跳表(skiplist)的理解

听到跳表(skiplist)这个名字,既然是list,那么应该跟链表有关。 跳表是有序链表,但是我们知道,即使对于排过序的链表,我们对于查找还是需要进行通过链表的指针进行遍历的,时间复杂度很高依然是O(n),这个显然是不能接受的。是否可以像数组那样,通过二分法进行查找呢,但…

SkipList详解

本文参考&#xff1a;《大数据日知录》 概念 SkipList是一种用来代替平衡树的数据结构。 虽然在最坏的情况下SkipList的效率要低于平衡树&#xff0c;但是大多数情况下效率仍然非常高&#xff0c;其插入、删除、查找的时间复杂度都是O(log(N))。 除了高效外&#xff0c;其实现…

跳表(skipList)

一、为何有skipList这种数据结构的出现 我们知道二分查找算法之所以能达到 O(logn) 这样高效的一个重要原因在于它所依赖的数据结构是数组&#xff0c;数组支持随机访问一个元素&#xff0c;通过下标很容易定位到中间元素。而链表是不支持随机访问的&#xff0c;只能从头到尾依…

跳表 skiplist 简介

跳表 skiplist 跳表 (Skip List) 是由 William Pugh 在 1990 年发表的文章 Skip Lists: A Probabilistic Alternative toBalanced Trees 中描述的一种查找数据结构&#xff0c;支持对数据的快速查找&#xff0c;插入和删除。 对于 AVL 树、红黑树等平衡树&#xff0c;在插入过…

SkipList(跳跃表)详解

Introduction: skiplist本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff08;Searching&#xff09;&#xff0c;即根据给定的key&#xff0c;快速查到它所在的位置&#xff08;或者对应的value&#xff09; 一般用于解决查找问题的数据结构分为两个大类…

docker中国镜像

一,如果是像redis,mysql等官方的镜像,直接配置阿里云的镜像就可以 1,注册阿里云账号,并登录 2,打开这个网址 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 3,页面上会教怎么设置,如下面的截图 二,如果是私有仓库的镜像 非常感谢原作者:https://www.jiansh…

Docker 使用国内镜像仓库

Docker 使用国内镜像仓库 1、问题描述2、总结 1、问题描述 由于某些原因&#xff0c;导致Docker镜像在国内下载速度特别慢。所以为了沉浸式开发。最好切换为国内源。这里以163 的镜像仓库举例。首先修改/etc/docker/daemon.json配置文件。 sudo vi /etc/docker/daemon.json…

MacOS上配置docker国内镜像仓库地址

背景 docker官方镜像仓库网速较差&#xff0c;我们需要设置国内镜像服务 我的MacOS docker版本如下 设置docker国内镜像仓库地址 点击Settings点击Docker Engine修改配置文件&#xff0c;添加registry-mirrors {"builder": {"gc": {"defaultKeepS…

Docker国内镜像加速地址与详细说明

简介 对于动不动就几百M甚至上G的Docker镜像来说&#xff0c;官方镜像总是掉线或速度极慢&#xff0c;为了改善这种情况&#xff0c;建议切换成国内镜像。常用的国内镜像使用阿里云、网易的居多&#xff0c;本篇内容将记录一下Docker的这些国内镜像是怎么使用的。 国内常用的…

Docker国内镜像

1、下面这些镜像实测基本都用不了。 网易镜像中心&#xff1a;http://hub-mirror.c.163.com daocloud镜像市场&#xff1a;https://hub.daocloud.io 七牛云&#xff1a;https://reg-mirror.qiniu.com Azure&#xff1a;https://dockerhub.azk8s.cn 中科大: https://docke…

docker 国内镜像配置

一、常用镜像地址 1、中国科技大学:https://docker.mirrors.ustc.edu.cn 2、阿里云:https://cr.console.aliyun.com/ 3、Docker中国区官方镜像:https://registry.docker-cn.com 4、网易:http://hub-mirror.c.163.com 5、ustc:https://docker.mirrors.ustc.edu.cn 6、daoclo…

window docker国内镜像设置

刚开始使用的时候&#xff0c;发现因为网络的问题&#xff0c;经常出现镜像下载失败的情况。如下图所示。 这是应为docker服务在国外,直接访问会因为网络原因失败或者特别慢,因此我们可以将将镜像源设置为国内的。 一. 在桌面右下角出有一个docker的图标,鼠标右键点击setings,…

【Docker】Docker 设置国内镜像源_docker国内镜像库

文章目录 1. Docker阿里云镜像加速2. 参考资料 点击跳转&#xff1a;Docker安装MySQL、Redis、RabbitMQ、Elasticsearch、Nacos等常见服务全套&#xff08;质量有保证&#xff0c;内容详情&#xff09; 1. Docker阿里云镜像加速 在国内&#xff0c;从官方的Docker Hub仓库拉取…

docker构建国内镜像服务

在国内想要下载镜像比较困难&#xff0c;因此很多公司都构建自己的私有仓库。如何搭建私有仓库&#xff0c;请参考《docker私有仓库从无到有》。然而即使私有仓库服务构建完成&#xff0c;但是里面没有镜像&#xff0c;一样很苦恼。今天介绍一下如何利用国内云服务商提供的镜像…

电网电压的三相静止对称坐标系和三相电网电压的相量表示法

电网电压的空间电压矢量和电网电压的相量表示这两个概念需要区分清楚。分别参考邱关源的《电路》和张兴的《PWM整流》相关章节。 图2 三相电网电压的相量表示法 电网电压的相量表示&#xff0c;三相相差120度&#xff0c;整体逆时针50HZ旋转&#xff0c;这里的120度是指三分之一…