Consistent Hashing (一致性哈希) 学习总结

简介

分布式系统在水平扩展增加服务器时,新的服务器需要replicate一些local的data才能让新的request去访问。我们需要解决的是如何有效的分割数据才能尽量减少增加服务器需要做的数据重新分配,从而加快增加新的服务器的速度和减少可能出现的错误。

简单的方法

最原始的方法是用简单的hash来分割数据。假设我们有8台服务器,所有request通过user id%8来选择服务器, 那么user 1会用到服务器1, user 12会用到服务器4, 以此类推。这样的好处是非常简单,但是坏处是每次增加服务器我们需要从每一台现有的服务器中移动大部分数据到新加入的服务器中。假设我们现在要在8台服务器的基础上增加一台到9台服务器,那么之前user 1,9,17,25, 33都会在服务器1上,现在除了user 1不变,user 9需要到server 9,user 17需要到server 8, user 25需要到server 7, user 33需要到server 6. 这样需要消耗大量的带宽,非常不有效。有什么更有效的分割方法呢?我们可以保持2^n台服务器,每次扩展都让服务器翻倍;这样的好处是我们每次只需要移动一半的数据。比如现在我们有4台服务器,user id%4=1的user会用到server 1。 如果扩充到8台,user id%8=1的user还是会用的服务器1,但是user id%8=5的user要开始用服务器5,以此类推。这样的坏处是每次扩容必须让服务器翻倍,投入会非常大,可能有很长的一段时间新增加的服务器并没有什么request,会很浪费,而且我们还是需要移动一半的现有数据,还是很不有效。有没有更好的方法呢?

一致性哈希

Consistent Hashing (CH) 是把所有服务器放到一个环上,每个服务器分配一个range的数据。假设我们有4台服务器,user id的范围是0-999,那么server 1管理0-249, server 2管理250-499,server 3管理500-749,server 4管理750-999. 如果500-749的request超载我们需要增加一个server,那我们就在环上增加server 5在server 3和server4之间,管理500-749中的一部分。这样我们只需要移动server 3上的数据,大大减少了带宽的消耗。因为每一个server拥有很大的range,增加或者减少server会给现有的服务器增加load,从而可能影响服务的可用性。新的server的使用同样会需要时间去完成replication也可能会对现有的服务器有影响。CH的一个变型很好了解决了这个问题:我们把所有的user id hash到很多小的virtual node上,然后把virtual node随机分配给所有的服务器。这样每个服务器拥有很多virtual node,增加virtual node的次数会变多,但是每次需要做的数据传输会少很多。当服务器负载到一定临界值时,我们可以增加服务器,重新分配相邻服务器的virtual node。CH是在分布式系统设计中很常见的一个设计模式,在各种大型的分布式系统中都有广泛的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值