Consistent Hashing是很经典的分片方法。试着用“那五个问题”给自己一个反馈。
-
Consistent Hashing解决了什么用户痛点?(What, 正面)
一个痛点就是,用户不需要维护一张mapping的映射视图了,所有的mapping都能够计算出来。另外Consistent Hashing解决的用户痛点就是当节点数变动的时候,不会出现大面积需要调整partition owner的情况。只有局部的partition需要调整。特别是通过增加虚拟节点,分片可以打散的非常均匀。当一个物理节点消失的时候,因为多个虚拟节点消失了,这些REQ能够被均匀的调整到neigbor的虚拟节点上,而这些虚拟节点又分布在不同的物理节点上。 -
其它技术为什么没有解决这个问题? (why,反面)
如GFS就维护了分片的metadata,没有采用consistent hashing。造成了metadata的负担。
另一个不维护视图的比如round-robin,一旦一个节点失效,如果要均匀打散,新的映射关系就很难有规律化,不再是RR的了。如果用接管节点,那么这个接管的节点就多了一倍的工作量。
其它哈希技术,比如简单的Hashing,虽然采用了REQID–》hash值的映射,但没有采用哈希环,也没有把server也通过同样的哈希函数映射上去(虽然其它均匀分布的哈希函数也能达到同样效果)。这样就没有解决哈希值到server的映射问题。
-
这个技术它是怎么解决这个问题的?(How)
Consistent Hashing通过把REQID和ServerID通过同样的哈希函数打散在一个0-M的环上(通过%M)。通过顺时针查找,REQID被它顺时针碰到的第一个server hash代表的server来处理。在加入一个节点的时候,本来哈希值落在两个节点间的REQ,现在有一部分要分到这个新节点上。而通过引入虚拟节点,就打散的更均匀。虚拟节点可以用IP+序列生成。 -
它(真的)是最优的方法吗?(质疑)
单独造一张表维护分片metadata的方法有最大的灵活性。而consistent hashing太有规律了,已经定死了,没有灵活度。 -
如果是你从头做,你会用什么方法?(代入)
我会根据应用的需要,来选择。如果是完全打散的,那么consistent hashing还是很有吸引力的。如果在分片的其中,还需要一些内在联系,那么可能就只能保存metadata,比如用metadata server来存了。