hash算法的应用很广泛,如安全加密、数据校验、唯一标识、散列函数、负载均衡、数据分片、分布式存储。这里简单聊一下hash算法在分布式下的数据存储,假如我们有三台redis集群节点A、B、C:
1,普通hash+取模算法
我们在对数据进行查询的时候,会进行这样的运算:hash(key)%3来找到对应的机器。不过当我们数据量变大需要增加一台机器的时候,那这里相应会调整为:hash(key)%4,这样的话会将之前三个节点上所存储的数据与机器的对应关系都会影响到,同样某个节点出了故障进行了下线也会有同样的问题,这就会给后面的数据库造成很大的压力。显然这种路由算法在机器常常增减的场景下是不能接受的。我们接着看应对策略:
2,一致性hash算法
具体过程是这样的:先使用2的32次方构造一个虚拟环,然后将机器节点分布在这个环上:hash(节点ip)%2^32,这里是对2^32进行取模而不是对机器节点个数进行取模,当进行数据查找时进行hash(key)运算然后顺时针找到第一个遇到的机器节点。同样当我们增加一台机器时,也只会影响到1/3节点的数据而不至于像第一种方式影响到的有节点数据。解决了动态增减节点造成的影响但还是会存在数据分布不均匀的情况,可能会出现80%的数据都集中在其中一台机器上而另两台机器上的数据很少,这个时候的策略:
3,一致性hash+虚拟节点思想
在第2种思想的基础上,我们再对所有节点进行多次hash运算生成多个虚拟节点,只要hash运算的次数合适,那么每个真实节点对应的虚拟节点会交织分布的很均匀,如此一来数据在节点上的分布也会很均匀。这里的过程就是数据再定位到虚拟节点、虚拟节点再对应真实节点。
最后再提一下redis的 hash slot算法
redis定位key的过程是:CRC16(key)%16384找到对应的slot,而每个slot有相关的node,每个node会记录自身所属的slot也会记录其它node所属的slot,如果key就在自身node上则返回对应的value,如果不在则返回MOVED并返回这个key所在的node。也就是CRC16(key)%16384 -> slot -> node
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。