外观
Redis 遇到哈希冲突怎么办
链地址法
- 原理:每个哈希桶维护一个链表,当不同的键通过哈希函数计算得到相同的哈希地址时,这些键值对会被添加到对应哈希桶的链表中。
- 优点:操作简单,插入、查找和删除的时间复杂度通常为
O (1)
。 - 缺点:当链表长度较长时,查找效率会降低,并且需要额外的内存空间来存储链表结构。
再哈希法(Rehashing
)
- 原理:当哈希表的负载因子超过一定阈值时,Redis 会触发再哈希操作。创建一个新的更大的哈希表,通常大小是原哈希表的两倍,然后将原哈希表中的键值对逐一迁移到新的哈希表中,并根据新的哈希函数重新计算它们的存储位置。
- 优点:可以减少冲突,使哈希表中的数据分布更均匀,提高查找效率。
- 缺点:再哈希操作需要一定的时间和资源,在数据量较大时可能会对性能产生一定影响。
渐进式再哈希
- 原理:Redis 使用两个全局哈希表,一个用于当前使用(主哈希表),一个用于扩容(备用哈希表)。在再哈希过程中,不是一次性将所有数据从旧表迁移到新表,而是在每次执行写命令时,除了正常处理这些命令外,还会将一些键值对从旧哈希表迁移到新哈希表中,逐步完成迁移。
- 优点:避免了一次性重哈希带来的长时间阻塞,保证了 Redis 服务的正常运行,不会因为哈希表的重新构建而出现长时间的停顿。
- 缺点:需要额外的空间来存储两个哈希表,并且迁移过程相对复杂。
开放寻址法
- 原理:当发生哈希冲突时,会顺序地查找下一个可用的数组位置,直到找到一个空闲位置为止。有线性探测、二次探测和伪随机探测等变体。
- 优点:可以减少内存开销,因为不需要额外的数据结构来存储冲突项。
- 缺点:随着负载因子增加,性能可能显著降低,尤其是当哈希表接近满载时。在 Redis 中使用相对较少,因为链地址法已经能够很好地处理大多数哈希冲突情况。