Redis--基础知识点--32--redis底层存储结构

Redis--基础知识点--32--redis底层存储结构 Redis 数据库底层实现中那个存储所有键值对的全局哈希表dict在运行过程中是会动态扩缩容的。1. Redis 哈希表的结构特点Redis 的数据库如db-dict底层使用的是dict 字典结构它内部维护两个哈希表ht[0] 和 ht[1]平时只用 ht[0]。当需要扩容或缩容时会分配一个 ht[1]大小是当前容量的 2 倍或 1/2 左右然后渐进式地将 ht[0] 中的数据迁移到 ht[1]迁移完成后 ht[1] 成为新的 ht[0]旧的释放。2. 触发扩容的条件Redis 会检查负载因子负载因子 哈希表中已有节点数 / 哈希桶的数量size自动扩容当负载因子 ≥ 1且 Redis 没有在执行bgsave/bgrewriteaof即没有在后台持久化时就会触发扩容如果正在持久化负载因子需要达到5才扩容。扩容规则新的哈希表大小为当前键值对数量 × 2并取最近的 2 的幂。比如当前有 3 个键容量为 4扩容后容量为 8。3. 触发缩容的条件当键值对被删除哈希表变得很空时Redis 也会自动缩容以节约内存。自动缩容当负载因子 0.1时会触发缩容。缩容规则新的哈希表大小就是当前键值对的数量然后按 2 的幂取整但不会小于 4除非空表。例如当前 2 个键容量原来是 16缩容后容量为 4。4. 渐进式 rehash不阻塞服务无论是扩容还是缩容都不是一次性把所有键重新哈希因为这样会导致 Redis 阻塞几秒甚至更久。Redis 采用了渐进式 rehash在 rehash 期间每次对哈希表的增删改查操作都会顺便把当前操作对应的桶从 ht[0] 迁移到 ht[1]。此外Redis 还会在空闲时间serverCron 定时任务主动迁移一批桶。这样整个迁移过程被分摊到多次请求中每个请求只增加微小开销客户端无感知。5. 手动控制可选你也可以通过命令强制触发或调整 rehash 行为手动触发 rehashCONFIG SET activerehashing yes默认开启临时禁止 rehashCONFIG SET activerehashing no不推荐查看当前的 rehash 进度INFO stats中的total_active_defrag等字段但 rehash 的具体状态需要看DEBUG OBJECT或MEMORY STATS。⚠️ 一个容易混淆的点不要把这个全局字典的动态扩缩容和Redis 集群Cluster的节点扩缩容搞混全局字典单个 Redis 实例内部的哈希表自动 resize默认就开启。Cluster 节点是集群层面的节点增删需要手动执行 resharding。你问的是前者Redis 内部确实是会动态扩缩容的且这是其内存管理的重要特性之一。如果你还想了解 rehash 期间如何同时访问两个哈希表、或者如何观测当前字典的扩容/缩容状态我可以继续展开说明。