当前位置: 首页 > 原理解释

一致性hash算法原理-一致性hash算法原理

数据库做 CDN,写请求过来。
要是直接照着一般思路去记“先算 hash,再查特定桶”,那挺好办写出来像是背答案的。咱们就不搞那些教科书式的条条框框,直接聊聊这玩意儿到底在干嘛,还有它到底是如何把数据分散开的。 实际上核心就一句话:把一份数据装进哈希表,然后给每个数据块加个固定的偏移量,最终根据结局重新计算一个值,看看它落在哪一组桶里。
这听起来有点绕,但这实际上是解决“数据一致性”最底层逻辑的变体。 想象一下,你有 100 个文件要存到 CDN 上。
要是直接用 Hash 写,那得把所有文件先排好序,再一个个加偏移量,最终算出值。
这操作量忒大了,对于大规模的数据量根本行不通。便就有了 Consistent Hashing 这个概念,它不关心文件原本是啥顺序,只关心文件本身的身份标识。 如何体现文件身份?咱们就假设文件被切成了几份数据块,每一份都配一个随机种子。
这个种子就像个独一无二的密码,用来证明这是同一份文件的专属副本。
比方说,文件 A 有三个副本,分别用了 101、102、103 做种子;文件 B 用了 201、202、203。就如此好办,不用管文件原本长啥样,也没管它们顺序排在哪,只要种子对得上,就认定是同一份文件。 有了种子,你就有了一个个“桶”。每个桶对应一个哈希值。计算哈希值的过程实际上挺好办,就是把种子拼起来,再做个整数运算,最终拿到结局。
比如种子是 101,算出来的哈希值就是 101。
这个哈希值作为桶的 ID 去查表,要是表里存了该种子对应的桶,那就说明文件在桶里。 这就有个关键难题:当新的文件进来时,它也需求一个种子,然后重新算哈希值,找到对应的那个桶。
要是那个桶里已经存了旧文件,新文件就得被往旧文件的位置挪那会儿,直到找到空位。
这个挪动的过程,就实现了数据的一致性。 为了弄懂这个算法,咱们得看看它到底如何工作。假设我们有两个文件,分别是 A 和 B,目前要把它们同步到同一个 CDN 服务上。 起初,把 A 的数据块分成三份,种子分别是 1,2,3。算出对应的哈希值,我们拿到三个桶:桶 1、桶 2、桶 3。 接着,把 B 的数据块分成三份,种子分别是 4,5,6。算出对应的哈希值,拿到桶 4、桶 5、桶 6。 这时候,我们构建一个哈希表,把桶和桶里的种子对应起来。
比如表里写:桶 1 对应种子 1,桶 2 对应种子 2,以此类推。 新文件 C 来了。我们给它算个种子,比如是 7。算出 C 的哈希值,发现是桶 7。目前的难题是,桶 7 里有没有东西?要是存了,那 C 就得去那个桶找旧数据挪钱。 可是,这里有个细节,种子是动态生成的。
每次有新文件进来,要么文件被修改了,种子都会变。
这意味着桶的位置也会变。
要是 C 的哈希值算出来是桶 10,而桶 10 里目前存的是文件 A,那我们就得把 A 从桶 10 拿出来,放到 C 所在的桶 10 里。 这就引出了一个经典场景:坏节点。假设 CDN 上有一群节点,B 节点的哈希表里写的是“桶 2 对应种子 2",可是实际物理位置可能已经变了。当新文件 D 进来,它的哈希值算出来也是桶 2,这时候算法会去 B 节点找旧文件 D,把 D 挪那会儿。
可是 D 所在的物理节点可能已经被删掉了。
这时候,B 节点就找不到旧数据了。 这就是为啥单纯用索引去同步数据会有风险。出于哈希表只是描述了逻辑关系,它没有记录物理位置。
要是节点挂了,要么数据被删除了,哈希表的位置就会错位,害得新的数据找不到旧数据。Consistent Hashing 的核心目标,就是要在物理位置形成变化时,尽量让逻辑上的数据块位置不形成忒大的偏移。 故此,一般的做法是维护一个整个的、包含所有节点和所有数据的整个哈希表。当节点加入或离开时,我们计算新的种子,重新计算新的哈希值,把数据块从旧表迁移到新表,就连直接在旧节点上保留一份副本。 咱们再来换个角度,假设我们有 1000 个文件,每个文件都有 3 个副本。我们排列顺序后,把种子设为 0, 1, 2... 999。
然后计算哈希值,把文件放到对应的桶里。 要是有 10000 个请求发到 CDN,每个请求都会触发一次新的计算。对于大多数情况,请求的哈希值落在同一个桶里,那就不需求移动数据,直接读取就行。
只有当两个请求的哈希值落在同一个桶时,算法才会去查桶里的种子,确认是不是同一份文件。
要是是,就读取原始数据。 这就避免了频繁的“移动数据”操作。想象一下,你是仓库管理员。仓库里有大量箱子,每个箱子都有编号。你收到一个新箱子,你算出它的编号,发现它和另一个箱子在同一格子里。
这时候你不需求搬箱子,直接拿那个已经存有的箱子就好。
这样你就不用一直搬运货物,效率就高了。 在 Consistent Hashing 里,这个“同一格子里”就是桶。
那个“没有搬箱子”就是数据一致性。通过维护一个整个且稳定的桶表,就算节点在物理空间上移动了,只要逻辑上对应的种子没变,数据块就不会乱动。 最终总结一下,Consistent Hashing 本质上是一个动态的映射算法。它不关心数据原本的物理顺序,只关心每个数据块的唯一标识(种子)。通过计算哈希值,把数据块映射到特定的桶(桶的位置),形成了一个动态的映射表。当新数据进来时,通过重新计算哈希值找到桶,要是桶里有旧数据,就挪那会儿;要是没有,就放新数据。
关键在于,通过维护一个包含所有节点当前状态的整个映射表,来保证物理位置变化时,逻辑位置尽可能保持不变。
这样就能在数据同步过程中,最大限度地削减不必要的移动操作,确保数据的一致性。
相关标签:

猜你喜欢

热门阅读

  • 赖柴尔定理-赖柴尔定理
  • 迪拜哪个国家的城市?-迪拜在哪国城市
  • 李毅吧番号及出处-李毅吧番号及出处
  • 贴春联的由来简介50字-春联由来简述
  • 思乡的名言和出处-思乡名言及出处

其他分站