面试题答案
一键面试1. Redis字典的渐进式rehash是什么
Redis的字典(dict)底层数据结构为哈希表。当哈希表保存的键值对数量太多或太少时,需要对哈希表进行扩展或收缩,这就涉及到rehash操作。 渐进式rehash指的是在扩展或收缩哈希表时,不是一次性将旧哈希表中的所有键值对全部迁移到新哈希表,而是分多次逐步迁移。具体做法是:
- 为新哈希表分配空间。
- 在字典中维持一个索引计数器变量
rehashidx
,它从0开始,每进行一次rehash相关的操作(如插入、删除、查找等),就将rehashidx
指向的旧哈希表中的键值对迁移到新哈希表,然后rehashidx
自增1。 - 当
rehashidx
递增到旧哈希表的最后一个索引时,表明rehash操作完成,将rehashidx
设为-1。
2. 为什么要采用渐进式rehash
- 避免阻塞:如果一次性完成rehash,当哈希表中键值对数量巨大时,会消耗大量的CPU时间,导致Redis在这段时间内无法处理其他客户端请求,造成阻塞。渐进式rehash将rehash操作分摊到多次操作中,避免了这种长时间的阻塞。
- 保证服务可用性:在进行哈希表的扩展或收缩时,Redis仍然能够正常处理其他操作,提高了系统的可用性和响应性能。
3. 实际应用场景
- 高并发读写场景:例如在电商秒杀活动期间,大量的商品信息存储在Redis字典中。如果此时需要对字典进行扩展或收缩,采用渐进式rehash可以在不影响高并发读写操作的情况下完成哈希表的调整,保证系统的稳定性和响应速度。
- 数据量动态变化场景:像社交平台,用户活跃度随时间动态变化,其相关数据(如用户在线状态、消息队列等)存储在Redis字典中。数据量可能频繁增减,渐进式rehash能在数据量变化时,平滑地对哈希表进行扩展或收缩,确保系统高效运行。
4. 渐进式rehash过程中数据读写处理
- 读操作:在渐进式rehash过程中,查找一个键时,会先在新哈希表中查找,如果没找到,再到旧哈希表中查找。这样可以保证无论键值对是否已经迁移到新哈希表,都能正确查找到。
- 写操作(插入、删除、更新):在进行插入、删除、更新操作时,首先会将操作应用到新哈希表中。如果在旧哈希表中存在对应的键值对,还需要将其从旧哈希表中删除(插入操作不需要考虑旧哈希表情况)。这样可以保证新哈希表的数据是最新的,并且随着操作的进行,旧哈希表中的键值对逐渐减少,最终完成rehash。