首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一致性哈希这么完美?为何TiDB/Ceph/Redis/GPFS 集体弃用

一致性哈希这么完美?为何TiDB/Ceph/Redis/GPFS 集体弃用

作者头像
早起的鸟儿有虫吃
发布2025-10-10 13:09:24
发布2025-10-10 13:09:24
1100
代码可运行
举报
运行总次数:0
代码可运行

C++ 周刊(C++ Weekly)第9期开始了

周刊目标:

不是要让你成为 C++ 专家

而是让你成为 C++ 面试专家

本期主题:

数据均衡拆分--hash函数

小思考(导读):

大家都知道,普通的哈希函数有个致命缺点:

节点数一变,几乎所有数据都要迁移,

一致性希函解决了这个问题

你可能不知道

为什么分布式数据库 TiDB不用一致性哈希

为什么内存数据库 Redis不用一致性哈希

为什么文件系统Ceph,也不用一致性哈希

这一期从,

数据查询

数据副本

数据规模

自动化运维角度

帮你彻底搞懂这些面试高频问题背后逻辑

一、用户故事

1.1 客户反馈

用户请求量暴增,订单积压,响应很慢,请立刻解决!”

1.2 小青(青铜,工作 0-5 年)

我来!我充满热情,积极响应!

解决办法如下:

1. 垂直扩展(Vertical Scaling)

内存吃满 → 升级:32GB 不够?直接加到 128GB

CPU 打满 → 升级:核心不够?上更高规格 CPU

线程不足 → 升级:3 个线程不够?直接开到 10 个、20 个

> 画外音:操作系统提供可插拔接口 提供这能保证

2. 水平扩展(Horizontal Scaling)

水平扩缩容指通过调整服务节点的数量来实现服务能力的扩缩容

单台服务器顶不住?→ 10 台不够,再加 20 台!

画外音 系统架构提前设计了可扩展性

Nginx:Master + worker 模型

支持Raft 协议的Tidb集群

1.3 领导:不满意

单线程改多线程,看似提升了并发,但负载均衡考虑了吗?

初次之外 你考虑什么因素 ,不均衡怎么办?

不会上来什么都没考虑吧,上来直接使用程咬金三板斧

二、TiDB为什么不用一致性hash

你有没有想过,传说中的一致性哈希,

为什么像Ceph、TiDB这样的存储系统不怎么用?

2.1. 一致性哈希的局限性

一致性哈希最早确实很火。

它把每台机器映射到哈希环上,

新增或删除节点时,数据迁移量很小。

问题也很明显:

① 不支持拓扑感知

一致性哈希只知道节点编号,不知道物理位置。

就像你搬家,房东只给钥匙,不告诉你新房在哪栋楼。

结果可能三个副本全落在同一机架。

一旦机房出问题,数据直接掉线

② 只支持 key→节点 单个查询, 不支持范围查询

2.2 TiDB 副本调度

TiDB 集群由 PD + TiKV + TiDB Server 构成。

策略范围分片(Range-based Sharding)

数据按 Key Range 划分成 Region(默认 96MB 左右)。

每个 Region 有多个副本,通过 Raft 保证一致性。

PD(Placement Driver)负责 Region 调度和均衡。

特点

1

支持范围查询(Range Scan):连续 Key 可以在一个 Region 内完成查询。

2

动态均衡:Region 热点会拆分(Split),PD 自动迁移副本。

3

副本管理原生:Raft 保证多副本一致性。

为什么不使用一致性哈希

- 一致性哈希天然只适合 单 Key 映射节点不支持顺序范围查询

- 一致性哈希本身没有多副本拓扑感知逻辑,需要额外设计。

Region 副本调度举例:

假设 TiDB 集群有 6 个 TiKV 节点:

代码语言:javascript
代码运行次数:0
运行
复制

数据中心 DC1

 ├─机架 R1: Node1, Node2

 └─机架 R2: Node3



数据中心 DC2

 ├─机架 R3: Node4, Node5

 └─机架 R4: Node6

Region 默认 3 副本

PD 会自动选择不同机架节点,例如:

Region 副本:Node1(R1)、Node3(R2)、Node4(R3)

优势

即使某个机架宕机,Region 副本仍可在其他机架继续提供服务。

支持自定义拓扑策略(跨机房、副本数可调)。

举例说明:范围查询

2.3 CRUSH(Ceph)是如何解决的

CRUSH 全称:Controlled Replication Under Scalable Hashing

2.1 关键设计

1

层级拓扑感知

CRUSH Map 里有 节点层级:数据中心 → 机房 → 机架 → 服务器 → OSD

可以定义规则,副本要分布在不同机架或机房,保证故障域隔离。

举例说明

假设 Ceph 集群有:

代码语言:javascript
代码运行次数:0
运行
复制

数据中心A

├─机架1: OSD 1,2

└─机架2: OSD 3,4

数据中心B

└─机架3: OSD 5,6

CRUSH 规则:每个对象 3 副本,要求 不同机架

对象 obj123 → PG → CRUSH 计算

CRUSH 输出三个 OSD: OSD2, OSD4, OSD5(分别在不同机架)

特点

保证多副本分布均衡

考虑拓扑结构避免单点故障

自动均衡,无需中心调度器全局维护

三 、Redis集群为什么不用一致性哈希

你知道吗?

做分布式存储,最重要的一件事就是——拆得均匀!

如果拆不均匀,负载就可能集中在几台机器上,成为瓶颈

拆分均匀需要什么条件,代价是什么,如果不均衡怎办?

Redis Cluster 有一套“老派”的做法:固定槽 + 手工调整

(1 )所有 Key 映射到 16384 个槽

代码语言:javascript
代码运行次数:0
运行
复制

slot = CRC16(key) % 16384

(2)然后把槽分配到节点,比如有 3 个主节点:

节点A:0-5460

节点B:5461-10922

节点C:10923-16383

槽分布不均怎么办?

只能手工调整槽范围,重新分配槽。

为了高可用,Redis 提供 主从复制

每个主节点挂多个从节点

主节点挂了,从节点自动顶上

生产环境通常用:

3主3从(6节点)10主10从(20节点)

Redis 集群最多支持 1000 个主节点(官方建议 ≤400)

扩容成本高,但对中小规模系统够用了

DynamoDB 的思路完全不同:

自适应一致性哈希 + 虚拟节点 + 多副本

1️⃣ 哈希环

所有 Key 映射到一个 超大哈希环[0, 2^128-1]

哈希函数保证 Key 随机分布,负载天然均衡

理论上支持 千到万节点,没有上限

2️⃣ 虚拟节点

每台机器分配几百个虚拟节点

新增节点 → 只接管一小部分虚拟节点

上万节点 → 一样平滑扩容

好处

拆分天然更均衡

哈希函数保证 Key 随机分布,负载天然均衡

超大哈希环, 2128-1 reids 216]

新增节点 → 只接管一小部分虚拟节点

上万节点 → 一样平滑扩容

DynamoDB 默认 3 副本,且跨可用区

写入时,顺时针找 连续 3 个虚拟节点 放在不同物理节点:

单节点挂了 → 数据可用

整个机房挂了 → 还有副本顶上

小系统用 Redis,足够用了。

大系统靠 DynamoDB。

产品愿景

DynamoDB 的核心目标是三件事:

① 无限扩展(Scalability)

理论上支持 上万节点,没有上限

一致性哈希 + 虚拟节点 → 自动均衡

一句话:用户量翻 100 倍,系统不需要重构。

② 高可用 & 容灾(High Availability & Fault Tolerance)

3 副本默认配置,且 跨可用区存储

写入数据 → 顺时针找 连续 3 个虚拟节点

单节点挂了 → 副本自动接管

整个机房挂了 → 还能继续对外服务

一句话:节点会挂、机房会挂,但数据不会丢。

③ 自动化运维(Autonomous Management)

DynamoDB 自己做 负载均衡

自己做 数据迁移

自己做 副本重建

节点故障靠 心跳包检测,发现异常立即重路由

运维几乎“零人工”

一句话:你不需要雇一队 DBA。

四. 为什么文件系统为什不用一致性函数

课程编号:15-445 / 645(本科生/研究生)

课程名:Database Systems

学校:Carnegie Mellon University(CMU)

主讲:Andy Pavlo(数据库内核大神,Peloton & NoisePage 项目负责人)

课程主页

https://15445.courses.cs.cmu.edu/fall2024/

PostgreSQL 的哈希索引早期是可扩展哈希,支持桶分裂和目录扩展

现代 PostgreSQL 中,默认索引用 B+Tree,但可扩展哈希仍然是重要的存储组件

英文原文

Extendible hashing is a type of hash system which treats a hash as a bit string and uses a trie for bucket lookup.

Because of the hierarchical nature of the system, re-hashing is an incremental operation (done one bucket at a time, as needed).

This means that time-sensitive applications are less affected by table growth than by standard full-table rehashes.

Extendible hashing was described by Ronald Fagin in 1979. Practically all modern filesystems use either extendible hashing or B-trees. In particular, the Global File System, ZFS, and the SpadFS filesystem use extendible hashing.

中文翻译

可扩展哈希(Extendible Hashing)是一种哈希系统,它将哈希值视为比特串,并使用 Trie 树 来进行桶(bucket)查找。

由于该系统具有分层结构的特点,重新哈希(re-hashing)是一个增量操作(按需一次处理一个桶)。这意味着,对于对时间敏感的应用,表增长对性能的影响比标准的全表重哈希要小得多。

可扩展哈希由 Ronald Fagin 在 1979 年提出。几乎所有现代文件系统都使用 可扩展哈希B 树。特别地,Global File System、ZFS 和 SpadFS 文件系统都使用了可扩展哈希

. 支持动态扩展

文件系统的目录或元数据大小是动态变化的,不可预知。

可扩展哈希是一种 增量扩展 的哈希结构:

可扩展哈希相比 B 树或者其他平衡树

虽然 B 树也能处理动态扩展,但对于哈希索引的 快速随机访问,可扩展哈希更直接。

这种特性对 大规模文件系统 特别重要,尤其是数百万甚至数亿个文件的目录

生活类比:邮筒分配信件

想象你是一个邮局管理员,需要把信件按收件人邮编放到邮筒里:

1

一开始只有 2 个邮筒

邮筒 0:放邮编以 0 开头的信

邮筒 1:放邮编以 1 开头的信

1

每个邮筒最多放 2 封信(容量限制)。

插入信件(类似插入 key)

插入 4 封信,刚好分配到 2 个邮筒里,不超过容量。

插入第 5 封信时,目标邮筒已满 → 需要拆分邮筒

拆成两个小邮筒,每个只看邮编的前 2 位

这样就能容纳更多信件

插入第 6 封信,如果邮筒再次满了,又继续拆分

全局深度类似“你需要看邮编几位数来决定放哪个邮筒”,随着拆分增加。

核心思想总结

1

增量扩展:只拆分满的桶(邮筒),不重建整个表

2

层次结构:桶号由哈希值的前几位决定(类似逐层看邮编)

3

高效查找:找某个 key,只需要根据哈希前几位找到对应桶

总结

如果遇到 数据不均衡 的情况,有两种思路:

① 在数据拆分时就考虑均衡

为什么要等到不均衡了再调整?

不过,这往往涉及 复杂的数学公式和概率模型。 作为开发人员,我们很难自己设计出来, 只能借助 别人已经发明的概念和算法

② 允许数据先不均衡,事后再调整

这种方式会结合 分片的物理位置、副本情况 等因素, 通过 重新分片迁移副本 等手段, 实现 更灵活、低成本的动态扩展

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端开发成长指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、用户故事
    • 1.1 客户反馈
    • 1.2 小青(青铜,工作 0-5 年)
    • 1.3 领导:不满意
  • 二、TiDB为什么不用一致性hash
    • 2.1. 一致性哈希的局限性
    • 2.2 TiDB 副本调度
    • 2.3 CRUSH(Ceph)是如何解决的
      • 2.1 关键设计
      • 举例说明
  • 三 、Redis集群为什么不用一致性哈希
    • ① 无限扩展(Scalability)
    • ② 高可用 & 容灾(High Availability & Fault Tolerance)
    • ③ 自动化运维(Autonomous Management)
  • 四. 为什么文件系统为什不用一致性函数
    • . 支持动态扩展
    • 生活类比:邮筒分配信件
    • 插入信件(类似插入 key)
    • 核心思想总结
  • 总结
    • ① 在数据拆分时就考虑均衡
    • ② 允许数据先不均衡,事后再调整
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档