当前位置: 首页 > news >正文

Redis 数据结构的底层实现—字符串、哈希表、列表、集合

Redis 的键(key)查找机制基于哈希表实现。常用的数据结构有字符串、哈希表、列表、集合及有序集合。

字符串

String,键和值可以是字符串或二进制数据。

哈希表

Hash,类似Java的HashMap。

列表

List,线性结构。可以按照元素被推入列表中的顺序来存储。

集合

Set,存储不重复的元素。无序。

有序集合

Sorted Set,每个元素由一个成员和分值组成。根据分值排序,分数不重复。

表 Redis 常用的5种数据结构

1 字符串 String

底层结构: SDS(Simple Dynamic String,简单动态字符串)。

struct sdshdr {
   int len; // 已使用的字节长度
   int alloc; // 总分配的字节长度
   char buf[]; // 实际存储字符的字节数组
}

SDS具有以下优势:

1.减少内存重分配次数。

空间预分配,当SDS需要扩容时,会额外预分配alloc的冗余空间。

惰性空间释放,缩短字符串时,不会立即释放多余空间。

2.二进制安全。

C字符串以\0作为结尾标识符,无法存储包含\0的二进制数据。而SDS根据len及buf[]来读取数据。

3.兼容部分C字符串函数。

SDS的buf数组仍以\0结尾。

2 哈希表 Hash

有两种结构:ziplist(压缩列表)与hashtable(哈希表)。

ziplist -> hashtable(redis不支持逆转)转换触发条件:

  1. hash-max-ziplist-entires(默认512),字段数量。
  2. hash-max-ziplist-value(默认64字节),所有字段和值的最大长度。

ziplist

是一种紧凑的,连续内存块结构。插入字段及对应值时,将它们作为两个新节点追加到ziplist尾部。查找及插入的时间复杂度为0(n)。

hashtable

查找和插入的时间复杂度为O(1),适合大规模数据。

表 哈希表的底层结构ziplist与hashtable的对比

2.1 哈希表的渐进式Rehash

Rehash 是指对哈希表的大小进行扩展或收缩。为避免Rehash对服务器性能造成影响,服务器会分多次、渐进式地将ht[0](原哈希表)里所有的键值迁移到ht[1]中。步骤如下:

  1. 初始化新哈希表ht[1],设置rehashidx=0。
  2. 逐步迁移数据。从ht[0].table[rehashidx]迁移整个桶(链条上所有的节点)到ht[1],rehashidx++,指向下一个待迁移的桶。
  3. 操作兼容。在rehash期间,插入直接写入ht[1];删除/查找/更新操作,先在ht[0]中查找,若未找到,则继续在ht[1]中查找;若某个桶正在迁移,对该桶的访问会短暂阻塞,直到迁移完成。
  4. 完成迁移,rehashix=-1,ht[0]情况,将ht[1] 设置为ht[0]。

3 列表 List

底层结构:quicklist。快速列表时一个由多个ziplist节点双向连接的链表。每个ziplist节点称为quicklistNode。

头部/尾部插入O(1):若头/尾节点的ziplist未满,直接插入到ziplist中,若已满,创建新的quicklistNode,插入元素后链接到链表头部/尾部。

中间插入O(n):需要遍历定位到具体位置。可能触发ziplist分裂和内存重分配。

list-max-ziplist-size参照控制ziplist的元素数量。

3.1 内存大小优化—压缩

对离头尾节点一定深度(list-compress-depth)的ziplist进行压缩,来减少内存占用。

将ziplist的原始数据通过LZF算法压缩,压缩后的数据替换原ziplist,更新quicklistNode.encoding为LZF。

读操作:如果encoding为LZF,则触发解压,生成临时ziplist,标记recompress=1(后续需要重新压缩)。

写操作:若recompress=1,再次调用LZF压缩。

4 集合 Set

有两种结构:intset 与hashtable。

intset -> hashtable 触发条件:

  1. 插入的元素不是整数。
  2. 元素数量超过set-max-intset-entires(默认512)。

intset是一个有序的整数数组,查找的时间复杂度为O(logn)。

hashtable 中每个entry的key字段存储Set的成员,value字段固定为null。

5 有序集合 Sorted Set

有两种结构:ziplist 与 skip list + hashtable。

ziplist -> skip list + hashtable 触发条件:

  1. 元素数量大于zset-max-ziplist-entires(默认128)。
  2. 元素字节长度大于zset-max-ziplist-value(默认64字节)。

ziplist: 以连续内存块存储成员和分数,第一个节点保存成员,第二个节点保存成员的分值。从小到大进行排序。复杂度O(n)。

skip list + hashtable : 哈希表存储的是元素key为元素,value为分值,作用是通过成员直接查找分数。复杂度O(log n)。


文章转载自:
http://casemate.wkuuf.cn
http://calpac.wkuuf.cn
http://bracteole.wkuuf.cn
http://arborization.wkuuf.cn
http://autoecious.wkuuf.cn
http://antifertility.wkuuf.cn
http://bovver.wkuuf.cn
http://airward.wkuuf.cn
http://beau.wkuuf.cn
http://cardiodynia.wkuuf.cn
http://beautiful.wkuuf.cn
http://boss.wkuuf.cn
http://ceramide.wkuuf.cn
http://antetype.wkuuf.cn
http://adamantane.wkuuf.cn
http://aleuronic.wkuuf.cn
http://antiozonant.wkuuf.cn
http://agrologic.wkuuf.cn
http://adoptable.wkuuf.cn
http://angell.wkuuf.cn
http://canikin.wkuuf.cn
http://carrion.wkuuf.cn
http://breadwinner.wkuuf.cn
http://adolesce.wkuuf.cn
http://chemoimmunotherapy.wkuuf.cn
http://bcom.wkuuf.cn
http://cerotype.wkuuf.cn
http://beleaguer.wkuuf.cn
http://apollinian.wkuuf.cn
http://birder.wkuuf.cn
http://www.dtcms.com/a/107787.html

相关文章:

  • 【银河麒麟系统常识】命令:reboot(立即重启操作系统)
  • SQL server 2022和SSMS的使用案例1
  • linux,物理机、虚拟机,同时内外网实现方案;物理机与虚拟机互通网络;
  • 机器学习 分类算法
  • 苍穹外卖day12
  • 网络安全的重要性与防护措施
  • 一、STM32简介
  • OpenCV 图形API(10)用于执行标量除以矩阵的逐元素操作函数divRC()
  • 低代码框架
  • 网络协议之系列
  • 商标知识产权管理系统平台有哪些功能?
  • 第三方平台步步紧逼之下,独立站商城系统应如何做
  • MoLe-VLA:通过混合层实现的动态跳层视觉-语言-动作模型实现高效机器人操作
  • 牛脸分割数据集labelme格式1324张1类别有增强图片
  • macvlan 和 ipvlan 实现原理及设计案例详解
  • 华为Eudemon8000E Series CFCard概述
  • MySQL 事务与锁机制详解
  • pytorch 离线安装
  • win11 设置 wsl2 ubuntu
  • 4 月 6 日 共赴香港|聚焦 Polkadot 为 Web3 云开拓的创新实践路径!
  • IGMP(Internet Group Management Protocol)与组播技术深度解析
  • 巧记英语四级单词 Unit1-2【晓艳老师版】
  • Spring笔记06-数据持久化
  • Cesium 核心思想及基础概念应用
  • 蓝桥杯高频考点——高精度(含C++源码)
  • Java服务端性能优化:从理论到实践的全面指南
  • Css径向渐变 - radial-gradient
  • 宽带空时波束形成算法原理及MATLAB仿真
  • 【每日算法】Day 16-1:跳表(Skip List)——Redis有序集合的核心实现原理(C++手写实现)
  • OkHttpHttpClient