hash算法、一致性hash算法以及hash slot算法的简单介绍

3,192 阅读4分钟

本文主要介绍分布式数据存储的核心算法,也就是数据分布的算法,主要包含:hash算法 、一致性hash算法(memcached) 以及redis cluster中使用的hash slot算法。

  • 数据分布其实就是数据如何分布到多个不同的节点上

hash算法

hash算法的话,主要是对一个key计算hash值,然后再对节点数量取模,映射到某个节点上。

hash算法及其缺点
hash算法及其缺点

缺点

假设Redis中使用了这种古老的hash算法,就会导致某个节点宕机后,key重新取模,分布在不同的节点上了。

或者举个例子,本来想查找 key为helloworld的数据,之前通过set值操作分布在node3上,然后现在node2宕机了,helloworld的hash值对2取模了,算出来就不再node3上,就导致node3上helloworld对应的数据就无效了,反正我现在基于最新的node数量来取模的,之前的数据都不作数了。

这就是大大的坑爹了,此时如果没有重新写入数据的操作,那么直接就崩了,我去get数据是从和之前不同的节点上获取的,肯定是没有数据的;那么就会去数据库中查找,数据库在高并发场景下的压力太大了,会扛不住的。

如果Redis 使用了该算法,就会导致,只要任意一个节点宕机了,大量的缓存数据就会失效,大量的请求无法获取有效的缓存数据,就会将压力全部移交给数据库,而数据库根本扛不住高并发。

所以这种算法是千万不要用的。

一致性hash算法

一致性hash在古老的hash算法基础上作了改进。

  • 一致性hash的底层结构是一个环,环上有2的32次方个点,即0、1、2、4、8 、...、 2^32-1
  • 环上的每一个点都有一个hash值
  • 圆环上放着不同的节点机器。

一致性hash的步骤

  1. 计算key的hash值
  2. 用上一步的值 % (2^32),用于确保key能映射到环上的某一个点(避免映射到环外),即某个key在环上对应的点是:hash(服务器的IP地址) % 2^32
  3. key落到圆环上以后,就会按照顺时针寻找距离自己最近的一个节点。

假如一台节点机器宕机了,那么原本在那台机器上的数据会受到影响,按照顺时针的方式,之前的节点机器宕机了,就会走到下一台机器上去,而下一台机器上是没有数据的,导致部分流量瞬间涌入数据库,重新建立缓存数据。

图画的比较丑,请见谅!

概括

一致哈希将每个对象映射到圆环边上的一个点,系统再将可用的节点机器映射到圆环的不同位置。查找某个对象对应的机器时,需要用一致哈希算法计算得到对象对应圆环边上位置,沿着圆环边上查找直到遇到某个节点机器,这台机器即为对象应该保存的位置。 当删除一台节点机器时,这台机器上保存的所有对象都要移动到下一台机器。添加一台机器到圆环边上某个点时,这个点的下一台机器需要将这个节点前对应的对象移动到新机器上。

一致性哈希的改进

思考一个问题,我们的一致性哈希算法是按照顺时针的方式来实现数据分布的,如果某个区间的哈希值比较多,就会导致大量的数据涌入一个节点,就会导致节点的热点问题,从而出现性能瓶颈。

为了解决这个问题,一致性哈希算法采用了“虚拟节点”。

即在环上均匀生成多个 虚拟节点,后续 请求先找虚拟节点,然后再通过虚拟节点找到对应的真实节点。

因此,只要保证虚拟节点是均匀分布的,就可以实现数据均匀分布在不同的节点上。

hash slot算法

再来看一下redis cluster的hash slot算法。

  • redis cluster有固定的16384个hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。

  • redis cluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot

  • hash slot使得node的增加和移除很简单,增加一个master,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去(移动hash slot的成本是非常低的

参考内容

  1. https://mp.weixin.qq.com/s/FZgMPcs7VolP_04fworiRA
  2. https://zh.wikipedia.org/wiki/%E4%B8%80%E8%87%B4%E5%93%88%E5%B8%8C
  3. 《中华石杉亿级流量》

本文使用 mdnice 排版