当前位置: 首页 > 后端技术 > Java

哈希算法和一致性哈希

时间:2023-04-01 16:28:29 Java

哈希算法应用广泛,如安全加密、数据校验、唯一标识、哈希函数、负载均衡、数据分片、分布式存储等。这里简单说说哈希算法的分布式数据存储。假设我们有三个redis集群节点A、B、C:1,我们在用普通的hash+取模算法查询数据的时候会执行这样一个操作:hash(key)%3找到对应的机器。但是当数据量变大的时候我们需要增加一台机器,那么这个就会调整为:hash(key)%4,这样会影响之前三个节点存储的数据和机器的对应关系。同样,如果一个节点出现故障下线,也会出现同样的问题,对后续的数据库造成很大的压力。显然,这种路由算法在机器经常增减的场景下是不能接受的。再来看看应对策略:2.一致性哈希算法的具体过程如下:先用2的32次方构造一个虚拟环,然后在这个环上分布机器节点:hash(nodeip)%2^32,这里是取2^32的模而不是机器节点数。进行数据查找时,先进行hash(key)运算,然后顺时针找到第一个遇到的机器节点。同样,当我们添加一台机器时,只会影响1/3节点的数据,而不是第一种方法影响的节点数据。解决了节点动态增减带来的影响,但是还是会出现数据分布不均的情况。可能会出现80%的数据都集中在其中一台机器上,而另外两台机器上数据很少的情况。此时的策略:3.一致性哈希+虚拟节点思想在第二种思想的基础上,我们对所有节点进行多次哈希运算,生成多个虚拟节点。只要哈希运算的次数合适,那么每个真实节点对应的虚拟节点就会交错均匀分布,这样数据就会均匀分布在节点上。这里的过程是将数据重新定位到虚拟节点,虚拟节点对应真实节点。最后提一下redis的hashslot算法。redis定位key的过程是:CRC16(key)%16384找到对应的slot,每个slot都有一个相关节点。每个节点都会记录自己所属的slot,同时也会记录其他节点。所属的slot,如果key在自己的节点上,则返回对应的值,如果不在,则返回MOVED,并返回key所在的节点。即CRC16(key)%16384->slot->node