服务器负载均衡技术

背景介绍:

由于网络的数据流量多集中在中心服务器一端,所以现在所说的负载均衡,多指的是对访问服务器的负载进行均衡(或者说分担)措施。负载均衡,从结构上分为本 地负载均衡和地域负载均衡(全局负载均衡),前一种是指对本地的服务器集群做负载均衡,后一种是指对分别放置在不同的地理位置、在不同的网络及服务器群集 之间作负载均衡。

每个主机运行一个所需服务器程序的独立拷贝,诸如Web、FTP、Telnet或e-mail服务器程序。对于 某些服务(如运行在Web服务器上的那些服务)而言,程序的一个拷贝运行在群集内所有的主机上,而网络负载均衡则将工作负载在这些主机间进行分配。对于其他服务(例如e-mail),只有一台主机处理工作负载,针对这些服务,网络负载均衡允许网络通讯量流到一个主机上,并在该主机发生故障时将通讯量移至其他主机。

常见服务器负载均衡策略

1、 DNS

最早的负载均衡技术是通过DNS来实现的,在DNS中为多个地址配置同一个名字,因而查询这个名字的客户机将得到其中一个地址,从而使得不同的客户访问不同的服务器,达到负载均衡的目的。

DNS负载均衡是一种简单而有效的方法,但是它不能区分服务器的差异,也不能反映服务器的当前运行状态。当使用DNS负载均衡的时候,必须尽量保证不同 的客户计算机能均匀获得不同的地址。由于DNS数据具备刷新时间标志,一旦超过这个时间限制,其他DNS服务器就需要和这个服务器交互,以重新获得地址数据,就有可能获得不同IP地址。因此为了使地址能随机分配,就应使刷新时间尽量短,不同地方的DNS服务器能更新对应的地址,达到随机获得地址,然而将过期时间设置得过短,将使DNS流量大增,而造成额外的网络问题。DNS负载均衡的另一个问题是,一旦某个服务器出现故障,即使及时修改了DNS设置,还是要等待足够的时间(刷新时间)才能发挥作用,在此期间,保存了故障服务器地址的客户计算机将不能正常访问服务器。

尽管存在多种问题,但它还是一种非常有效的做法,包括Yahoo在内的很多大型网站都使用DNS。

也可以在客户端实现,客户端获取某个域名对应的ip地址列表,然后分别去ping这些ip地址,选择一个响应最快作为连接服务器。这种方法可以防止某个机器故障不能及时发现的问题,响应的延迟大小也基本上可以反映网络和服务器负载情况。这种策略的缺点是增加了客户端代码的复杂度。这种策略在一些升级服务器上有应用。

2、 代理服务器

使用代理服务器,可以将请求转发给内部的服务器,使用这种加速模式显然可以提升静态网页的访问速度。然而,也可以考虑这样一种技术,使用代理服务器将请求均匀转发给多台服务器,从而达到负载均衡的目的。

这种代理方式与普通的代理方式有所不同,标准代理方式是客户使用代理访问多个外部服务器,而这种代理方式是代理多个客户访问内部服务器,因此也被称为反向代理模式。虽然实现这个任务并不算是特别复杂,然而由于要求特别高的效率,实现起来并不简单。

使用反向代理的好处是,可以将负载均衡和代理服务器的高速缓存技术结合在一起,提供有益的性能。然而它本身也存在一些问题,首先就是必须为每一种服务都专门开发一个反向代理服务器,这就不是一个轻松的任务。

代理服务器本身虽然可以达到很高效率,但是针对每一次代理,代理服务器就必须维护两个连接,一个对外的连接,一个对内的连接,因此对于特别高的连接请求,代理服务器的负载也就非常之大。反向代理方式下能应用优化的负载均衡策略,每次访问最空闲的内部服务器来提供服务。但是随着并发连接数量的增加,代理服务器本身的负载也变得非常大,最后反向代理服务器本身会成为服务的瓶颈。

3、 地址转换网关

支持负载均衡的地址转换网关,可以将一个外部IP地址映射为多个内部IP地址,对每次TCP连接请求动态使用其中一个内部地址,达到负载均衡的目的。很多 硬件厂商将这种技术集成在他们的交换机中,作为他们第四层交换的一种功能来实现,一般采用随机选择、根据服务器的连接数量或者响应时间进行选择的负载均衡 策略来分配负载。由于地址转换相对来讲比较接近网络的低层,因此就有可能将它集成在硬件设备中,通常这样的硬件设备是局域网交换机。

当前局域网交换机所谓的第四层交换技术,就是按照IP地址和TCP端口进行虚拟连接的交换,直接将数据包发送到目的计算机的相应端口。通过交换机就能将 来自外部的初始连接请求,分别与内部的多个地址相联系,此后就能对这些已经建立的虚拟连接进行交换。因此,一些具备第四层交换能力的局域网交换机,就能作 为一个硬件负载均衡器,完成服务器的负载均衡。

由于第四层交换基于硬件芯片,因此其性能非常优秀,尤其是对于网络传输速度和交换 速度远远超过普通的数据包转发。然而,正因为它是使用硬件实现的,因此也不够灵活,仅仅能够处理几种最标准的应用协议的负载均衡,如HTTP 。当前负载均衡主要用于解决服务器的处理能力不足的问题,因此并不能充分发挥交换机带来的高网络带宽的优点。

4、 协议内部支持

除了这三种负载均衡方式之外,有的协议内部支持与负载均衡相关的功能,例如HTTP协议中的重定向能力等,HTTP运行于TCP连接的最高层。客户端通过 端口号80的TCP服务直接连接到服务器,然后通过TCP连接向服务器端发送一个HTTP请求。在服务器分清客户端所需的网页和资源之前,至少要进行四次 TCP的数据包交换请求。由于负载平衡设备要把进入的请求分配给多个服务器,因此,它只能在TCP连接时建立,且HTTP请求通过后才能确定如何进行负载 的平衡。当一个网站的点击率达到每秒上百甚至上千次时,TCP连接、HTTP报头信息以及进程的时延已经变得很重要了。在HTTP请求和报头中有很多对负 载平衡有用的信息。首先,也是最重要的一点是,我们可以从这些信息中获知客户端所请求的URL和网页,利用这个信息,负载平衡设备就可以将所有的图像请求 引导到一个图像服务器,或者根据URL的数据库查询内容调用CGI程序,将请求引导到一个专用的高性能数据库服务器。惟一能局限这些信息获取的因素是负载 平衡设备本身的灵活程度。事实上,如果网络管理员熟悉Web内容交换技术,他可以仅仅根据HTTP报头的cookie字段来使用Web内容交换技术改善对 特定客户的服务,如果能从HTTP请求中找到一些规律,还可以充分利用它作出各种决策。除了TCP连接表的问题外,如何查找合适的HTTP报头信息以及作 出负载平衡决策的过程,是影响Web内容交换技术性能的重要问题。

但它依赖于特定协议,因此使用范围有限。根据现有的这些负载均衡技术,并应用优化的均衡策略,来实现后端服务器负载分担的最优状态。

游戏世界的负载均衡

1、 根据功能模块分散压力

每个服务器只完成特定功能,玩家根据需要连接不同的服务器。

clip_image002

2、 根据玩家数目分散压力

每个服务器完成所有功能,把玩家分配到不同服务器中,从而减少单个服务器压力。

clip_image004

BigWorld介绍

1、本地交互是廉价的,跨主机交互是昂贵的,因此尽量把相互接近的实体放到同一个服务器上。

地理上相差很远的实体则考虑放到不同服务器上。

clip_image006

3、 以实体(玩家、怪物和其他NPC等)为中心计算负载

实体作为单一事件的代码和数据。

实体可以在不同主机间移动。

实体都可以被保存到数据库。

clip_image008

4、 地图的划分有静态的和动态两种。

静态划分虽然容易,但是很多时候并不能反映真实的负载情况。

动态划分虽然开发难度大些,但是更灵活,更容易平衡真实负载。

动态划分是通过实时的移动不同游戏服务器的地图边界来实现的。

动态划分可以实时调整不同服务器的压力,无需预先配置和预测。

clip_image010

5、 如何提高效率

减少服务器之间的交互。

在边界区域放置实体对象的拷贝(ghost对象)。

所有读操作都在本地执行,这样比远程读取对象属性快很多。

假设一个地图由6个server来负责

clip_image012

以server 5为例

clip_image014

其中绿色区域是用来放置临近的其他server的ghost对象

 
 clip_image016

其中绿色区域为发送实体对象信息到其他临近server用来创建ghost对象

clip_image018

如何减少不同主机之间的通信

1、 通过RPC调用改变对象状态属性。

2、 所有的读操作都在本地执行。

3、 写操作会从ghost对象传到实体对象。

a) print localMonster.health

i. Reads from local copy

b) localMonster.attack()

i. Calls “attack” function directly on local object

c) print remoteMonster.health

i. Reads from local ghost copy

d) remoteMonster.attack()

i. Sends command to remote server

ii. Remote server calls “attack” on local object

通过AOI来提高数据通知效率

1、 最简单的方法是所有对象互相可见。

2、 这样会导致n2 次数据传递,代价非常大。

3、 如果只是发给对象感兴趣的区域(Area of Interest AOI ),则可以大大提高通知效率。

下面是AOI示意图

clip_image020

问题与解决方案

问题一

实体对象在不同server间移动,但是由于server的ip是动态变化,让客户端来做又不合适,一个合理的做法是加入代理服务器proxy。

最简单的架构

clip_image022

使用代理服务器(BaseApp)

clip_image024

使用代理服务器转发报文

用户在CellApp 1上

clip_image026

用户移动到CellApp 2上

clip_image028

问题二

当对象给另外一个服务器的对象发送消息或RPC,在回复消息之前被负载均衡方式移动到其他服务器,这时回复消息是否会出错?

使用邮箱和自动转发功能解决这个问题。

在下面的例子中,player 2随便在那个服务器上,当他向player 1发送一条消息后被转移到其他服务器,但是他还是能够收到player 1的回复。

clip_image029

服务器伸缩性演示

播放影片

问题三

硬件和实体都可能不是统一的,硬件有差别,不同实体的开销也不相同。

解决方法:根据cpu的消耗情况来分担负载,而不是根据用户数目。

如何处理当机

1、 所有机器都向中心服务器汇报状态。

2、 当机发生时,不同游戏服务器的地图边界重新划分。

3、 负载重新分配。

4、 死亡的对象通过ghost恢复,由于重叠的区域比较大,因此真正死亡的对象不多。

如何防止还未死掉的机器过载

1、 减少加载的对象数目。

2、 减少工作负载直到条件改善。

一个负载均衡之后的示例

clip_image031

物理地图的单元划分

整个世界地图被划分成很多单元,每一个单元都是100×100平方米的面积,负载均衡时边界调整是以单元为单位的。

单元的划分也有利于并行加载地图,提高了加载的速度。

当一个地图的容量超过机器物理内存时,也可以轻松处理。

理论上支持无限大的地图。

数据库伸缩处理

传统的最简单的处理是,所有的游戏服务器都和一个中心数据库打交道,这样会导致中心数据库的压力过大,容易出现过载。

解决方案:

每个BaseApp都有一个SQLite DB,然后SQLite DB把数据合并到中心数据库。

这样大大减少了中心数据库的压力。

如何保证对象ID唯一性

1、对象必须有唯一性ID,否则对象在不同服务器间移动就有问题。

2、如果都在中心数据库产生唯一性ID,这样会导致中心数据库的压力成为一个瓶颈。

解决方案一:

在不同机器上随机产生128位的ID,这样重复的可能性很小,但是并不完美。

另外,128位对象ID显得有点长。

解决方案二:

有中心数据库给每个游戏服务器分配ID,每个游戏服务器再给本机器上的对象分配下级ID。

这样拼接起来的ID肯定不会有重复,而且长度较短。

缺点是ID浪费较大,每个游戏服务器都占有一个号码段,跟用户多少无关。

如何处理边缘对象的移动

由于服务器的地图边缘经常动态移动,那么如何处理在地图边缘来回移动的对象?该对象可能在两个不同服务器上来回移动。

这些移动对服务器的性能有较大影响。

解决方案:

1、 延迟处理,是否定时处理?

2、 一些重要的对象身份属性不依赖于物理位置。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值