当前位置:网站首页>redis你到底懂不懂之list
redis你到底懂不懂之list
2022-07-07 22:03:00 【InfoQ】
前言
- 在之前我们已经学习了redis五大数据结构中的list结构。其内部是linkedList和zipList两种结构。这是我们已经学习的内容。之前我没有结合操作具体查看。事实上在两者中还存在一种结合体quickList

结构演变
- 在上面我们添加了一个key为zlist的数据。通过object encoding zlist查看底层就是通过quicklist来构建的。之前在ziplist章节汇总我们了解到在redis中hash和list基本数据结构都使用了ziplist存储数据的。在list中我们确实quicklist。这里我们提前说明下quicklist内部就是基于ziplist来实现的。
linkedList
- 在开场quicklist之前我们简单梳理下之前学过的linkedList ,他是一种常见的双线链表。通过两个指针完成我们链表的构建。

C++指针
- redis是基于内存运行的,而内存有十分的宝贵所以redis在设计了双线链表后觉得有点耗内存。因为指针本身也是需要开辟空间的。根据系统的不同指针占位不同。这里我总结了一下一个指针占位就是一个系统操作的基本位
- 这里基本位是什么意思呢?加入你是64位系统那么一个指针就是64位即8个字节。如果你是32位系统那么一个指针就是32位即4个字节
- 也就是说如果我在redis中向双向链表中存储N个英文字母,我们又知道一个应为字母占1个字节。那么这N个元素就是N的listNode . 那么维持着N个listNode中间就需要2*(N-1)个指针。在64位系统中也就是我们需要开辟将近129倍的空间来存储内容。上述情况我们只有N个字节的内容,却需要
2*(N-1)*8+N
个字节来构建listNode。
- 随着节点的递增我们浪费程度越离谱。所以redis在双向链表的基础上结合了ziplist进行改良。
过渡原因

ziplist
- 在ziplist章节中我们知道ziplist是一块连续内存,是redis对内存的一种改良结构。ziplist实现了内存的高使用率!

linkedlist+ziplist好处

quicklist引入
- quicklist是在redis3.2之后引入的,笔者这里使用的是redis6.4方便源码好像并没有quicklist源码。
- 后来翻阅了之后redis6.4好像取消了quicklist . 结构。所以我又特别下了一个3.2的版本。这里具体的是redis3.2.4版本!!!
庐山真面目
quicklist

- 通过他的源码我们很清晰的看出他的内部数据结构!这个大家应该很熟悉了。quicklist可以说就是我们之前的linkedList 结构。内部就是双向链表只不过里面的属性稍微多了点

- 通过图示是不是感觉和linkedList一样。

- 接下来我们看看quicklist中各个属性的含义吧

quicklistNode
- quicklist只是一个抽象的概念,真正负责数据的存储的是组成quicklist的成员quicklistNode 。

- 各个属性的作用

- 通过上面的属性介绍,我们也可以了解了解到node节点中的数据结构就是ziplist 。在ziplist基础上会在进行压缩达到内存更高的使用效率!
- 关于压缩这里我们不用太去了解!主要目的就是一种编码,这种编码是无法真正使用的在使用期间redis会进行解码操作。在解码操作期间就是通过recompress属性来标记的。

insert
- 在了解quicklist基本结构之后我们在看看insert时结构会发生哪些变化!上面我们也提到了在redis.conf配置文件中
list-max-ziplist-size
属性是用来设置quicklist中每个节点中的ziplist存储的大小设置的。
两端插入

- 第一种情况就是我们需要插入的数据是在两端的。如上图所示我们在redis.conf配置文件中设置的
list-max-ziplist-size: 2
。表示内部节点ziplist中entry个数最大为2 。此时我们head头部节点中已经存储了两个内容,tail尾部节点存储的是1个节点!
- 这个时候如果我们想头部添加一个元素是obj1 。 可想而知我们是无法加入的,这个时候redis会重新创建一个ziplist结构并包含obj1 ,将新创建的ziplist加入到链表的头部之后

- 而obj2加入尾结点时,因为尾结点的节点数是1还未达到峰值2,所以直接就加入了。最终的效果图如下

中间插入
st=>start: Insert
ziplistInsert=>operation: 向ziplist中插入
subziplistInsert=>operation: 将该ziplist拆分两个ziplist, 在对应位置加入
insertNear=>operation: 插入相邻的ziplist中
newZipInsert=>operation: 新建ziplist插入
cond=>condition: ziplist是否可以容纳
headtailCond=>condition: 插入位置在ziplist两端
nearheadtailCond=>condition: 相邻ziplist是否可以容纳
e=>end: 快乐的一天
st->cond
cond(yes)->ziplistInsert
cond(no)->headtailCond(yes)->nearheadtailCond
headtailCond(no)->subziplistInsert
nearheadtailCond(yes)->insertNear
nearheadtailCond(no)->newZipInsert
总结

参考文献
边栏推荐
- 光流传感器初步测试:GL9306
- 【推荐系统基础】正负样本采样和构造
- How does starfish OS enable the value of SFO in the fourth phase of SFO destruction?
- [leetcode] 20. Valid brackets
- Pigsty: out of the box database distribution
- The difference between -s and -d when downloading packages using NPM
- Introduction to programming hardware
- Two small problems in creating user registration interface
- 数据库查询——第几高的数据?
- Usage of limit and offset (Reprint)
猜你喜欢
某马旅游网站开发(登录注册退出功能的实现)
Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis
CoinDesk评波场去中心化进程:让人们看到互联网的未来
Chisel tutorial - 04 Control flow in chisel
52岁的周鸿祎,还年轻吗?
【編程題】【Scratch二級】2019.12 飛翔的小鳥
STM32F1与STM32CubeIDE编程实例-旋转编码器驱动
某马旅游网站开发(对servlet的优化)
Kubectl 好用的命令行工具:oh-my-zsh 技巧和窍门
Set up personal network disk with nextcloud
随机推荐
【编程题】【Scratch二级】2019.03 垃圾分类
Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis
全自动化处理每月缺卡数据,输出缺卡人员信息
Basic learning of SQL Server -- creating databases and tables with the mouse
[programming problem] [scratch Level 2] December 2019 flying birds
Cmake learning notes (1) compile single source programs with cmake
【编程题】【Scratch二级】2019.12 飞翔的小鸟
Usage of limit and offset (Reprint)
35岁那年,我做了一个面临失业的决定
webflux - webclient Connect reset by peer Error
SQL uses the in keyword to query multiple fields
Trust orbtk development issues 2022
快速回复二极管整流特性
Postgres timestamp to human eye time string or millisecond value
About the difference between ch32 library function and STM32 library function
FFA与ICGA造影
Install sqlserver2019
每日刷题记录 (十六)
Fully automated processing of monthly card shortage data and output of card shortage personnel information
面试题详解:用Redis实现分布式锁的血泪史