惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News | PayPal Newsroom
S
Security Affairs
T
Tor Project blog
P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Security @ Cisco Blogs
H
Heimdal Security Blog
Hacker News: Ask HN
Hacker News: Ask HN
Help Net Security
Help Net Security
U
Unit 42
云风的 BLOG
云风的 BLOG
The Hacker News
The Hacker News
Cisco Talos Blog
Cisco Talos Blog
量子位
F
Full Disclosure
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
有赞技术团队
有赞技术团队
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Forbes - Security
Forbes - Security
人人都是产品经理
人人都是产品经理
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Security Blog
Microsoft Security Blog
博客园 - Franky
腾讯CDC
AI
AI
Last Week in AI
Last Week in AI
Latest news
Latest news
Google Online Security Blog
Google Online Security Blog
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
IT之家
IT之家
Martin Fowler
Martin Fowler
Blog — PlanetScale
Blog — PlanetScale
V2EX - 技术
V2EX - 技术
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - 叫我安不理

C#如何优雅处理引用类型的深拷贝 老马失前蹄,竟然在数据库外键上翻车了,重温外键级联 字符编码知多少(二) 字符编码知多少(一) 给自己看的mongoDB快速入门 为什么OAuth2与SSO经常混为一谈? 浅谈为什么我讨厌分布式事务 为什么说方法的参数最好不要超过4个? C#代码如何影响CPU缓存速度? 浅谈.NET微服务架构的演变 C#网络编程(六)----Socket编程模型 C#网络编程(五)----细嗦TCP粘包 C#网络编程(四)----HttpClient C#网络编程(三)----HTTP协议 C#网络编程(二)----网络层/链路层 C#网络编程(一)----应用层/传输层 重生之我是操作系统(十)----I/O管理 重生之我是操作系统(九)----文件管理(下) 重生之我是操作系统(八)----文件管理(上) 重生之我是操作系统(七)----内存管理(下)
优雅求模,一致性哈希算法
叫我安不理 · 2025-08-27 · via 博客园 - 叫我安不理

传统哈希局限性

求模,也就是 key % 节点数 N, 当节点数量变化时(如服务器扩容 / 下线),几乎所有数据的映射关系都会失效,导致大量数据需要重新迁移,引发 “哈希雪崩”。

image

key的hash值 节点数 求模
10 3 10 % 3 = 1
11 3 11 % 3 = 2
12 3 12 % 3 = 0
10 4 10 % 4 = 2
11 4 11 % 4 = 3
12 4 12 % 4 = 0

此时可以看到之前分配到1,2,0节点的key,需要被重新移动到2,3,0。也就是75%的数据需要移动。
如果这个总数是20亿呢?这会是一场灾难

关于哈希可以参考此文 https://www.cnblogs.com/lmy5215006/p/18748028

理论支撑:一致性哈希

那如何解决这个问题呢?
正所谓头痛医头,脚痛医脚。既然是因为分母发生变化导致,那我想个办法让分母不变不就解决这个问题了?
聪明的小伙伴已经想到了,把分母设为int最大值2³²-1即可。
这时候新的问题又来了,2³²-1=4294967295 这么大的一个分母(节点数),任何数求模余数都是他自己,这就失去了求模的意义,求模的本质是为了对hash瘦身,你倒好又绕回来了,因此这条路走不通,但也提供了灵感。

哈希环(hash ring)

因此,在1997年,consistent hash算法被提出,它结合了环形数组与上述的灵感。将hash算法的输出范围抽象成一个圆环,并hash值限定为0-2³²-1。

image

节点映射到哈希环

把每一个节点(Node)算出一个hash值,放在hash ring对应的位置上

假设有3个节点
image

数据映射到哈希环

将要存储的数据(key)也通过相同的算法计算出hash值,放在hash ring对应的位置上

假设有1000个key,数据映射到环后,顺时针方向寻找第一个遇到的节点,该节点就是存储key的节点
image

节点动态增删

当要动态增删节点时,一致性hash只会影响hash ring上相邻节点的部份数据,而不是迁移所有数据,这极大减少了数据迁移量
image
image

删除结节也同理,就是一个在hash ring上此消彼长的过程。

进一步优化:虚拟节点

image
让我们再回到此图,在最初的3个节点中,我们会发现一丝丝不和谐的因素,蓝色节点中keys的数量为103,绿色节点keys的数量为572,红色节点的keys数量为325,他们之间的分配并不均衡。

当节点较少时,keys可能集中分布在某一个特定节点,导致旱的旱死,涝的涝死,这便是数据倾斜
那如何优化呢?在计算机中,没有什么是不能通过增加一层中间层能解决的。

为每个物理节点创建多个"虚拟节点",由虚拟节点代替物理节点,映射到hash ring上

image

具体落地:Hash Slot

有了理论支撑,在具体落地的过程中,发生了细微变化。但核心目标依旧不变:当节点变化时,数据最小化迁移

Consistend Hash Hash Slot
空间初始化 构建 0~2³²-1 的hash ring。 划分固定数量的Hash Slot,比如Redis的16384个槽。
数据映射 通过hash(key)映射到ring上的某个点,顺时针找到最近节点 通过hash(key)得到hash,再通过hash%槽总数得到槽编号,最后通过槽编号与节点的映射关系得到所属节点。
节点映射 计算节点的hash值,比如(IP+端口),直接映射到环上 节点不直接映射,而是通过维护与槽位的映射关系,如节点 A 负责槽 0~5460,节点 B 负责槽 5461~10922

Hash Slot解决了什么痛点?

Consisten hash痛点 Hash Slot方案
数据倾斜 槽的数量足够大,且槽数量在节点之间均匀分配,比如Redis有16384个槽,假设3个节点,每个节点分配5461个槽,因为槽的数量很大,所以天然避免数据倾斜
数据迁移颗粒度大 迁移粒度从 “节点级” 缩小到 “槽级”—— 节点扩容 / 缩容时,仅需迁移 “待分配 / 释放的槽”(而非整个节点的数据)

事实上,Hash Slot与Consistend Hash在思想上没有本质上的差别。你也可以创建16384个虚拟节点来对标Hash Slot,只是工程化难度不同的选择而已