一致性哈希

news/发布时间2024/5/4 15:42:21

一致性哈希

   一、什么是一致性哈希
    一致性哈希是一种用于分布式系统中数据分片和负载均衡的算法。它的核心思想是将数据和节点通过哈希函数映射到一个固定范围的环形空间中,每个节点在环上占据一个位置,而数据则根据哈希函数计算出的值映射到环上的某个位置上。目前主要应用于分布式缓存当中。

    可以有效地解决分布式存储结构下动态增加和删除节点所带来的问题。

   二、普通哈希的问题

    1.  负载均衡

    分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是集群管理最基本的功能。如果采用常用的hash(object)%N 取模的方式,在节点进行添加或者删除后,需要重新进行迁移改变映射关系,否则可能导致原有的数据无法找到。

    比如:随着业务和流量的增加,假如我们的Redis查询服务节点扩展到了3个,为了将查询请求进行均衡,每次请求都在相同的Redis中,使用hv = hash(key) % 3的方式计算,对每次查询请求都通过hash值计算,得出来0、1 、2的值分别对应服务节点的编号,计算得到的hv的值就去对应的节点处理。

    但是这里有个问题,服务增减是需要对此时的key进行重新计算,比如减少一个服务的时候,此时需要按 hv = hash(key) % 2计算,而增加一个服务节点的时候需要按 hv = hash(key) % 4计算,而这种取模基数的变化会改变大部分原来的映射关系,导致数据查询不到。

    也就是说在对系统做扩容或者缩容时,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题。

    我们应该要重新想一个新的算法,来避免分布式系统在扩容或者缩容时,发生过多的数据迁移。而一致性哈希算法显然是一个更好选择!

    三、一致性哈希算法

    一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题。一致性哈希同样使用了取模的方式,不同的是对 2^32 这个固定的值进行取模运算。

   1. 哈希环

   首先,我们把全量的缓存空间当做一个环形存储结构。环形空间总共分成2^32个缓存区。通过对 2^32 进行取模运算的结果值虚拟成一个圆环,环上的刻度对应一个 0~2^32 - 1 之间的数值。如下图:

         

 

   1) 节点入环

   一致性哈希要进行两步哈希:

   第一步:对存储节点进行哈希计算,也就是对存储节点做哈希映射,比如根据节点的 IP 地址进行哈希;

   第二步:当对数据进行存储或访问时,对数据进行哈希映射;

   所以,一致性哈希是指将「存储节点」和「数据」都映射到一个首尾相连的哈希环上。

   2) 新增节点

   当缓存集群的节点有所增加的时候,普通哈希算法会导致原有哈希映射大面积失效。而一致性哈希整个环形空间的映射仍然会保持顺时针规则,只有一小部分key的归属会受到影响。

3) 删除节点


2. 对「数据」进行哈希映射得到的结果要怎么找到存储该数据的「节点」呢?

映射的结果值往顺时针的方向的找到第一个节点,就是存储该数据的节点。

因此,在一致哈希算法中,如果增加或者移除一个节点,仅影响该节点在哈希环上顺时针相邻的后继节点,其它数据也不会受到影响。


3. 不平衡
我们通过新增节点和删除节点,知道了该方式会影响该节点的顺时针的后一个节点,其他节点不受影响。

但是因为生成哈希值的分布并不是均匀的,如下图新增k4、k5,如果节点B宕机了,k2和k4也迁移到节点C,导致那么大部分请求就落到节点C了,如果数量更多呢,此时会导致节点C压力陡增,这样就不均衡了!


4. 如何通过虚拟节点提高均衡度?

要想解决节点在哈希环上分配不均匀的问题,就是要有大量的节点,节点数越多,哈希环上的节点分布的就越均匀。

但问题是,实际中我们没有那么多节点。为了优化这种节点太少而产生的不均衡情况,一致性哈希算法引入了[虚拟节点]的概念。也就是对一个真实节点做多个副本。

具体做法是,不再将真实节点映射到哈希环上,而是将虚拟节点映射到哈希环上,并将虚拟节点映射到实际节点,所以这里有「两层」映射关系。

比如对每个节点分别设置 3 个虚拟节点:

对节点 A 加上编号来作为虚拟节点:A-01、A-02、A-03
对节点 B 加上编号来作为虚拟节点:B-01、B-02、B-03
对节点 C 加上编号来作为虚拟节点:C-01、C-02、C-03

 

 

五、为什么一致性哈希算法更多地应用在分布式缓存

由于分布式缓存系统的节点部署变化更频繁,而传统关系型数据库的分库分表相对稳定。不过说到mysq1,在水平分库分表的过程中, 仍然可以采用一致性哈希的思想。虽然这样的处理逻辑会复杂一些,却可以避免动态水平扩展时候的问题。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/11343123.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

解决 Edge 关闭后前两次打开都会闪退, 第三次才能正常使用 的问题

前言 为了节省 C 盘的宝贵空间, 我用 mklink 把 C 盘的 edge 文件夹里的 User Data 目录挪出来了, 用了一段时间好像没啥问题, 后边 edge 更新了几次就出现这种闪退的问题了, 搜索了一番后发现了个官方社区的回答, 改下注册表就好 解决方案添加一个注册表项 HKEY_LOCAL_MACHINE…

即时消息技术剖析与实战

1.架构与特性:一个完整的IM系统是怎样的?当服务端有消息需要推送给客户端时,也是将经过业务层处理的消息先递交给接入层,再由接入层通过网络发送到客户端。 此外,在很多基于私有通信协议的IM系统实现中,接入服务还提供协议的编解码工作,编解码实际主要是为了节省网络流量…

实验报告3

项目一 解题思路 1.用char函数定义字符 2.scanf函数输入三个字母 3.用a-32表示对应的大写字母 核心代码 #include <stdio.h>int main(){ char a,b,c;scanf("%c,%c,%c",&a,&b,&c);printf("%c的ASCII值:%d 大写字母:%c\n",a,a,a-32);pri…

CNCKAD数冲激光编程排版软件介绍

CNCKAD是一种集成了CAD和CNC的软件,它可以导入各种图形和CAD文件格式,比如DXF、DWG和IGES,帮助用户创建复杂的3D模型、独特的几何形状和特殊的设计要求。CNCKAD的核心功能是自动化的刀具路径生成,它可以通过多种方式生成刀具路径,包括手动、自动、半自动和机器学习等方法,…

Go 实战|使用 Wails 构建轻量级的桌面应用:仿微信登录界面 Demo

Wails 框架提供了一种简洁而强大的方式,让开发者能够利用 Go 的性能优势和 Web 前端的灵活性,从而能够使用更高效、更轻量级的方法来构建跨平台的桌面应用。本文探讨 Wails 框架的使用,从搭建环境到开发,再到最终的构建打包。概述 本文探讨 Wails 框架的使用,从搭建环境到…