一致性hash到底多牛×

前几天面试的时候被问了一个很熟悉但是就是想不出来的问题(这可能就是没有记牢固的原因)

面试官:你了解一致性hash吗?知道什么是虚拟节点吗?
我:不了解。。。
当时我就觉得我可能是疯啦,居然这样直接回绝,后来想想,如果强迫自己去说的话,可能会吞吞吐吐还不确定,更加难受,干脆长痛不如短痛!!!
所以我下来赶紧把这一块的知识点补齐

普通hash的弊端

一般在服务器集群背景下,对于同一个客户的请求分发会出现问题
我们知道对于每一次的请求分发进行hash计算,然后对集群中服务器数量进行除余,最后确定到底会分发到哪一个服务器上
弊端:当集群的服务器的数量发生改变(增加或者减少),那么所有的用户请求对应的服务器都会发生改变(即不会请求原来的服务器),这样可能会造成所有用户数据丢失。

一致性hash

一致性hash有效的解决了上面提到的弊端。
一致性hash维护一个散列表,该散列表从 0 到2的32次方都会存在,然后首尾相连
在这里插入图片描述

一致性hash的性质:

平衡性(Balance)
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。

单调性(Monotonicity)
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲区加入到系统中,那么哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲区中去,而不会被映射到旧的缓冲集合中的其他缓冲区。简单的哈希算法往往不能满足单调性的要求,如最简单的线性哈希:x= (ax + b) mod §,在上式中,P表示全部缓冲的大小。不难看出,当缓冲大小发生变化时(从P1到P2),原来所有的哈希结果均会发生变化,从而不满足单调性的要求。哈希结果的变化意味着当缓冲空间发生变化时,所有的映射关系需要在系统内全部更新。而在P2P系统内,缓冲的变化等价于Peer加入或退出系统,这一情况在P2P系统中会频繁发生,因此会带来极大计算和传输负荷。单调性就是要求哈希算法能够应对这种情况。

分散性(Spread)
在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。

负载(Load)
负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。

平滑性(Smoothness)
平滑性是指缓存服务器的数目平滑改变和缓存对象的平滑改变是一致的。

根据上述它的5大特性,会有以下情况

1、开始,将各个服务器节点利用一定的hash算法反映到环形散列表上,尽量让其平均分布
在这里插入图片描述
2、每次来一个请求会先对请求进行hash,然后将其反应在环状散列表上,
如果正好落在一个服务器节点上,那么就直接让该服务器响应,
如果没有所在服务器节点上,那么顺时针查找最近的服务器节点,让其进行相应
在这里插入图片描述
3、如果集群中服务器的数量发生改变,那所有的用户的数据都会丢失吗?
不会,它只会影响一部分的用户
在这里插入图片描述
这样做的一个弊端:

如果节点 1 宕机或者删除节点 1 ,那么原来请求到节点 1 的都会请求到节点 2 ,那么节点 2 的压力就会激增,很可能导致节点 2 承担不起这么大的压力而挂机,然后所有的请求又请求到下一个节点,这样循环,出现雪崩的现象
解决方法:虚拟节点(某一个节点挂机之后,让其所有的请求分别分摊到多个节点上)

4、如果服务器节点的分布出现极端情况,导致大量的请求会到达其中一个服务器,而其他的服务器则闲置,这个时候就要引入虚拟节点的概念。
在这里插入图片描述
在这里插入图片描述
用到虚拟节点保证分配到节点1和节点2的请求的数量大致相同

hash槽

在 redis cluster 采用数据分片的哈希槽来进行数据存储和数据的读取,redis cluster一共有2^14(16384)个槽,所有的master节点都会有一个槽区比如0~1000,槽数是可以迁移的。master节点的slave节点不分配槽,只拥有读权限。
但是注意在代码中redis cluster执行读写操作的都是master节点,并不是你想 的读是从节点,写是主节点。第一次新建redis cluster时,16384个槽是被master节点均匀分布的。
redis 集群(cluster)的hash算法不是简单的hash算法,而是crc16算法,一种校验算法。

在这里插入图片描述
新建master节点
新建的master节点是没有槽区的,需要给master节点分配槽

删除master节点
1.如果主节点有从节点,需要将从节点转移到别的主节点上。
2.转移后 如果主节点有哈希槽,去调哈希槽,然后在删除master节点
注意:redis cluster的动态扩容和缩容并不会影响集群的使用。

一致性hash和hash槽的对比

1、hash槽并不是闭合的,key的定位规则是根据CRC-16(key)%16384的值来判断属于哪个槽区,从而判断该key属于哪个节点,而一致性哈希是根据hash(key)的值来顺时针找第一个hash(ip)的节点,从而确定key存储在哪个节点。
2、 一致性哈希是创建虚拟节点来实现节点宕机后的数据转移并保证数据的安全性和集群的可用性的。redis cluster是采用master节点有多个slave节点机制来保证数据的完整性的,master节点写入数据,slave节点同步数据。当master节点挂机后,slave节点会通过选举机制选举出一个节点变成master节点,实现高可用。但是这里有一点需要考虑,如果master节点存在热点缓存,某一个时刻某个key的访问急剧增高,这时该mater节点可能操劳过度而死,随后从节点选举为主节点后,同样宕机,一次类推,造成缓存雪崩。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页