Redis 原理 - List
List 数据结构
Redis 3.2 前,使用 压缩列表zipList 或 双向链表linkedList
当同时满足下面两个条件时,使用zipList存储数据- list保存的每个元素长度小于64字节
 - 列表中数据个数少于512个
 
Redis 3.2 及之后的底层实现方式: quickList
quickList 是一个基于 zipList 的双向链表, quickList 的每个节点都是一个 zipList , 结合了双向链表和 zipList 的优点
双向链表就不多说了,就是基础的数据结构
压缩列表(zipList)
struct ziplist<T> {
    int32 zlbytes; // 整个压缩列表占用字节数
    int32 zltail_offset; // 最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点
    int16 zllength; // 元素个数
    T[] entries; // 元素内容列表,挨个挨个紧凑存储
    int8 zlend; // 标志压缩列表的结束,值恒为 0xFF
}
struct entry {
    int prevlen; // 前一个 entry 的字节长度
    int encoding; // 元素类型编码
    byte[] content; // 元素内容
}

- 优势: 内存连续,高效顺序访问,减少内存碎片.
 - 劣势: 当数据量过大时,zipList就不那么好用了. 因为为了保证它存储内容在内存中的连续性,插入的复杂度为O(N),而且如果超出zipList内存大小,还会做重新分配的内存空间,并将内容复制到新的地址. 如果数量大的话,重新分配内存和拷贝内存会消耗大量时间. 所以不适合大型字符串,也不适合存储量多的元素..
 
适用场景: 少量数据, 读远大于写,提供高效的读取操作
快速列表(quickList)
是zipList和linkedList的结合体,是将linkedList按段切分,每一段用zipList来紧凑存储
typedef struct quicklist {
    quicklistNode *head; // 指向quicklist的头节点
    quicklistNode *tail; // 指向quicklist的尾节点
    unsigned long count; // 压缩列表中总元素数量
    unsigned int len; //链表节点的个数 quicklistNode
    int fill : 16; // ziplist大小限定,由list-max-ziplist-size给定
    unsigned int compress : 16; // 节点压缩深度设置,由list-compress-depth给定
} quicklist;
typedef struct quicklistNode {
    struct quicklistNode *prev; // 指向上一个ziplist节点
    struct quicklistNode *next; // 指向下一个ziplist节点
    unsigned char *zl; // 数据指针,如果没有被压缩,就指向ziplist结构,反之指向quicklistLZF结构
    unsigned int sz; // 指向的ziplist的字节数
    unsigned int count : 16; // 指向的ziplist的元素个数
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  // 预留字段,存放数据的方式,1--NONE,2--ziplist
    unsigned int recompress : 1;     // 解压标记,当查看一个被压缩的数据时,需要暂时解压,标记此参数为1,之后再重新进行压缩
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; // 扩展字段
} quicklistNode;
typedef struct quicklistLZF {
    unsigned int sz; // LZF压缩后占用的字节数
    char compressed[]; // 柔性数组,存放压缩后的ziplist字节数组
} quicklistLZF;

在向quicklist添加一个元素的时候,不会像普通的链表那样,直接新建一个链表节点。而是会检查插入位置的 ziplist 是否能容纳该元素,如果能够容纳,那么就直接保存到ziplist,如果不能容纳,才会新建一个Node节点,并保存到新的 ziplist 中。
总结
quickList 结合了 ziplist 和 双向链表的优点, 相当于把 双向链表 拆分为 一段段的 ziplist , 每一段的 ziplist 是连续存储的, 可以做到高效的顺序访问,有利于减少内存碎片.
List的常用命令
- LPUSH key element ... 向列表的左侧插入一个或多个元素
 - RPUSH key element ... 向列表的右侧插入一个或多个元素
 - LPOP key 移除并返回列表左侧的第一个元素
 - RPOP key 移除并返回列表右侧的第一个元素
 - LRANGE key start stop 返回索引范围内的所有元素
 - BLPOP key timeout 移除并返回列表左侧的第一个元素,没有元素时会阻塞等待指定的时间
 - BRPOP key timeout 移除并返回列表右侧的第一个元素,没有元素时会阻塞等待指定的时间
 - 更多的List命令,请查阅 官方文档
 
Redis 原理 - List的更多相关文章
- Redis原理与实践总结
		
Redis原理与实践总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述.如有错误,还望见谅,欢迎指 ...
 - Redis原理篇
		
Redis原理篇 1.发布 订阅模式 1.1列表 的局限  前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...
 - Redis 系列(04-2)Redis原理 - 内存回收
		
目录 Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 1. 过期策略 1.1 定时过期(主动淘汰) 1.2 惰性过期(被动淘汰) 1.3 定期过期 2. 淘汰策略 2. ...
 - Redis原理详解
		
Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...
 - 面试被吊打系列 - Redis原理
		
小张兴冲冲去面试,结果被面试官吊打! 小张: 面试官,你好.我是来参加面试的. 面试官: 你好,小张.我看了你的简历,熟练掌握Redis,那么我就随便问你几个Redis相关的问题吧.首先我的问题是,R ...
 - redis原理分析
		
基本全是参考http://blog.csdn.net/a600423444/article/details/8944601 redis的使用大家都很熟悉,可能除了watch 锁,pipelin ...
 - Redis原理及使用
		
一:原理介绍 1:什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2:Reids的特点Redis本质上是一个Key-Value类型的内存数据库,很像memcache ...
 - Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)
		
一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
 - redis原理及实现
		
1 什么是redis redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他 ...
 - Redis原理及集群相关知识
		
读书笔记 <Redis开发与运维 > Redis使用场景 作为缓存层 减少对Mysql的压力 计数功能 比如使用原子命令incr 共享Session 设置过期时间 可以限制短信接口等调用 ...
 
随机推荐
- 内华达大地测量实验室gnss数据半自动化下载
			
内华达大地测量实验室GNSS数据半自动化下载 前言 目的:继上篇GNSS时序形变位移数据下载,介绍了内华达网站GNSS位移数据如何手动交互进行下载.后面发现若自己需要下载很多站点的数据,我要通过手动一 ...
 - manim边做边学--动画组合
			
动画组合类的作用是将多个动画组合起来,以实现更复杂的动画效果. Manim中有4个用于动画组合的类: AnimationGroup:将多个动画组合在一起同时播放,能一次性呈现多个对象的不同变化 Lag ...
 - IntelliJ IDEA2020永久激活破解教程(无限试用)
			
IntelliJ IDEA2020激活破解教程(无限试用) 鉴于想拥有一个十分舒适的编程环境,我特意将自己的电脑运行内存从4G扩展到12G,加装一个256G的固态作为C盘,并且将系统升级为Window ...
 - Springboot集成-ClickHouse
			
1.clickhouse应⽤场景 1.绝大多数请求都是用于读访问的 2.数据需要以大批次(大于1000行)进行更新,而不是单行更新:或者根本没有更新操作 3.数据只是添加到数据库,没有必要修改 4.读 ...
 - 消息中间件之-Kafka相关知识
			
前言 本篇文章是我基于拉勾kafka课程所作的笔记,包括Kafka基本架构.核心概念.生产者解析.消费者解析.存储.事务.一致性保证等等,希望对大家有所帮助. 一.kafka架构 Kafka基础知识 ...
 - docker 使用centos镜像运行javaweb
			
Docker 是 2014 年最为火爆的技术之一,几乎所有的程序员都听说过它.Docker 是一种"轻量级"容器技术,它几乎动摇了传统虚拟化技术的地位,现在国内外已经有越来越多的公 ...
 - DataGrip中执行ORACL语句块进行代码测试
			
--语句块执行使用关键字declare声明变量,变量间分号隔开,SELECT INTO语句给变量赋值,语句块放到BEGIN END之间. declare v_id int; v_val varchar ...
 - V-Control 开箱即用的.NET MAUI组件库发布了!
			
之前写过挺多的MAUI Sample,其中有很多代码可以打包成组件,当组件完善到一定程度,我会把控件封装起来放到控件库中. 今天,在这个仓库建立一年零八个月后,我觉得可以考虑将其作为开源库发布. 有很 ...
 - Java 将 RTF 转换为Word、PDF、HTML、图片
			
RTF文档因其跨平台兼容性而广泛使用,但有时在不同的应用场景可能需要特定的文档格式.例如,Word文档适合编辑和协作,PDF文档适合打印和分发,HTML文档适合在线展示,图片格式则适合社交媒体分享.因 ...
 - 在Windows系统中安装Open WebUI并连接Ollama
			
一.Open WebUI简介与安装前准备 Open WebUI是一个开源的大语言模型(LLM)交互界面,支持本地部署与离线运行.通过它,用户可以在类似ChatGPT的网页界面中,直接操作本地运行的Ol ...