分片计算逻辑hash取余
❤hash取余算法
一旦涉及到单调性,最先考虑到的计算逻辑就是hash散列.hash取余是一种分布式结构中非常常见经典的计算方法.
hash取余对数据key-value的key值做hash取余计算,得到结果只要key值不变(字符串相等) 取余结果在[0,1,2,3,…,n-1] n=分片个数(节点个数),计算公式:
(key.hashCode()&Integer.MAX_VALUE)%N 其中N为分片(节点)个数
key.hashCode(): 对key做hash散列计算,只要key值不变,得到一个不变可正可负的整数.只要散列计算,能够做到key不变,整数结果不变,不一定非得使用hashCode 最终任意一个key值都会对应[-21亿,21亿]区间的一个整数
key.hashCode()&Integer.MAX_VALUE: 31位二进制保真运算,目的是将前面的整数保真后31位二进制,保证他是一个正整数.& 位的与运算.目的是取得一个正整数
**结论1:**当key值不变时,可以得到一个不变的正整数
(key.hashCode()&Integer.MAX_VALUE)%N
N=5,取余结果 [0,1,2,3,4]
N=4,取余结果 [0,1,2,3]
N=3,取余结果 [0,1,2]
对N取余 结果[0,1,2,3,4,5…,N-1]
**结论2:**当key值不变时,可以通过hash取余得到 [0,1,2,…,N-1] 一个不变的取余结果
hash取余就可以应用在redis分布式数据分片计算逻辑中
当有key-value出现时,先对key做hash取余 n是节点个数(现在是3)
所有节点jedis排序(list) 0 1 2 … n-1 使用到取余结果对应到一个固定的jedis对象,最终连接固定的redis节点
❤hash取余不适用于redis的分布式集群
只要是hash必定数据倾斜; 可以通过key值的设计解决数据倾斜,key越规律,数据倾斜越小.
※ 由于redis集群有动态线性扩展的特点.3个变5个,5个变12个,很频繁发生.hash取余无法保证扩容,缩容时的单调性. (单调性造成严重破坏)
在一个频繁发生扩容缩容的分布式结构中,hash取余不适用,但是N不发生变化的结构中总是使用hash取余.