分布式负载均衡算法——一致性Hash、Hash槽

1、总述

分布式负载均衡算法的主要目的就是为了缓解集群服务器的压力,让客户端的请求尽可能均匀分散在各个服务器节点中。下面主要分析一致性Hash和Hash槽两种算法。

参考链接:
https://blog.csdn.net/majunzhu/article/details/100173943
https://blog.csdn.net/Saintyyu/article/details/100056329

2、普通Hash

这里我们先考虑这种普通hash的实现方式,考虑有2个服务器节点,有6个数据(0~5),那自然想到的是采取这种hash函数:num%k(k为服务器数) 来均匀分散这6个数据到服务器上。

  • 节点0——0,2,4
  • 节点1——3,5

但是如果数据量增加了,造成服务器节点不够用了,假设这里加入增加2个数变为(0…7),并增加一个节点。这时数据分布变为:

  • 节点0——0,3,6
  • 节点1——1,4,7
  • 节点2——2,5

从上面就可以看出新增节点或删除节点都会极大地影响原来的数据分布形式,会造成大量的数据迁移。

3、一致性Hash

为了解决上述问题,即如何保证在删除或新增节点的情况下尽可能小的影响原有节点的数据分布,从而减少数据迁移的大小,防止集群雪崩的发生。于是才有了一致性hash算法,其一致性在于尽可能让原来的节点数据保持一致性不变,而不是分布式集群的数据一致性。

一致性hash是一个0-232的闭合圆,(拥有232个桶空间,每个桶里面可以存储很多数据,可以理解为s3的存储桶)所有节点存储的数据都是不一样的。计算一致性哈希是采用的是如下步骤:

  • 对节点进行hash,通常使用其节点的ip或者是具有唯一标示的数据进行hash(ip),将其值分布在这个闭合圆上。
  • 将存储的key进行hash(key),然后将其值要分布在这个闭合圆上。
  • 从hash(key)在圆上映射的位置开始顺时针方向找到的一个节点即为存储key的节点。如果到圆上的0处都未找到节点,那么0位置后的顺时针方向的第一个节点就是key的存储节点。

如图:
在这里插入图片描述
从上面可以看到新增节点,只会影响其下一个节点的数据,并不会影响其他节点的数据,所以这极大地提高了集群的数据迁移性能,具有较好的容错性和可扩展性。

【虚拟节点的必要性】
但是我们还得考虑一个问题,就是热点数据所在的节点崩溃时候,可能仍然会造成集群雪崩的发生:以上图为基准,删除了node2节点后,原本在node2节点上的数据就会被重新定位node4上。这样就产生一个影响:原来node2的数据转移到node4上,这样node4的内存使用率会骤增,如果node2上存在热点数据,node4会扛不住甚至会可能挂掉,挂掉之后数据又转移给node3,如此循环会造成所有节点崩溃,也就是前面所说的雪崩的情况。
在这里插入图片描述
为了解决雪崩现象和数据倾斜现象,提出了虚拟节点这个概念。就是将真实节点计算多个哈希形成多个虚拟节点并放置到哈希环上,定位算法不变,只是多了一步虚拟节点到真实节点映射的过程

以雪崩现象来说明:如下图节点real1节点又俩个虚拟节点v100和v101,real2有俩个虚拟节点v200和v201,real3节点有v300和v301俩个虚拟节点。

在这里插入图片描述
这样就算Real1崩溃了,其虚拟节点所管理的数据会被迁移到多个其他真实节点对应的虚拟节点上去,这样就解决了雪崩和数据倾斜的问题了。

4、Hash槽

redis cluster采用数据分片的哈希槽来进行数据存储和数据的读取。redis cluster一共有214(16384)个槽,所有的master节点都会有一个槽区比如0~1000,槽数是可以迁移的。master节点的slave节点不分配槽,只拥有读权限。但是注意在代码中redis cluster执行读写操作的都是master节点,并不是你想 的读是从节点,写是主节点。第一次新建redis cluster时,16384个槽是被master节点均匀分布的。
在这里插入图片描述
其实在某种程度上来讲,hash槽和一致性hash实际上是差不多的,我们将一致性hash环展开,不正是hash槽的模式吗,所以其基本原理类似,只是有如下区别。

和一致性哈希相比,它并不是闭合的,key的定位规则是根据CRC-16(key)%16384的值来判断属于哪个槽区,从而判断该key属于哪个节点,而一致性哈希是根据hash(key)的值来顺时针找第一个hash(ip)的节点,从而确定key存储在哪个节点。

  • 一致性哈希是创建虚拟节点来实现节点宕机后的数据转移并保证数据的安全性和集群的可用性的。
  • redis cluster是采用master节点有多个slave节点机制来保证数据的完整性的,master节点写入数据,slave节点同步数据。当master节点挂机后,slave节点会通过选举机制选(raft协议)举出一个节点变成master节点,实现高可用。

【优点】

当发生扩容时候,我们只需要定义映射表关系即可,随意改变slot的映射关系,重要的事情再说一遍,映射表才是哈希槽的精髓,可以按需求随意组合,以下举个例子:

0<=slot< 900 映射到server1上,

1000<=slot<4000映射到server2上,

5000<=slot<2^14 会映射到server3上,

900<=slot<1000 会映射到server4上,

4000<=slot<5000 会映射到server4上,

所以相对于一致性hash而言其优点在于,哈希槽采用灵活的可配置映射表,可以随意组织映射到新增server上面的slot数,比一致性hash的算法更灵活方便;同时也给开发人员手工配置更大的简洁性。

发布了69 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/JustKian/article/details/104237245