1.分片计算中,hash取余算法的缺点
在使用redis集群时,hash取余(key.hashCode()&Integer.MAX_VALUE%N),存在两个缺点
• 数据倾斜不可避免(只要是散列hash,数据计算结果倾斜必定存在)
• 扩容缩容集群时,数据迁移量过大(重点)
@Test
public void test08(){
int count=0;
for(int i=0;i<10000;i++){
String key=UUID.randomUUID().toString();
int result3=(key.hashCode()&Integer.MAX_VALUE)%3;//当分片数是三的时候
int result4=(key.hashCode()&Integer.MAX_VALUE)%4;//当分片数是四的时候
if(result3==result4){
count++;
}}
System.out.println("比例是:"+count/10000.0);
}
结论:当使用hash取余做分片计算时,节点整体越多,扩容,缩容数据迁移量就越大
2.hash一致性
**2.1介绍**
hash一致性是一种数学模型,对其原理的应用是有区别的,本质数据逻辑一模一样;1997美国麻省理工大学大二学生研究的数学模型,数据计算基石--hash散列;
任意的二进制数据,都可以做hash散列到0-2^32-1正整数区间;这个整数区间叫做--hash环
**2.2hash一致性计算逻辑**
hash一致性在jedis客户端代码中可以实现计算,将所有的节点信息(10.9.100.26:6379),计算hash散列得到0-43亿之间一个整数做映射,
将所有key值(内存对象),也做hash散列计算,映射到整数hash环中某个整数位置
在计算的结果中,寻找key值与节点的对应关系,key值的整数在环上顺时针寻找最近的节点整数,做对应;
上图的key对应的节点结果:
6379: key3,5,6,7
6380:key1,4
6381:key2
2.3扩容和缩容的结果
当有节点加入集群时
需要迁移的数据量,key6,7对应橘色弧线的所有key值;
扩容和缩容时,节点数量越多.数据未命中比例越少.少到一定程度,无需认为处理
2.4 数据的平衡性处理
上图的问题:hash一致性模型下,6379节点对应的数据量远远超过其他两个节点,造成6379最先达到瓶颈;
hash一致性算法中.支持引入虚拟节点进行计算;
虚拟节点是计算过程中过渡的变量
node1:虚拟节点
node1#1
node1#2
node1#3
node1#4
node1#5
…
node2:虚拟节点
node2#1
node2#2
…
虚拟节点可以看成真实节点信息+后缀的字符串;依然做hash散列计算映射到环上,这时,key值的顺时针寻找最近节点一旦对应的是虚拟节点,将会根据虚拟节点与真实节点的关系最终对应到某个真实节点;虚拟节点的个数越多数据的平衡性越好;jedis实现的hash一致性中,每一个节点的虚拟节点个数=160*weight权重值(默认是1)
**
3.总结hash一致性算法
**
1 基于数据模型–hash散列算法
2 hash散列算法的结果区间0-43亿–hash环
3 所有数据做散列映射到环上某个整数
4 key值顺时针寻找最近节点
5 引入虚拟节点(虚拟节点个数越多.平衡性越好)