您的位置:首页 > 文旅 > 旅游 > 食品品牌推广方案_建设企业和施工企业_刷链接浏览量网站_怎么自己做网址

食品品牌推广方案_建设企业和施工企业_刷链接浏览量网站_怎么自己做网址

2025/5/19 15:49:18 来源:https://blog.csdn.net/m0_73762612/article/details/147541383  浏览:    关键词:食品品牌推广方案_建设企业和施工企业_刷链接浏览量网站_怎么自己做网址
食品品牌推广方案_建设企业和施工企业_刷链接浏览量网站_怎么自己做网址

引言

对于哈希算法,相信大家一定不会陌生。它经常被用在负载均衡、分库分表等场景中。例如,在进行分库分表时,我们可能初步根据业务分析,确定 128 张表足以满足当前的数据量需求。此时,当需要插入或查询一条记录时,我们会先对分表键(如 buyer_id​)进行哈希运算,然后将运算结果对 128 取模(hash(buyer_id) % 128​)。这样就能得到一个 0 到 127 之间的数字,从而唯一定位到一个分表。

然而,随着业务的扩展,128 张表可能变得捉襟见肘。这时就需要增加分表的数量,比如增加到 129 张。如果仍然采用简单的哈希取模方式(hash(buyer_id) % 129​),问题就来了:取模的基数变了,几乎所有 buyer_id​ 计算出的目标表编号都会发生改变!这意味着几乎所有现存的数据都需要在新的 129 张表之间重新进行分配。这无疑是一项成本极高且极具破坏性的操作。

一致性哈希(Consistent Hashing) 算法正是为了解决这类问题而生的。它是一种在分布式系统中添加或删除节点时,能够有效地、尽可能地减少数据迁移和重新分布成本的算法。

一致性哈希算法原理

一致性哈希的核心思想是将数据和节点都映射到一个概念性的“哈希环”上。

  1. 构造哈希环: 首先,想象一个闭合的环,代表所有可能的哈希输出值。通常这个范围是 (0) 到 (2^{32} - 1)。这个环是整个算法的基础。

  2. 映射节点(表): 接下来,我们将系统中的每个节点(在我们的例子中是 table_0000​ 到 table_0127​ 这 128 张表)映射到哈希环上的一个位置。这通过计算节点标识符(如表名)的哈希值,然后对 (2^{32}) 取模来完成:

    • ​Hash("table_0000") % 2^32​
    • ​Hash("table_0001") % 2^32​
    • ...
    • ​Hash("table_0127") % 2^32​
      这些哈希值决定了每张表在环上的“固定”位置。
  3. 映射数据: 当需要存储数据时(例如,一条带有特定 buyer_id​ 的记录),我们同样对数据的键(buyer_id​)进行哈希运算,并将其映射到环上:

    • ​Hash(buyer_id_12321) % 2^32​
    • ​Hash(buyer_id_34432) % 2^32​
    • ...
    • ​Hash(buyer_id_767676) % 2^32​
      这样,哈希环上就同时分布了节点(表)和数据的位置。
  4. 数据归属确定: 现在,数据的位置和表的位置都在环上确定了。那么,一个特定的数据项应该存储在哪张表中呢?规则很简单:从数据在环上的位置开始,沿着顺时针方向查找,遇到的第一个节点(表),就是负责存储该数据的节点。

由于数据键(buyer_id​)和表名(table_xxxx​)的哈希值是固定的,在节点(表)数量不变的情况下,每次对同一个 buyer_id​ 进行计算,总能顺时针找到相同的目标表。

一致性哈希在节点扩容中的应用

以上就是一致性哈希的基本原理。现在回到开头的问题:如果我们需要增加一张分表(比如 table_0128​),该如何处理?

  1. 映射新节点: 首先,像其他表一样,将新表 table_0128​ 通过哈希函数映射到哈希环上:
    ​Hash("table_0128") % 2^32​
  2. 数据迁移: 新表 table_0128​ 加入后,它会“插入”到环上的某个位置。根据“顺时针查找第一个节点”的规则,原本应该存储在 table_0128​ 顺时针方向下一个节点上的一部分数据,现在其顺时针遇到的第一个节点变成了 table_0128​。因此,只有这部分数据需要从原来的节点迁移到新的 table_0128​ 中。

一致性哈希节点增加示意图

(这里可以想象一张图,显示新节点插入环中,只有其逆时针方向到上一个节点之间的数据需要迁移)

关键优势: 与普通哈希取模在增加节点时几乎需要移动所有数据不同,一致性哈希算法确保了在增加(或删除)节点后,只有受新节点位置直接影响的一小部分数据需要迁移,绝大多数数据的位置保持不变。这极大地降低了系统扩容或缩容时的成本和风险。

一致性哈希算法总结

一致性哈希通过将整个哈希空间视为一个环形结构,并将节点(服务器/表)和数据(键)都映射到这个环上。通过计算哈希值确定位置,然后依据顺时针(或逆时针)查找最近节点的规则来确定数据的归属。

优点:

  1. 最小化数据迁移: 在增加或删除节点时,仅影响环上相邻节点之间的一小部分数据,保持了较好的数据均衡性和稳定性。
  2. 高扩展性: 节点数量变化时,对整体数据结构和绝大多数数据的存储位置没有影响,易于扩展。

缺点:

  1. 哈希倾斜 (Hash Skew): 在节点数量较少,或者节点哈希值在环上分布不均匀时,可能导致某些节点负载远超其他节点,即数据倾斜。
  2. 雪崩效应(级联故障): 如果一个节点失效,其负载会完全转移给顺时针的下一个节点,可能导致该节点过载而失效,引发连锁反应。(引入虚拟节点可以缓解)
  3. 节点频繁变更的开销: 虽然比普通哈希好很多,但如果节点添加或删除非常频繁,仍然会带来不可忽视的数据迁移开销和系统压力。

Hash 倾斜的解决方法

正如缺点中提到的,即使使用一致性哈希,如果节点在环上分布不均,或者某些数据哈希后天然地聚集在一起,仍然可能出现数据倾斜问题——即少数节点承载了大量数据。这会导致节点负载不均,并且在这些“胖”节点发生变更(如宕机或扩容)时,数据迁移量依然较大。

解决方法主要有两种思路:

  1. 增加物理节点数量: 在服务器资源充足的情况下,可以部署更多的物理节点。节点越多,理论上每个节点分担的数据量越少,即使有倾斜,单个节点的压力也可能降低到可接受范围。但这并不能完全解决哈希分布不均的根本问题,且成本较高。

  2. 引入虚拟节点 (Virtual Nodes): 这是更常用且更有效的方法。与其将一个物理节点(如一台服务器或一张表)只映射到环上的一个点,不如将其映射为环上的多个虚拟节点。

    • 例如,一个物理节点 Node A​ 可以映射为 Node A-1​, Node A-2​, ..., Node A-k​ 这些虚拟节点,每个虚拟节点通过不同的哈希计算(比如 hash("Node A-1")​, hash("Node A-2")​)得到在环上的不同位置。
    • 数据映射时,仍然是顺时针查找第一个虚拟节点。
    • 当一个物理节点加入或离开时,它相当于同时加入或移除了它所对应的所有虚拟节点。
    • 好处: 大量的虚拟节点通常能在环上分布得更均匀,即使物理节点数量不多,也能有效打散数据,显著改善数据倾斜问题。同时,当物理节点增删时,负载能更均匀地分散给其他多个物理节点(通过它们各自的虚拟节点),而不是仅仅压垮顺时针的下一个邻居。

通过引入虚拟节点,一致性哈希算法能够更好地应对数据倾斜,进一步提高系统的负载均衡能力和稳定性。


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com