一 背景
Swift通过引入Ring来实现对物理节点的管理,包括记录对象与物理存储位置间的映射关系,物理节点的添加和删除等。
针对决定某个对象存储在哪个节点上之类的问题,最常规的做法就是采用Hash算法,如果存储节点的数量固定,普通的Hash算法就能满足要求,但是因为Swift通过增减存储节点来实现无限的可扩展性,存储节点数量可能会发生变动,此时所有对象的Hash值都会改变,这对于部署了极多的Swift来说不太现实。因此Swift采用了一致性Hash算法来构建Ring。
二 一致性Hash
假设有N台存储节点,为使负载均衡,需要把对象均匀地映射到每个节点上,这通常使用Hash算法来实现。
对于普通的Hash算法,首先计算对象的Hash值key,然后再计算key mod N(key对N取模)的结果,得到的结果就是数据存放的节点。
比如,N=2,则值为0,1,2,3,4的key按照取模的结果分别存放在0、1、0、1、0号节点。
如果Hash算法是均匀的,数据就会平均分配在这两个节点上。如果每个数据的访问量比较平均,负载也会平均分配到两个节点上。
当然,这只是理想中的情况。在实际使用中,当数据量和访问量进一步增加,两个节点无法满足需求的时候,需要增加一个节点来满足用户的访问请求。
假设,N增加为3&#