02 Redis的数据结构

  1. Redis——“快”:μs速度找到KV并完成操作。依赖于

    a. 内存

    b. 数据结构

  2. 6种底层数据结构 & 5种Redis数据类型

dataStructure

  1. Redis的“快”中的“慢操作”
  • KV用哈希表存储,哈希表结构=数组+哈希桶

哈希表是一个指针数组,每个元素是一个指向entry结构体的指针(哈希桶)
entry包含两个元素:

  • *key——指向key的指针
  • *value——指向value的指针
  • 哈希表查找过程主要依赖于哈希计算,与数据量多少无直接关系
    hashTable_
  1. 哈希表存储要解决的问题

哈希冲突——链式哈希

rehash可能带来的操作阻塞——渐进式rehash

  • 哈希冲突
    • 解决:链式哈希——同一个哈希桶中多个entry用链表连接
    • entry结构体中增加*next指针指向下一个entry
    • hashTable
  • rehash可能带来的操作阻塞
    • 背景:链式哈希潜在问题——同一哈希桶内链接元素过多(同一桶内的冲突过多),导致查找KV时的时间消耗增加。
    • 解决:rehash——增加现有哈希桶数量,对entries进行重排,以减少单个桶内的冲突
    • rehash具体操作

      Redis默认使用两个全局哈希表,表1rehash


      a. 给表2分配比表1更大的空间(比如表1的2倍大小)

      b. 将表1数据重映射&copy到表2

      c. 释放表1空间

    • rehash中处理重映射&copy的时间会随着entries的增加而增加,涉及到了大量的数据copy操作,数据量大的情况下,极有可能阻塞Redis主线程,因此Redis采用渐进式rehash
  • 渐进式rehash

    原理:将表1每个桶的“重映射&copy”分散到Redis的每次请求上

  1. 集合数据的操作效率

集合数据的操作效率取决于两个因素:集合类型的底层数据结构、具体的操作

  • 集合类型的底层数据结构:整数数组、双向链表、哈希表、压缩列表、跳表

    • 压缩列表:

      有序数组

      表头增加3个字段:zlbytes——列表长度、zltail——列表尾偏移、zllen——列表中的entry个数

      表尾用zlend——列表结束标志

      ziparray

    • 跳表:

      有序链表上加多级序列

      通过索引位置的跳转实现数据快速定位

      索引通过链表连接

      jumpTable

    • 查找时,各个集合类型底层数据结构的时间复杂度表

      底层数据结构 时间复杂度
      哈希表 O(1)
      跳表 O(logN)
      双向链表 O(N)
      压缩列表 O(N)
      整数数组 O(N)
  • 不同操作的复杂度

    单元素操作是基础
    范围操作非常耗时
    统计操作通常g高效
    例外情况只有几个

    • 范围操作: 集合类型中的遍历操作
    • 统计操作:比如集合中元素个数的统计

图片来源于极客时间专栏《Redis核心技术与实战》

posted @ 2021-07-24 23:04  _程序兔  阅读(82)  评论(0编辑  收藏  举报