几种常见的数据的负载均衡的算法

Tair和Memcache虽然称为“分布式”缓存服务器但服务器端并没有“分布式”功能。服务器端仅包括内存存储功能,其实现也非常简单。下面将介绍几种常见的数据的负载均衡的算法。分析他们的利弊和在他们在现有技术中的使用情况

1. Memcached的分布式方法,根据余数计算分散

Memcached的分布式方法简单来说,就是“根据服务器台数的余数进行分散”求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。

Ø 根据余数计算分散的缺点

余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。 那就是当添加或移除服务器时缓存重组的代价相当巨大。 添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中率。在Web应用程序中使用memcached时,在添加memcached服务器的瞬间缓存效率会大幅度下降,负载会集中到数据库服务器上,有可能会发生无法提供正常服务的情况。

mixi的Web应用程序运用中也有这个问题,导致无法添加memcached服务器。 但由于使用了新的分布式方法,现在可以轻而易举地添加memcached服务器了。这种分布式方法称为 Consistent Hashing。

2. Consistent Hashing

Consistent Hashing如下所示:首先求出memcached服务器(节点)的哈希值,并将其配置到0~232的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值并映射到圆上。 然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过232仍然找不到服务器,就会保存到第一台memcached服务器上。


Ø 图4 Consistent Hashing:基本原理

从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响。


Ø 图5 Consistent Hashing:添加服务器

因此,Consistent Hashing最大限度地抑制了键的重新分布。 而且,有的Consistent Hashing的实现方法还采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。因此使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。

通过下文中介绍的使用Consistent Hashing算法的memcached客户端函数库进行测试的结果是, 由服务器台数(n)和增加的服务器台数(m)计算增加服务器后的命中率计算公式如下:(1 - n/(n+m)) * 100

3. 维护一张对照表

Tair的服务器是一个集群,通常包含多台服务器。客户端需要一种规则来确定操作需要执行的相应服务器。传统的方法是根据对一个唯一的标识(下面我们称这个为key)做hash操作,将hash值对服务器的数量取模操作,以决定目标服务器。这便是我们介绍的第一种方案

所谓对照表就是将key的hash值和其对应服务器的关系以表格的形式保存起来,而不是直接依赖服务器的数量。由于key的hash值的范围太大,如果每个hash值有一条对照记录,那么这个对照表会非常庞大,使用、维护和管理的成本都太高。所以我们再将hash值对一个“固定数”取模,这将使对照表的记录数缩减到这个固定数,所有“取模”后的值相同的记录将被存储在同一台服务器上。

在选择这个“固定数”时需要考虑的问题是:

这个“固定数”不能太大,不然我们这个取模的意义就不大了

这个“固定数”也不能太小,因为这个“固定数”决定了这个集群服务器能容纳的物理机器上限,超过这个数量的物理机器将不能和数据对应起来

在Tair中我们现在使用的是:1023

客户端根据这张对照表和key的hash值路由到目的服务器并执行数据操作,服务器根据这张表执行扩容、复制操作等。

Ø  对照表格式介绍

对照表是一个数组,数组的长度为6*固定数,元素的下标为hash值,元素的值是服务器的地址(包括IP和端口),所以每个元素表示一条对照关系。相当于一个有6列的表格,每列的含义如下:

master

slave

迁移目标服务器的master

迁移目标服务器的slave

给客户端的master

给客户端的slave

Tair为了增加数据的可靠性,可以为每台服务器添加一个slave,作为备份。数据写入时会同步写入master和slave,读取时可以随机选择从master还是slave上读,所以在对照表中master和slave都需要。

当新增节点时,新节点需要从原有机器上同步完数据后,才能提供服务,所以在同步过程中,这些机器将位于第3和第4列。

当slave挂了后重新起来时它并不能马上提供服务,它需要先和master同步数据,以保证自己和maste状态一致后才能正常工作。在这个过程中,其它服务器(特别是其对应的master)需要知道这台slave起来了,但是client不能,否则client将会把一半的read请求发送到这台slave上,而slave上的数据可能没有或者是脏数据。所以在slave完成同步前不能推送给client,这里的最后两列就是给client端的对照表。在正常的时候,它和前两列是一致的,但是在slave恢复时,将不会在最后两列出现。

config server数据结构的示意图


当服务器状态发生变化或者有新服务器增加时,config server需要重新构建这张对照表以反应最新的对照关系。

重新构建对照表:由于对应关系的改变需要迁移数据,所以在构建对照表的时候需要在维持数据均衡的前提下尽可能的保留原有的对照关系。

下面以“固定数”为11,在3个节点(A、B、C)的基础上新增一个节点(D)为例描述构建对照表的步骤:

原有的对照表如下(我们这里只抽象的表示了节点的概念,实际情况将包括master/slave等6列,但这不影响构建的逻辑):


根据现在可用的节点构建新的对照表

可用的节点指和config server心跳正常的节点或者做了raid的节点。对于做了raid的节点,即使master/slave心跳都不正常,我们也不删除该节点。 当D节点添加进来后新的对照表如下:


将新的节点和老的节点比较,保留原有节点需要负责的hash值个数

在原对照表中(假设hash值以1开始),A节点负责{1、4、7、10},B节点负责(2、5、8、11),C节点负责(3、6、9) 在新对照表中,A节点负责{1、5、9},B节点负责{2、6、10},C节点负责{3、7、11},D节点负责{4、10} 这里我们并不使用新节点中的对应关系,而只使用新节点中每个节点负责的hash值的个数,以A节点为例:在新对照表中,A节点负责3个hash值,所以我们在原对照表中找出A负责的3个hash值,即{1,4,7},把这些节点仍旧交由A负责。对B,C节点也一样。最后剩下没有节点负责的交由新节点D。 在执行以上步骤后,结果对照表为:


将结果对照表和原对照表比较,将两者不相同的节点添加到搬迁的对应关系中。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值