一、使用场景:
1、Redis集群的使用:
为了保证Redis的高可用,提高Redis的读写性能,最简单的方式---做主从复制,
组成Master-Master(主主模式)或者Master-Slave(主从模式)的形式,或者建
立Redis集群,进行数据读写分离,类似于数据库的主从复制和读写分离。
同样类似于数据库,表单数据 > 500W 时,需要进行分库分表。所以当数据量
很大时(Redis与数据库对数据量大小有所差异),我们同样可以对Redis进行分库分表操作。
假设:一个社交网站,需要使用Redis存储图片资源,存储格式为
键值对(key:name --> value:path),而我们需要通过文件名查找该文件
所在服务器上的路径,数据量大概2000W。对其进行分库分表,规则就是
随机分配。假设部署8台缓存服务器,每台服务器大概500w数据。且进行
主从复制。
则:由于规则是随机的,所以某一条数据,可能存在于任何一组Redis
中,因此需要依次遍历所有的Redis服务器才可以查询到预期结果。显然,
遍历的效率就很低了。
2、为Redis集群使用Hash值:
【上面的假设,达不到我们的逾期结果。所以随机分配规则不行,那就模仿数据库分库分表:
按照Hash值、取模、按照类别、按照某个字段值等常见的规则就可以提高其效率了】
假设我们查找的是“a.png”,由于有四台服务器(排除从库),因此公式:
Hash(a.png) % 4 = 2,就可以定位到2号服务器上了,这样的话避免了
遍历所有服务器,大大提升了性能。
【核心思想 : 每一张图对应的Hash值取模计算后对应不同服务器的标号,实现定位到相应服务器的功能】
3、仅使用Hash值会产生的弊端与缺陷:
1、【问题1】接上面的假设:如果4台服务器不能满足我们的缓存需求时,我们需要加一台服务器。
那么当添加一个Redis结点后,只有四个节点与原来结点存储位置一样。此时其他节点,
无法从缓存在获取数据(缓存失效),则会一起到后台数据库读取数据,就会造成缓存血崩。
2、【问题2】同接上面的假设:如果4台服务器突然有1台出现了故障,那我们则需要将它移除,
当服务器由原来的4台变为3台,也会出现上述缓存血崩的现象。
原4台:
服务器缓存不足,添加后,5台服务器:
二、揭开一致性Hash算法的神秘面纱:
一、一致性Hash算法的取模方法:
1、上描述Redis集群取模方式:
Hash值对服务器数量取模
2、一致性Hash算法的取模方法:
Hash值对(2^32)-1取模,使得整个hash值空间构成一个虚拟的环。
3、Hash环:整个空间顺时针方向组织,正上方0直到(2^32)-1。由这2^32
个点组成的环称为Hash环,且起点跟终点在零点方向上重合。
假设某哈希函数H的值空间为0~(2^32)-1取模【即,hash值是一个32位的无符号整型】:
二、服务器位置的分配:
1、对各个服务器的hash值进行哈希:
取服务器IP或者主机名作为关键字进行哈希,这样就可以
将每台机器确定在hash环上的相应位置。
假设将上文4台服务器使用IP地址进行哈希后定位在环空间上:
三、数据如何访问相应的服务器(利用数据定位相应的服务器):
1、将数据值key使用同一个函数Hash计算出hash值,来确定此数据在环上的位置。
2、从算得的该位置,沿环顺时针“走”,第一个遇到的服务器就是改数据应该定位到的服务器
3、通俗易懂的话来说,就是把数据分类,分别定位到环上的不同区域,
而这某一类数据所在的区域,就是一台服务器,用来承载这些数据。
假设我们有Object A、Object B、Object C、Object D四个对象,经过hash计算后,环空间对饮位置如下:根据一致性hash算法数据对象A被定位到Node A上面。
三、一致性hash算法的容错性与可扩展性:
1、容错性:
假设Node C不幸宕机,只有A、B、D不会受影响,C对象会被重定向到D。
仅仅是此服务器C到其环空间前一台服务器B之间的数据受影响,其他的不会受影响。
2、可扩展性:
增加Node X,只有逆时针离它最近的C数据会被重定位到X,其他数据对象
A、B、D不受影响。
综上所述:一致性hash算法对于结点的增减都只需要重定位环空间的一小部分数据,所以保证了容错性和可扩展性。
四、hash环的数据倾斜问题:
1、当服务结点太少时,容易因为节点不分不均匀而造成数据倾斜问题。
2、大量数据分布在一个节点上,这个结点压力会很大
假设系统中只有2台服务器:
假设,在上面情况下,为每台服务器计算三个虚拟节点,于是可以计算“Node A1、Node A2、
Node A3、Node B1、Node B2、Node B3”的哈希值,于是六个虚拟节点:
同时数据定位算法不变,仅仅是多了虚拟节点到实际结点的映射,这样结点A上的数据就均匀定位到Node A1、Node A2、Node A3上了,这样就解决了数据倾斜问题。
五、结语:
一致性Hash算法,主要是考虑到分布式系统每个节点都可能失效,并且新结点很可能动态增加或减少。为了保证系统节点数目发生变化时,系统任然能对外提供良好的服务。这就是一致性hash算法带来的好处。
参考博文1: 一致性哈希算法原理 - lpfuture - 博客园 (cnblogs.com)