consistent-hashing

一致性哈希:一套扛得住增减机器的分工规则

它是干嘛的。 凡是把数据按 key 摊到多台机器上存的系统——分布式缓存、分片数据库、分布式存储——都需要一条规则,只看 key 就能回答:它在哪台? 无状态的计算层永远用不上它;它只活在状态被分片的那一层。

要紧的性质不是圈。 是增减成员时的局部性:一台机器加入或离开时,只有它附近的 key 改归属,留下来的机器之间的 key 绝不互相挪窝。加一台机器,应该只搬走约 1/N 的 key,不能更多。

朴素规则恰死在这里。 用 hash(key) % N 分配:公式里含着机器数,加一台,几乎每个 key 的答案都变。值还躺在老机器上,但读的人被新公式指去了别处——对应用而言,这是一次全量缓存失效、或一次全网数据搬家,由"扩容"这个动作亲手触发。

圈是买到这条性质的一种构造。 把哈希的输出范围(假定 0..99,真实是 0..2^32)首尾接上——做成圈只是为了让最后一段绕回第一段、不留无主的尾巴,全图一条规则走到底。每台服务器把自己的身份哈希到圈上:一个标记、一个坐标。这些数字是坐标不是算子,永远不拿它们除任何东西。 key 哈希到一个点,顺时针走,碰到的第一个标记就是它的主人;每个标记身后那一段就是那台机器的辖区。写入时用这条规则决定值放哪,读取时用同一条规则找回。加一台机器就是插一个标记:它只接管前头那一段,只有那一段的 key(≈1/N)搬家。撤一台,它那一段顺手交给下一个标记。

平衡要靠虚拟节点。 每台机器只撒一个随机点,圈会被切得七歪八斜,60/25/15 的切法很常见。所以每台物理机撒 100–200 个点(名字加序号逐个哈希)。它的辖区变成许多小随机段的总和,而许多随机长度加起来必然收敛(大数定律):切分落在几个百分点之内。白捡的好处:大机器可以多撒点、按比例多扛;一台死了,它撒在各处的小段落到许多个不同邻居头上,而不是整段砸垮顺时针的下一家。

亲戚和替代品,性质相同。 Redis Cluster 把自由的圈换成 16384 个固定槽位(key 哈希进槽,槽分配给机器;扩容挪槽不挪 key)。Rendezvous hashing 连圈都不要:拿 hash(key, 每台机器名)逐个打分,最高分赢——新机器只能抢走它自己赢的 key,老归属纹丝不动。性质是魂,圈只是皮。

实操中极少自己实现。 它沉在组件里:Cassandra 的分区器就是这张环(虚拟节点叫 token),memcached 客户端内置(ketama),Envoy、HAProxy 提供它作为面向有状态后端的负载均衡模式。原生 Postgres 根本没有分片——那边的分布式答案是加一层(Citus:固定分片数 + 再平衡器,加机器时搬分片)。从业者真正要拍板的决策是选哪个组件、尤其是拿哪一列当分片键——算法是 settled 的,分片键选错才真贵。

über diesen eintrag

Einer von sijie's Wiki-Einträgen. Die KI auf dieser Site ist im selben Corpus verankert und antwortet in sijie's Stimme mit Zitaten zurück auf Einträge wie diesen — das Beantworten kostet sijie Geld, daher wartet sie hinter einem Code: zugriffscode eingeben →