Consistent Hashing 一致性哈希算法
无论是数据库scale up, 负载均衡算法等只要是分布数据、请求又能让系统知道该去哪里找,就能用到一致性哈希算法。
例子:
我们有一个数据库用来存储用户数据。随着时间增长,数据量太大,我们希望有更多台数据库例如5台来平均的分担存储的数据。那么,我们的系统或者load balancer怎么知道具体的某个数据是存在哪台数据库呢?我们可以通过简单的mod算法,比如说user_id % 5的结果来选择该把数据存储在哪台数据库,后面读的时候也通过%5来找到对应的数据库。但是,如果我们要scala up更多台的数据库时候,比如增加到6台, mod 6的结果将发生变化,原来mod 5的结果和新的Mod 6的结果将不一致,即便我们做了数据迁移,把对应的数据迁移到对应的数据库使得我们可以继续使用mod 6算法,一旦继续scale up将再次面临这个问题。
传统的Hash算法
传统的哈希算法采用 hash(m) % n 映射 m 的地址,当添加新节点或者有节点出现故障的时候, n 将产生变化,随即 hash(m) % n 的结果值将发生变化,几乎所有的地址映射都会受到影响
优化, 构建哈希环
一致性哈希则不同于传统方法,本质是构造一个定长的哈希环,将每个节点 hash 后放置在环中的某处位置上,计算 m 的哈希值后 顺时针 寻找最近的节点位置。添加新节点后,只需计算新节点的 hash 放置在环中,影响的只是顺时针临近的映射地址,其他均不受影响:
继续优化,避免数据倾斜
当哈希环上的节点分布不均匀时,节点的管辖范围有概率性的不同,大量的 m 哈希后产生了数据倾斜。参考 加权轮询法(Weight Round Robin) 的加权特性,不够分配就加权来补,在哈希环中补加虚拟节点 vn 个,使整个哈希环中的节点分布达到理论性的均衡: