Redis学习笔记-哈希桶和底层数据结构

文章目录

  • Redis 学习笔记-哈希桶和底层数据结构
      • 1.Redis 基本数据类型
      • 2.Redis 底层数据结构类型
      • 3.Redis 基本数据类型和底层数据结构关系示意图
      • 4.key 是如何查找到哈希桶
        • 4.1 哈希表(HashTable)原理图
        • 4.2 哈希桶和数据类型对应原理图
        • 4.3 渐进式 rehash
      • 5.底层数据结构
        • 5.1 双向链表示意图
        • 5.2 压缩列表
        • 5.3 跳表
        • 5.4 不同数据结构时间复杂度
      • 6.小结

Redis 学习笔记-哈希桶和底层数据结构

前面文章介绍了 Redis 基本数据类型和这些数据类型对应的一些操作,知道了 Redis 很快的原因是 内存数据结构,这篇文章就围绕 数据结构 来介绍一下 Redis 底层有哪些数据结构,为什么这些数据结构会提升访问速度,学习这些底层数据结构将会加深对 Redis 设计原理的理解。

1.Redis 基本数据类型

  • String(字符串)
  • Set(集合)
  • Sorted Set(有序集合)
  • List(列表)
  • 散列表(哈希)
  • GEO
  • HyperLogLog
  • Stream(流)

2.Redis 底层数据结构类型

  • 简单动态字符串
  • 双向链表
  • 压缩列表
  • 哈希表
  • 跳表
  • 整数集合

3.Redis 基本数据类型和底层数据结构关系示意图

  • String 类型对应 简单动态字符串
  • List 类型对应 双向链表压缩列表
  • Hash 类型对应 压缩列表散列表
  • Sorted Set 类型对应 压缩列表跳表
  • Set 类型对应 散列表整数集合
    Redis学习笔记-哈希桶和底层数据结构_第1张图片

Tips:GEOHyperLogLogStream 后续文章单独讨论。

4.key 是如何查找到哈希桶

首先 key 需要经历 全局哈希表 找到 哈希桶,关于哈希表(HashTable) 的原理可以参考我之前写的文章来了解,哈希表也叫散列表,这里简单介绍一下 哈希表(HashTable) 的原理,每一个 key 可以通过哈希计算变成一个较大的整数,然后通过数学模型取就可以对应到某个数组中的索引,然后通过这个索引值可以快速找到数组中的元素,这个元素可以称为 哈希桶 元素,如下图所示简单展示了哈希表(HashTable)的实现原理:

4.1 哈希表(HashTable)原理图

Redis学习笔记-哈希桶和底层数据结构_第2张图片

Tips:如上图所示的数组可以称为一个哈希桶Redis 中解决哈希冲突时采用拉出一个链表来解决的。

4.2 哈希桶和数据类型对应原理图

Redis学习笔记-哈希桶和底层数据结构_第3张图片

4.3 渐进式 rehash

上述哈希桶需要考虑一个问题,当 key 的数量比较庞大时,可能导致哈希桶的数量不合理(即哈希取时的素数不合理),从而出现哈希冲突比较多的情况,直接带来的影响是哈希桶中的 entry 链表过长,众所周知,当链表太长的时候查找元素需要遍历(复杂度O(N))才能找到 key 对应的那一个 entry,为了解决这个问题 Redis 设计者采用了 渐进式 rehash,它的目的是重构哈希桶的数量,让哈希桶数量更加合理,使 key 对的 entry 在哈希桶中分布更加均匀,从而从概率角度上减少 entry 链表的长度,具体实现逻辑如下:

  • Redis 设计了 2 个全局哈希表,记作 哈希表A哈希表B,最开始默认使用哈希表A,哈希桶记作是 Ma哈希表B 不分配内存,等待调度。
  • 哈希表A 中的哈希桶冲突比较频繁,且数量比较大(某个阈值)的时候,就会启用 哈希表B,并且哈希表B的哈希桶数量Mb大于Ma(具体要依据数学模型)。
  • 哈希表B 建立好之后就需要考虑将哈希表A 的数据转移到 哈希表B 中,如果有大量的数据迁移可能会导致 Redis 线程阻塞导致业务停摆,这个时候 Redis 采用了 渐进式 rehash
  • 渐进式 rehash 可以简单理解为每次访问 哈希表A 数据的时候顺带带一点数据出来给 哈希表B,整个过程是 渐进 完成的,不会影响业务在正常运行。
  • 数据转移完成之后就会释放 哈希表A 的内存,等待下次同样的情况时,重构哈希桶使用。

5.底层数据结构

对于 字符串(String) 来说,找到哈希桶就可以直接对它操作(增删改查等)简单动态字符串,而对于 ListHashSorted SetSet 这些数据类型来说,找到哈希桶之后还需要对应到 双向链表压缩列表哈希表跳表整数集合这些底层数据结构中的,下面简单介绍一下几种数据结构:

5.1 双向链表示意图

Redis学习笔记-哈希桶和底层数据结构_第4张图片

5.2 压缩列表

压缩列表(ziplist) 实际是一个字节数组,它的设计目的是为了节约内存,和普通数组不同的是在数组头部会有三个字段,分别是 zlbytes(列表长度)zltail(列表尾部偏移量)zllen(entry 的个数),在 压缩列表 的尾部还会有 zlend(结束)字段,示意图如下图:
Redis学习笔记-哈希桶和底层数据结构_第5张图片

5.3 跳表

Redis学习笔记-哈希桶和底层数据结构_第6张图片

5.4 不同数据结构时间复杂度

Redis学习笔记-哈希桶和底层数据结构_第7张图片

6.小结

Redis 中的数据结构比较丰富,全部熟练地记住所有的操作比较困难,但掌握其底层数据结构原理之后,在如何选择合适的数据类型时能有一个理性地推断,而且也能根据这些原理合理地选择数据类型。

扫码关注
Redis学习笔记-哈希桶和底层数据结构_第8张图片

你可能感兴趣的:(Redis,数据结构和算法,redis,数据结构,数据库,nosql,mysql)