Redis源码篇 - Ziplist数据结构

news2024/11/29 8:49:18

Ziplist是一种内存优化的list存储结构,通过使用连续的内存空间存储,来减少内存碎片化,同时和链表的不同还有,它不存储前后指针,而是通过变长的字节存储前节点元素长度,通过计算长度来实现节点的查找。它是一种以时间换空间的数据结构

普通的链表中节都存储着前后指针,分别指向上一个节点和下一个节点,节点在内存不是顺序存储的,所以会造成内存碎片化。

ziplist就是通过申请连续的内存空间来实现链表的功能,结构如下:

 ziplist中,记录了zlail尾部指针偏移量,是为了可以通过其快速定位到尾部entry,实现方向索引。

 prevlen:上一个entry大小(1字节或者5字节),可以通过该长度计算来移动指针实现元素遍历查找。prevlen是一个边长字节:

  • 当前entry元素大小在1~253字节时,prevlen使用1个节点来存储。
  • 当前entry元素>= 254字节时,prevlen使用5个节点来存储,此时前一个1个字节固定为254最为标记,表示后面4个字节存储大真正数据。

   (之所以取254,是因为zlend固定为255,用来表示结尾)

encoding:encoding存储了元素内容的类型编码信息(数值或者字符串)以及长度 (1、2、5字节),ziplist通过这个字段来决定后面的content的形式 。 当encoding最高的2位为11是,说明是数字,否则是字符串。
当数值类型在0~12范围内,则存储在encoding中,此时忽略entry-data。

和linklist相对比为什么会节省空间?

  • ziplist通过申请连续内存空间存储,减少了内存碎片化。
  • 内存不需要维护前后指针,节省了空间,而是通过len的计算偏移量,从而移动指针实现遍历查询。
  • 同时redis对其做了相对优化,比如边长的prevlen,当前entry在254以内时,使用1个字节存储,超过时使用5个字节存储。

缺点?

  • 压缩列表通过申请连续的内存空间存储,节省空间,这是它优点,同时也是它缺点,因为当数据量越来越大时,并不能保证能申请到大的连续的内存空间,查询性能也会下降(O(n)),所以一般当数据量达到一定程度时,需要转成其他存储结构。比如quicklist、hash等。

压缩链表中连锁更新问题

 通过上面的介绍,了解到entry中pervious_entry_length会使用1或者5字节来存储上一个entry长度:

  • 如果前一个节点长度小于254时,则使用1个字节来保存长度。
  • 如果前一个节点长度>= 254时,使用5个字节来保持长度,其中前1个字节固定为0xfe,后4和字节才是真正的长度数据。

压缩链表中连锁更新场景

如果,有N个连续的、长度为250~253字节之间entry,此时他们的prevlen都是1个字节存储前一个节点长度,如下:

 此时插入了一个大于或等于254字节元素A:

此时发现因为A是超过了254字节,所以B需要申请空间使用5个字节的prevlen保存A长度:

 当B完成空间申请之后,B的内存空间就是254了,因为多申请了4个字节,此时C又需要使用5字节prevlen来存储,需要申请空间。

总结压缩链表中entry使用边长prevlen记录上一个entry长度,当存在连续的、长度为250~253之间的entry时,此时发生新增、删除新的大于254数据时,会导致连续空间扩张操作称之为连锁更新Redis并没有对此进行处理,因为概率比较低。

Ziplist特性:

  • 压缩列表可以看成一种连续空间的”双线链表“。
  • 列表节点之间不是通过指针连接,而是记录上一个节点和本节点长度来寻址,内存占用低。
  • 如果列表数据过多,导致列表过程,可能影响查询性能,因为和链表一样都需要O(n)的查询效率。
  • 增或者删除数据时,可能发生连锁更新问题。

 图地址:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/792973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

因材施教,有道发布“子曰”教育大模型,落地虚拟人口语教练等六大应用

因材施教的教育宗旨下,大模型浪潮中,网易有道凭借其对教育场景的深入理解和对商业化的理性思考,为行业树立了垂直大模型的典范。 7月26日,教育科技公司网易有道举办了“powered by 子曰”教育大模型应用成果发布会。会上重磅推出了…

好莱坞怕了, Gen-2全面开启免费使用

仿佛一声惊雷炸响,7月24日Runway 宣布,Gen-1 和 Gen-2 已经彻底开放,任何人都可以注册一个账号免费尝试。生成的视频长度为 4 秒,每秒消耗 5 个积分,利用免费额度可以生成二十六个视频。如果免费积分耗尽,付…

【前端学java】JAVA中类的基础概念

theme: cyanosis java中的类语法和前端的类语法几乎是一致的。 基础代码示例 JAVA的面向对象编程和JS的类语法十分接近,我们看一段代码 public class Object_oriented {public static void main(String[] args) {// 打工人 前的PeoPle是类型People dagongren ne…

微信自动回复怎么设置?

宝子们 你们有遇到或正面临以下情况吗? NO.1 “消息爆炸” 小能,是一位在微信公众号分享美食和旅行的博主 由于内容质量高、互动性强,他的粉丝数量迅速增长 然而,随之而来的是大量的留言和私信 小明根本无法应付 他曾经试…

GFLv2 论文学习

1. 解决了什么问题? 预测定位质量对于目标检测很重要,在 NMS 时它能提供准确的得分排序,提高模型的表现。现有方法都是通过分类或回归的卷积特征来预测定位质量得分。 2. 提出了什么方法? 受到 GFLv1 的 general distribution …

端口复用与重映射

端口复用和重映射 STM32F1有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。 大家都知道,MCU都有串口…

Linux中的ldd命令使用方法总结

ldd(List Dynamic Dependencies)命令是Linux系统中的一个工具 它用于打印出一个可执行文件所依赖的共享库文件(动态链接库) 当你运行ldd命令,并跟上一个可执行文件作为参数,它会列出该可执行文件所需要的…

Spingboot 整合netty-socket.io

Spingboot 整合netty-socket.io 依赖 注意版本号&#xff0c;不然client版本不对的话也是连不上的 https://github.com/mrniko/netty-socketio ​ <dependency><groupId>com.corundumstudio.socketio</groupId><artifactId>netty-socketio</art…

使用TensorFlow训练深度学习模型实战(下)

大家好&#xff0c;本文接TensorFlow训练深度学习模型的上半部分继续进行讲述&#xff0c;下面将介绍有关定义深度学习模型、训练模型和评估模型的内容。 定义深度学习模型 数据准备完成后&#xff0c;下一步是使用TensorFlow搭建神经网络模型&#xff0c;搭建模型有两个选项…

年轻小伙爆肝ARST

关于 ARTS 的释义 —— 每周完成一个 ARTS&#xff1a; ⭐️● Algorithm: 每周至少做一个 LeetCode 的算法题 ⭐️● Review: 阅读并点评至少一篇技术文章 ⭐️● Tips: 学习至少一个技术技巧 ⭐️● Share: 分享一篇有观点和思考的技术文章 希望通过此次活动能聚集一波热爱技…

GitLab 删除项目

1.点击头像 2.点击Profile 3.选择要删除的项目点进去 4.settings-general-Advances-expand 5.然后在弹出框中输入你要删除的项目名称即可

【WEB开发】Java获取高德POI(关键词搜索法)实现数据展示

前言 该篇文章是关键词搜索法获取高德poi&#xff0c;但鉴于无法突破200条记录的上限&#xff0c;所以采用了本方法进行区/县循环检索。开始之前我们首先需要明白一些常识 poi是兴趣点&#xff0c;它本身除了经纬度&#xff0c;还记录了一些信息&#xff0c;如名称、地址、联…

mirror功能

实现方式 mirror逻辑的工作阶段&#xff1a; ngx在log phase之后&#xff08;在ngx_http_free_request处调用&#xff09;已完成向client端返回response&#xff0c;在log phase之后完成close connection&#xff08;短链接&#xff09;&#xff0c;在该阶段处理mirror逻辑不…

【Redis】高级篇: 一篇文章讲清楚Redis的单线程和多线程

目录 面试题 Redis到底是多线程还是单线程&#xff1f; 简单回答 详解 Redis的“单线程” Redis为什么选择单线程&#xff1f; 后来Redis为什么又逐渐加入了多线程特性&#xff1f; Redis为什么快&#xff1f; 回答 IO多路复用 Unix网络编程的5种IO模型 主线程和IO…

温湿度传感器的工作原理及应用领域你了解多少呢?

传感器是一种将物理量转换为电信号的装置&#xff0c;用于检测温度、湿度、压力、光强、震动等物理量。它能够将检测到的物理量转换为电信号&#xff0c;并输送到计算机、单片机等设备进行分析和处理。生产生活中&#xff0c;不同的场所和环境对温湿度有着特殊要求&#xff0c;…

看完即会,抓取微信小程序数据包教程

在给VIP学员答疑的时候&#xff0c;有很多小伙伴问到能不能抓取到微信小程序数据呢&#xff1f;答案当然是肯定的&#xff0c;通过Fiddler或者Charles这些主流的抓包工具都可以抓得到&#xff0c;在IOS平台抓取微信小程序和https请求都是一样的设置&#xff0c;接下来给大家通过…

【代码随想录day20】验证二叉搜索树

题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 思路 最开始想简单…

Linux 学习记录58(ARM篇)

Linux 学习记录58(ARM篇) 本文目录 Linux 学习记录58(ARM篇)一、GIC相关寄存器1. 系统框图2. 中断号对应关系 二、GICD寄存器1. GICD_CTLR2. GICD_ISENABLERx3. GICD_IPRIORITYRx4. GICD_ITARGETSRx5. GICD_ICPENDRx 三、GICC寄存器1. GICC_PMR2. GICC_CTLR3. GICC_IAR4. GICC_…

JAVA面试总结-Redis篇章(五)——持久化

Java面试总结-Redis篇章&#xff08;五&#xff09;——持久化 1.RDBRDB全称Redis Database Backup file (Redis数据备份文件)&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文件&#x…

持续贡献开源力量,棱镜七彩加入openKylin

近日&#xff0c;棱镜七彩签署 openKylin 社区 CLA&#xff08;Contributor License Agreement 贡献者许可协议&#xff09;&#xff0c;正式加入openKylin 开源社区。 棱镜七彩成立于2016年&#xff0c;是一家专注于开源安全、软件供应链安全的创新型科技企业。自成立以来&…