redis 六. list应用场景及底层分析
List 类型
- 一. 简单命令示例
- 二. java 操作示例
- 三. 使用场景
- 四. 底层分析
一. 简单命令示例
1.首先简单说明: List是一个双端链表的结构,内容是2的32次方减1个元素,大概40多亿,主要功能有push/pop等,一般用在栈,队列,消息队列等场景
2.简单命令
//1.向列表左边添加元素
LPUSH key value[value...]
//2.向列表右边添加元素
RPUSH key value[value...]
//3.查看列表
LRANGE key start stop
//4.获取列表中的元素个数
LLEN key
二. java 操作示例
- 操作 List 列表类型,按照插入顺序排序,可以添加一个元素到列表的头部(左边)或者尾部(右边),通过list进行指定下标的查询,可以做到简单分页
@Testpublic void test03(){//1.创建操作List类型数据的对象ListOperations<String ,String> listOperations= stringRedisTemplate.opsForList();//2.左上添加,第一个添加的会被后一个添加的挤压到下面listOperations.leftPush("student","liuliuliu");//3.右下追加,第一个添加的会被后一个添加的挤到上面listOperations.rightPush("students", "Zhao Liu");//4.查询,根据key与下标获取指定位置的数据,左闭右闭,两边包含,返回一个ListList<String> students = listOperations.range("student", 0,2);//5.根据key与指定下标获取单个数据String stu = listOperations.index("student", 1);//6.获取当前List类型数据的长度Long total = listOperations.size("student");//7.删除List类型数据,key为student的,value值为"Li",在List中第二次出现的,listOperations.remove("student", 2, "Li");// 删除多条,有左删除一条,右删除一条等stringRedisTemplate.delete("student");//8.从左边开始获取并删除String srt1 = listOperations.leftPop("student");//9.右边开始获取并删除String str2= listOperations.rightPop("student");}
三. 使用场景
- 公众号订阅: 假设用户a订阅了某个公众号sss,当sss公众号发布新文章,就会push到a用户的list中
//发布文章命令
LPUSH (like文章模块+a用户id) sss公众号文章id, bbb公众号文章id
//分页
LRANGE (like文章模块+a用户id) 0 9
- 商品评论列表: 一个商品会被不同用户评论,保存评论是按照先后顺序排序,查询商品时按照时间逆序排序,list存储时,key是商品id,value是评论信息:商品编号
LPUSH (品id)key 评论者id:评论信息
四. 底层分析
- list底层有linkedList、zipList和quickList三种存储方式
- 当列表对象保存的所有字符串元素的长度都小于 list-max-ziplist-value 默认 64字节, 并且保存的元素数量小于list-max-ziplist-entries默认512个时采用zipList, 否则采用linkedlist
- linkedlist: redis中自建了listNode对象, 通过内部的prev 和 next 指针组成的一个双端链表,
- 在redis 在 3.2 版本时,考虑到redis的空间存储效率和时间效率,引入了quicklist快速列表作为 list 的底层实现可以看成ziplist+linkedList实现的一个双端链表,链表中的每一个节点都以压缩列表ziplist的结构保存着数据,而ziplist有多个entry节点,保存着数据。相当于一个quicklist节点保存的是一片数据,而不再是一个数据
- redis中封装了quicklist 结构体变量, 内部通过quicklistNode 保存每一个节点数据,
typedef struct quicklist {quicklistNode *head;quicklistNode *tail;unsigned long count; /* total count of all entries in all ziplists */unsigned long len; /* number of quicklistNodes */int fill : QL_FILL_BITS; /* fill factor for individual nodes */unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */unsigned int bookmark_count: QL_BM_BITS;quicklistBookmark bookmarks[];
} quicklist;
typedef struct quicklistNode {//上一个node节点struct quicklistNode *prev; //下一个nodestruct quicklistNode *next; //保存的数据 压缩前ziplist 压缩后压缩的数据unsigned char *zl; //表示zl执行的ziplist的总大小,注意如果ziplist被压缩了,这个sz的值仍然时压缩前的大小 unsigned int sz; //表示ziplist包含的数据个数,16bitunsigned int count : 16; //表示ziplist是否压缩,1表示没有,2表示压缩了unsigned int encoding : 2; //预留字段,当前是一个固定值2,表示使用zplist作为数据容器unsigned int container : 2; //解压标记1, 通过该标记可以再次压缩unsigned int recompress : 1;unsigned int attempted_compress : 1; unsigned int extra : 10;
} quicklistNode;
- 使用quicklist 插入数据时可以头部插入,或者尾部插入,
- 如果头节点(或尾节点) 上ziplist大小没有超过限制(即_quicklistModeAlLowEInsert 返回1),那么新数据被直接插入到ziplist中(调明ziplisteush ) 。
- 如果头节点(或尾节点)上ziplist太大了,那么新创建一个quicklistlode节点(对应地也会新创建一个ziplist),然后把这个新创建的节点插入到quicklist双向链表中
- quicklist 在任意指定位置插入数据时
- 当插入位置所在的ziplist大小没有超过限制时,直接插入到ziplist中
- 当插入位置所在的ziplist大小超过了限制,但插入的位置位于ziplist两端,并且相邻的quicklist链表节点的ziplist大小没有超过限制,那么就转而插入到相邻的那个quicklist链表节点的ziplist中;
- 当插入位置所在的ziplist大小超过了限制,但插入的位置位于ziplist两端,并且相邻的Squicklist链表节点的ziplist大小也超过限制,这时需要新创建一个quicklist链表节点插入。
- 对于插入位置所在的ziplist大小超过了限制的其它情况(主要对应于在ziplist中间插入数据的情况),则需要把当前ziplist分裂为两个节点,然后再其中一个节点上插入数据
- quicklist 查找: quicklist的节点是由一个一个的ziplist构成的每个ziplist都有大小,所以先根据每个node个数,找到对应的ziplist,调用ziplist的index就能成功找到。
- quicklist 删除: 在区间删除时,会先找到start 所在的 quicklistlode,计算删除的元素是否小于要删除的count,如果不满足删除的个数,则会移动至下一个quicklistNode 继续删除,依次循环直到删除完成为止
相关文章:
redis 六. list应用场景及底层分析
List 类型一. 简单命令示例二. java 操作示例三. 使用场景四. 底层分析一. 简单命令示例 1.首先简单说明: List是一个双端链表的结构,内容是2的32次方减1个元素,大概40多亿,主要功能有push/pop等,一般用在栈,队列,消息队列等场景 2.简单命令 //1.向列表左边添加元素 LPUSH ke…...
成语填字接龙隐私政策
1. 适用范围 (a) 在您注册本应用帐号时,您根据本应用要求提供的个人注册信息; (b) 在您使用本应用网络服务,或访问本应用平台网页时,本应用自动接收并记录的您的浏览器和计算机上的信息,包括但不限于您的IP地址、浏览…...
导出LKD3588开发板的根文件系统
序:将RK3588上的整个根文件系统的文件通过ssh拷贝到PC系统(虚拟机) 工具:RK3588上的ubuntu系统需要安装:ssh, rsync。 PC电脑(虚拟机)上安装:ssh, rsync。 安装ssh 和rsync不做介绍,百度里面全是,也很简单需要设置开发板root权限的密码,因为后面同步文件的时候会用到…...
【统计模型】某地区土壤所含可给态磷回归分析
目录 某地区土壤所含可给态磷回归分析 一、研究目的 二、数据来源和相关说明 三、描述性分析 3.1 样本描述 3.2 数据可视化 四、数据建模 4.1 回归模型A 4.2 回归模型B 4.3 回归模型B模型诊断 4.4 回归模型C 五、结论及建议 5.1 结论 5.2 建议 六、代码 某地区土…...
redis 十. 线程基础
目录一. redis 基础复习与了解redis6二. redis 线程问题总结一. redis 基础复习与了解redis6 redis官网, redis中文网站, redis命令参考网站此处以redis6.0.8或以上版本为例(查看自己redis版本命令"redis- server -v")按照redis6以上版本测试使用时,redis.conf下需要…...
NQA简介
NQA简介定义目的NQA原理描述使用DHCP进行测试DNS测试NQA的联动机制NQA的应用场景定义 网络质量分析NQA(Network Quality Analysis)是一种实时的网络性能侦探和统计技术,可以对响应时间、网络抖动、丢包率等网络信息进行统计。NQA能够实时监视…...
[python]上下文管理contextlib模块与with语句
文章目录with语句自定义对象支持withcontextlib模块closing自动关闭suppress回避错误ExitStack清理Python 中的 with 语句用于清理工作,封装了 try…except…finally编码范式,提高了易用性。with语句 with语句有助于简化资源管理: # 离开作…...
STM32之TIM编码器接口
编码器简介: 例子讲解:正交编码器有两个输出,一个A相,一个B相,AB接口输出正交信号。然后接入STM32的定时器的编码器接口,编码器接口自动控制定时器时基单元中的CNT计数器进行自增或自减,比如初始…...
b站第一,Python自动化测试实战详细教学,3天教你学会自动化测试
目录 简介 Python自动化测试概述 Python自动化测试目标 Python自动化测试流程 1. 测试计划和设计 2. 测试脚本开发 3. 测试执行和管理 4. 测试维护和优化 Python自动化测试最佳实践 Python自动化测试工具和框架 结论 简介 自动化测试是软件开发过程中一个必不可少的…...
刷题记录:P8804 [蓝桥杯 2022 国 B] 故障 条件概率
传送门:洛谷 题目描述: 题目较长,此处省略 输入: 3 5 30 20 50 0 50 33 25 0 30 0 35 0 0 0 0 0 25 60 1 3 输出: 2 56.89 1 43.11 3 0.00读完题目,我们会发现其实题目给了我们两个事件,并且这两个事件是相互关联的.因此不难想到使用条件概率 我们将故障原因看做事件AAA,结合…...
【算法】常用的基础数论
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下🐾 文章目录1.GCD&LCM2.判断素数(质数)3.分解质因子1.GCD&LCM 最大公约数&最小共倍数 欧几里得算法——高效 //最大公约数 int gcd(int x,i…...
云原生场景下的容器网络隔离技术
云原生场景下的容器网络隔离技术 一、研究背景 随着云计算时代的到来,尤其是容器化技术的飞速发展,云原生作为云计算的未来阶段,其安全势必成为云安全的主要战场。从目前的云原生环境来看,云原生网络安全问题层出不穷࿰…...
用python绘制有向图
目录 添加边权重的有向图思路介绍代码实现效果图设置不同的样式节点和边的有向图思路介绍代码实现效果图下面的Python代码用于绘制有向图,其中使用了 networkx和 matplotlib.pyplot等库。 添加边权重的有向图 思路介绍 首先,创建了一个空的有向图像对象G,并添加了4个节点…...
Spring MongoDB 开发教程(一)—官方原版
MongoDB支持包含一系列功能:Spring配置支持基于Java的configuration类或Mongo驱动程序实例和副本集的XML命名空间。MongoTemplate帮助类,在执行常见的Mongo操作时提高生产力。包括文档和POJO之间的集成对象映射。将异常转换为Spring的可移植数据访问异常…...
数据结构——二叉搜索树
一、二叉搜索树概念 二叉搜索树又叫二叉排序树,它或是空树,或是具有以下性质的二叉树: (1)若它的左子树不为空,则左子树上的所有节点的值都小于根节点的值; (2)若它的…...
23年5月高项学习笔记3---项目管理概述
项目是创造独特的产品、服务或成果而进行的临时性的工作 独特:每个项目都不一样 可交付成果:某一过程,阶段或项目完成时形成的独特的并且可验证的产品、服务或成果。 临时的:明确的起点和终点、 -------- 项目集: 相…...
【组织架构】中国铁路成都局集团有限公司
0 参考 中国铁路成都局集团有限公司 1 公司介绍 中国铁路成都局集团有限公司,是中国国家铁路集团有限公司管理的18个铁路局集团有限公司之一,简称“成局”,地处中国西南,管辖范围辐射四川、贵州、重庆地区。管内地形复杂&#x…...
剧前爆米花--爪哇岛寻宝】java多线程案例——单例模式、阻塞队列及生产者消费者模型、定时器、线程池
作者:困了电视剧 专栏:《JavaEE初阶》 文章分布:这是关于java多线程案例的文章,进行了对单例模式、阻塞队列及生产者消费者模型、定时器和线程池的讲解,希望对你有所帮助! 目录 单例模式 懒汉模式实现 饿…...
Guitar Pro8中文版更新说明及系统要求介绍
Guitar Pro吉他软件是初学作曲,特别是同时又初学吉他的朋友们的良师益友,是一款极佳的初级软件,是非实时作曲软件之中的一件佳作。Guitar Pro在吉他和弦、把位的显示、推算、查询、调用等方面,也异常方便、简洁、直观和浩瀚&#…...
【id:19】【20分】A. 三数论大小(引用)
题目描述 输入三个整数,然后按照从大到小的顺序输出数值。 要求:定义一个函数,无返回值,函数参数是三个整数参数的引用,例如int &a, int &b, int &c。在函数内对三个参数进行排序。主函数调用这个函数进行…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
