一致性Hash算法
一致性hash算法是在1997年由麻省理工研究人员提出解决在分布式Cache问题中提出.为了解决网络中Hot spot热点问题.
一致性Hash算法之前
如在高并发访问量巨大的应用程序中,如果一旦Cache缓存服务器宕机,会导致大量的请求直接打到后端服务器或者数据库中,直接导致压垮后端服务器
后来缓存服务器出现多台的集群状态,某一个需要缓存的值经过某一种算法来选择具体缓存到哪个一个缓存服务器 如取模算法
假定有3台缓存服务器 Node1 Node2 Node3
计算出需要缓存的值key % 3 取模 得到值一定是 0-2 之间的一个数字 如果是0->Node1 1->Node2 2->Node3
这种算法实现逻辑十分简单,但在存在一个严重的问题.
比如现在我们需要增加一台缓存服务器变成了4台 Node1 Node2 Node3 Node4
此时一个key是跟4取模, 比如之前缓存的key为6 与3取模 6%3=0 从Node1中查找没问题,此时变成4台服务器6%4=2 此时从Node3中找,因为增加了一台服务器Node3没有Node1之前存储的数据,导致直接打到后端服务器
这种算法最大的问题在于,如果增加或者减少缓存服务器 会导致所有的缓存失效,导致缓存雪崩
一致性Hash算法解决的问题
- 一致性Hash算法,首先有一个2³²-1点组成的hash环,所有的缓存节点Node用一种hash算法计算中的值一定会落在hash环上某一个点
- 当需要缓存某一个值的时候也使用一样的hash算法,计算出一个值也一定会落在hash环中的某一个点
- 然后根据key落在hash环上的位置 顺时针找到下一个Node节点的位置,此时就找到了key需要存在哪个Node
这么做的好处在于,如果添加或者减少一个缓存Node不会导致整个缓存的雪崩
此时如果增加一个节点Node4,Node4落在Node1 和 Node2 之间 此时Node1 到 Node4节点的缓存失效,Node4 到 Node2之间的缓存还有效,也不会影响Node2 - Node3和 Node3 - Node1 节点
删除一个Node节点也是同样的道理,某一个节点的添加和删除不会影响整个缓存集群,只会影响一部分的缓存失效
存在的问题
-
hash偏斜问题 如果多个Node节点计算出来的hash值非常接近,导致落在hash环上的距离非常接近,会导致大量的数据会落在某一个节点上,如果该节点宕机会导致缓存雪崩,下图key1 key2 key3 都会落在Node3上,如果Node3的宕机很有可能造成缓存雪崩
-
解决办法就是增加hash环上的节点数量,但是真实的机器是需要成本的,所以可以虚拟复制出多个Node节点均匀的分布在环上这些节点称为虚拟节点, 如以前有Node1 现在虚拟多Node1’ Node1’’ Node1’’’ …等打散分布在hash环上 就避免了出现hash偏斜