一致性hash
一般来说,基于hash算法的分片中,算法内部是把记录分片到一种叫做“bucket”(hash桶)的内部算法结构中的,然后hash桶与实际的分片节点一一对应,从此实现了分片、路由的功能。
在这种一般结构中,在需要增加分片数量来横向扩容时,由于分片节点和hash桶之间的一一对应,导致算法根据原先的hash桶个数的进行的路由失效,需要根据新的hash桶数目做数据的再平衡才能再次服务。
一般hash算法中,这个数据再平衡本质就是更新hash算法的参数(hash桶数目)之后,再拿所有现存记录重新过一遍调整后hash算法,从而确定新的分片。
因此,由于数据再平衡工作量巨大,而且再平衡期间基本阻塞了所有的访问与操作,一般hash算法的直接分片很难做横向扩容。
为了实现横向扩容,有一种解决思路就是“过度分片”。该规则在算法层面解除了hash桶与分片节点的一一对应关系,从而实现了这种思路。这个规则独有一个虚拟桶倍数的概念——指的是一个分片上有且仅有多少个hash桶。在平常工作中,该规则与一般的hash算法分片的表现没有什么差异。
在横向扩容的时候,该规则就体现其优点了。分片节点的增加不会影响到算法核心的“分桶”工作,因此就不需要做代价高昂的数据再平衡,而简化为以hash桶为单位的数据迁移。数据迁移也不会波及所有的既存数据,因此从阻塞数据范围和阻塞时间长度上都得到了极大的改善。
与其他“过度分片”的做法相似,该规则的横向扩展是存在一个设计极限的。这个极限是分片节点数的上限,值等于“虚拟桶倍数×分片节点数”。此外,由于虚拟桶倍数与分片节点数都必须是正整数,而且要服从“虚拟桶倍数×分片节点数=设计极限”,因此在横向扩容的过程中,增加分片节点并不是一台一台地加上去的,而是以一种因式分解的方式增加——因此有浪费物理计算力的可能性。