数据分片让我们先来看一个例子。我们经常使用Redis作为缓存,将一些数据放在上面,以减轻数据的压力。当数据量不大,访问压力不高时,通常一个Redis就可以搞定。对于高可用,有主从就够了;当数据量变大,并发量变大的时候,所有缓存的数据放到一台机器上就有点困难了。毕竟一台机器的资源是有限的。通常我们会搭建一个集群环境,将数据尽可能均匀的放在各个Redis中。比如我们集群中有4个Redis。那么如何把数据尽量均匀的放到这4个Redis中呢?最简单的就是取模算法:hash(key)%N,N是Redis的个数,这里N=4;看起来很不错,因为依靠这个方法,我们平均可以将数据存储在4个Redis中。当有新的请求来的时候,我们也可以定位到数据会在哪个Redis中,这样就可以准确的查询到缓存的数据了。02数据分片遇到的问题但是4个Redis不够用,需要再加4个Redis;那么这个余数算法将变成:hash(key)%8;那么试想一下,当前大部分的缓存位置都会出错,极端情况下会造成缓存雪崩。03ConsistencyHashAlgorithmConsistencyHash算法可以很好的解决这个问题。它的大致过程是这样的:以0为起点,2^32-1为终点,画一条直线,然后将起点和终点重叠,直线变成圆,方向为顺时针方向由小到大。0右边的第一个点是1,然后是2,依此类推。将三台服务器的IP或者其他关键字进行hash后,取2^32取模,这样肯定会落在这个圆上的某个位置,记为Node1、Node2、Node3。然后对datakey进行同样的操作,必然会落在圆上的某个位置上;然后顺时针走,可以找到某个Node,就是要存放key的server。如果添加服务器或删除服务器,只会影响部分数据。但是,如果节点太少或者分布不均,很容易造成数据倾斜,即大部分数据会集中在某台服务器上。为了解决数据倾斜的问题,一致性哈希算法提出了【虚拟节点】,为每个服务节点计算多个哈希值,并将它们放在环上的不同位置。当然我们也可以发现,一致性Hash算法只解决了大部分的数据问题。
