数据结构:快速的Redis有哪些慢操作?

一、底层数据结构

  • 简单动态字符串
  • 双向链表
  • 压缩列表
  • 哈希表
  • 调表
  • 整数数组
    在这里插入图片描述

二、键和值用什么结构组织?

Redis 使用了一个哈希表来保存所有键值对。一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以,我们常说,一个哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据,哈希桶中的元素元素保存的并不是值本身,而是指向具体值得指针
哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对——我们只需要计算键的哈希值,就可以知道它所对应的哈希桶位置,然后就可以访问相应的 entry 元素
在这里插入图片描述

全局是指Redis数据库中的所有key和value,是由一个哈希表来索引的。通过在这个哈希表中查询key,就可以找到对应的value。然后根据value的具体类型(例如Hash,Set,List等),再通过value的底层数据结构来读取具体的value数据,例如List通过双向链表来读取数据。

三、为什么哈希表操作变慢了?

  1. 原因:哈希冲突
  2. 解决方式:链表式,同一个哈希桶中的多个元素用一个链表来保存,它们之间依次用指针连接。

四、rehash

  1. 增加现有的哈希桶数量,让逐渐增多的 entry 元素能在更多的桶之间分散保存,减少单个桶中的元素数量,从而减少单个桶中的冲突
  2. Redis 默认使用了两个全局哈希表:哈希表 1 和哈希表 2。一开始,当你刚插入数据时,默认使用哈希表 1,此时的哈希表 2 并没有被分配空间。随着数据逐步增多,Redis 开始执行 rehash,这个过程分为三步:
    • 给哈希表 2 分配更大的空间,例如是当前哈希表 1 大小的两倍
    • 把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中
    • 释放哈希表 1 的空间
    • 原来的哈希表 1 留作下一次 rehash 扩容备用
    • 渐进式rehash执行时,除了根据键值对的操作来进行数据迁移,Redis本身还会有一个定时任务在执行rehash,如果没有键值对操作时,这个定时任务会周期性地(例如每100ms一次)搬移一些数据到新的哈希表中,这样可以缩短整个rehash的过程

五、渐进式rehash

Redis 仍然正常处理客户端请求,每处理一个请求时:

  1. 从哈希表 1 中的第一个索引位置开始,顺带着将这个索引位置上的所有 entries 拷贝到哈希表 2 中
  2. 等处理下一个请求时,再顺带拷贝哈希表 1 中的下一个索引位置的 entries
    把一次性大量拷贝的开销,分摊到了多次处理请求的过程中,避免了耗时操作,保证了数据的快速访问

六、集合类型底层数据结构

  • 整数数组
  • 双向链表
  • 哈希表
  • 压缩列表
  • 跳表
    查询时间复杂度
    在这里插入图片描述
压缩列表
  • 类似于一个数组,数组中的每一个元素都对应保存一个数据。
  • 和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数
  • 压缩列表在表尾还有一个 zlend,表示列表结束
  • 查找定位第一个元素和最后一个元素,可以通过表头三个字段的长度直接定位,复杂度是 O(1)。而查找其他元素时,只能逐个查找,此时的复杂度就是 O(N)
    在这里插入图片描述
跳表
  • 有序链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位
  • 查找过程就是在多级索引上跳来跳去,最后定位到元素。这也正好符合“跳”表的叫法。当数据量很大时,跳表的查找复杂度就是 O(logN)
    在这里插入图片描述

什么时候开始Rehash

  • 装载因子:哈希表中所有entry的个数除以哈希表的哈希桶个数
  • 装载因子大于等于1,且哈希表允许进行hash:每个桶里边都有一个元素,并且进行RDB生成或AOF时,哈希表被标记为不允许进行rehash
  • 装载因子大于等于5:数据量远远大于哈希桶的数量,马上进行rehash
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值