Redis是如何避免“数组+链表”的过长问题

目录

一、扩展和收缩

二、使用高质量的哈希函数

三、使用跳跃表(skiplist)或其他数据结构

四、哈希表分片


一、扩展和收缩

       Redis通过动态调整哈希表的大小来解决“数组+链表”的长度问题,这涉及到两个过程:扩展(Expand)和收缩(Shrink)。

  1. 扩展:

    • 当哈希表的负载因子(load factor)超过一个阈值时,Redis会进行扩展操作。
    • 负载因子是哈希表已存储的元素数量与哈希表大小的比值。
    • 扩展操作包括分配一个新的更大的哈希表,并逐渐将旧表中的所有键值对rehash到新表中。
  2. 收缩:

    • 相对地,当负载因子低于另一个阈值时,Redis会执行收缩操作,减少哈希表的大小。
    • 这通常发生在删除大量键值对后,为了节省内存空间,Redis会将键值对rehash到一个更小的哈希表中。

   负载因子和rehash

  • 负载因子的计算:

    • 负载因子 = 哈希表中的元素数量 / 哈希表的大小
    • 当负载因子太高时,意味着发生哈希冲突的可能性增加,链表会变得较长,影响性能。
    • 当负载因子太低时,意味着内存使用不够高效。
    • 默认扩展负载因子:
      • 在没有进行BGSAVE或BGREWRITEAOF操作时,负载因子超过1时进行扩展。
      • 如果正在进行BGSAVE或BGREWRITEAOF操作,则负载因子阈值提高到5,即负载因子超过5时进行扩展。这意味着在正常情况下,当哈希表的负载因子超过1时,Redis就会触发扩展操作。但是,如果Redis正在进行磁盘写操作,如BGSAVE或BGREWRITEAOF,为了避免在磁盘IO已经很高的情况下进一步增加内存重分配的负担,它会提高扩展操作的负载因子阈值到5。这样可以在一定程度上平衡内存使用和磁盘IO之间的性能。
    • 当哈希表的负载因子小于0.1时,Redis会进行收缩操作。
  • rehash过程:

    • rehash是将所有键值对从旧的哈希表移动到新的哈希表的过程。
    • Redis使用渐进式rehash,它不是一次性完成,而是分多次进行,以避免长时间的阻塞。

   渐进式rehash

  • 渐进式rehash的实现:
    • 在rehash期间,Redis同时保持旧表和新表。
    • 每次对哈希表的操作(如添加、删除、查找)时,Redis会将旧哈希表的一部分键值对迁移到新哈希表。
    • 这样可以将rehash的计算量分散到每个操作上,避免一次性的大量计算导致服务不可用。

二、使用高质量的哈希函数

       Redis使用MurmurHash等高质量的哈希函数来减少哈希冲突。

三、使用跳跃表(skiplist)或其他数据结构

     对于有序数据集合,Redis使用跳跃表而不是链表来存储元素,跳跃表的平均和最坏情况下的时间复杂度都比链表要好。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。 1. 字符串 字符串是Redis最基本的数据结构,底层采用简单动态字符串(SDS)实现。SDS本质上是一个带有缓冲区的结构体,可以实现动态扩容和缩容,支持O(1)时间复杂度的字符串操作。 2. 哈希 哈希是Redis中的一种键值对集合,底层采用哈希表实现。哈希表采用数组+链表的结构组织数据,可以实现O(1)时间复杂度的键值查询、插入、删除等操作。 3. 列表 列表是Redis中的一种双向链表结构,底层采用双向链表实现。双向链表可以实现O(1)时间复杂度的插入、删除等操作,可以用于实现队列、栈等数据结构。 4. 集合 集合是Redis中的一种无序集合,底层采用哈希表实现。哈希表可以实现O(1)时间复杂度的元素查询、插入、删除等操作,可以用于实现优秀的去重和交集、并集、差集等操作。 5. 有序集合 有序集合是Redis中的一种有序集合,底层采用跳表和哈希表实现。跳表可以实现O(logN)时间复杂度的元素查询、插入、删除等操作,而哈希表可以实现O(1)时间复杂度的元素查询、插入、删除等操作,可以用于实现按照分值排序的有序集合。 综上所述,Redis支持多种数据结构,每种数据结构底层采用不同的数据结构实现,可以根据具体的应用场景选择合适的数据结构来存储数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值