面试题答案
一键面试Redis渐进式rehash内存分配与管理
- 数据结构调整:Redis使用两个哈希表(ht[0]和ht[1])来实现渐进式rehash。开始时,所有数据都在ht[0]中。当需要进行rehash(如哈希表元素数量达到负载因子阈值)时,会分配ht[1],其大小通常是ht[0]的两倍或其他合适的扩展倍数。
- 逐步迁移:在渐进式rehash过程中,不是一次性将ht[0]中的所有数据迁移到ht[1],而是每次处理客户端请求时,从ht[0]中迁移一小部分数据到ht[1]。具体来说,会在每次执行命令时,顺带将ht[0]中索引为rehashidx的桶及其关联的键值对迁移到ht[1],然后将rehashidx加1。这样,随着时间推移,ht[0]中的数据逐渐迁移到ht[1]。在迁移过程中,对于查找操作,如果在ht[0]中未找到,还会去ht[1]中查找;写入操作则直接写入ht[1]。当ht[0]中的数据全部迁移完毕,ht[0]会被释放,ht[1]成为新的ht[0],下次rehash时再重新分配ht[1]。
好处
- 避免性能峰值:如果一次性进行rehash,在数据量较大时,会消耗大量CPU时间,导致Redis在这段时间内响应变慢甚至无响应。渐进式rehash将rehash操作分摊到多次请求处理中,避免了因集中式rehash造成的性能峰值,保证了Redis在rehash过程中仍能正常提供服务,对客户端请求的响应时间影响较小。
- 合理利用内存:在渐进式rehash过程中,虽然在一段时间内会存在两个哈希表占用内存,但由于是逐步迁移,并非瞬间将所有数据复制到新的哈希表,所以不会在短时间内造成内存的急剧增加。并且当迁移完成后,旧的哈希表(ht[0])会被释放,保证了内存的合理使用,避免了因一次性分配新哈希表空间而可能导致的内存不足问题。