List 数据结构

  1. Redis 3.2 前,使用 压缩列表zipList 或 双向链表linkedList

    当同时满足下面两个条件时,使用zipList存储数据

    • list保存的每个元素长度小于64字节
    • 列表中数据个数少于512个
  2. 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的更多相关文章

  1. Redis原理与实践总结

    Redis原理与实践总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述.如有错误,还望见谅,欢迎指 ...

  2. Redis原理篇

    Redis原理篇 1.发布 订阅模式 1.1列表 的局限 ​ 前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...

  3. Redis 系列(04-2)Redis原理 - 内存回收

    目录 Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 1. 过期策略 1.1 定时过期(主动淘汰) 1.2 惰性过期(被动淘汰) 1.3 定期过期 2. 淘汰策略 2. ...

  4. Redis原理详解

    Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...

  5. 面试被吊打系列 - Redis原理

    小张兴冲冲去面试,结果被面试官吊打! 小张: 面试官,你好.我是来参加面试的. 面试官: 你好,小张.我看了你的简历,熟练掌握Redis,那么我就随便问你几个Redis相关的问题吧.首先我的问题是,R ...

  6. redis原理分析

    基本全是参考http://blog.csdn.net/a600423444/article/details/8944601     redis的使用大家都很熟悉,可能除了watch 锁,pipelin ...

  7. Redis原理及使用

    一:原理介绍 1:什么是redis?  Redis 是一个基于内存的高性能key-value数据库. 2:Reids的特点Redis本质上是一个Key-Value类型的内存数据库,很像memcache ...

  8. Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)

    一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...

  9. redis原理及实现

    1 什么是redis redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他 ...

  10. Redis原理及集群相关知识

    读书笔记 <Redis开发与运维 > Redis使用场景 作为缓存层 减少对Mysql的压力 计数功能 比如使用原子命令incr 共享Session 设置过期时间 可以限制短信接口等调用 ...

随机推荐

  1. Solution -「NOI 2017」「洛谷 P3825」游戏

    \(\mathscr{Description}\)   Link.   给大家看个乐子: link, 懒得概括题意啦. \(\mathscr{Solution}\)   对于没有 X 的情况, 显然可 ...

  2. 【开源】C#上位机必备高效数据转换助手

    一.前言 大家好!我是付工. 我们在进行上位机开发时,从设备端获取到的数据之后,需要进行一定的数据处理及转换,才能生成我们需要用的数据. 这其中就涉及到了各种数据类型之间的相关转换,很多非科班出身的电 ...

  3. .NET 9 new features-Microsoft.ML.Tokenizers 库

    在 .NET 9 中,微软引入了 Microsoft.ML.Tokenizers 库,为 .NET 开发者提供了强大的文本标记化功能. 一.什么是Microsoft.ML.Tokenizers Mic ...

  4. 注册表判断是否安装微软Edge浏览器

    自己摸索的,注册表判断是否安装微软Edge浏览器: bool checkInstalledMsEdge() { try { using(var ieKey = Registry.LocalMachin ...

  5. Phi小模型开发教程:C#使用本地模型Phi视觉模型分析图像,实现图片分类、搜索等功能

    大家好,我是编程乐趣. 我们都知道,要实现对结构化的数据(文本)搜索是比较容易的,但是对于非结构化的数据,比如图片,视频就没那么简单了. 但是现在有了AI模型,实现图片分类.搜索等功能,就变得容易很多 ...

  6. 从购物找零到两数之和:一道经典算法题的深度解析|LeetCode 1 两数之和

    LeetCode 1 两数之和(Two Sum) 点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中) 生活中的算法 还记得上次去超市购物吗?你拿着一张100元钞票 ...

  7. postman获取时间戳并自动计算token

    工作中时常要测试接口,公共请求参数包括id, timestamp, token, token = MD5(id + key + timestamp)并转大写. 每次用外部工具去获取时间戳并计算toke ...

  8. go实现设计模式(1)——简介

    六大原则 开闭原则(Open Close Principle) 对扩展开放,对修改关闭.对程序进行拓展时,尽量不去修改原有的代码,应该通过扩展实体的行为来实现. 里氏替换原则(Liskov Subst ...

  9. WPF 创建自定义鼠标光标指针

    WPF Cursor类中的两个构造函数: public Cursor(Stream cursorStream) public Cursor(string cursorFile) 以上的构造函数所使用的 ...

  10. CF895C Square Subsets 题解

    看到 \(a_i\le 70\) 后,发现 \(n\) 啥用没有,因为只需要枚举 \(1-70\) 选几个即可. 看到求完全平方数后,想到分解质因数,由于 \(a_i\le 70\),所以只有 \(1 ...