« 数据采集系统的调试数据采集器的灵活性 »

负载均衡运行的进程

负载均衡运行的进程


负载均衡的技术沙龙,主要是基于LVS的负载均衡,受益匪浅,开阔了思路,回去要好好研究一下.

  其实使用web服务器自身的设置也能达到负载均衡的目的,我们公司使用的web服务器是resin,resin自生就可以进行负载均衡设置,但是只有professional版本才支持,这个东西的license一个CPU要$500,所以实际使用的apache+resin的组合(免费嘛:)),由于公司的系统只有运营商和CP会登录访问,并发压力并不大,使用负载均衡主要是为了防止系统死掉后无法登录,所以这样的设计基本够用了。如果并发访问量很大的话,就应该考虑在apache前面加squid做cache、通过dns轮寻等方案了。 虽然网上也有apache+resin进行负载均衡设置的例子,但是由于apach和resin不同版本的配置的配置文件有一定的差距,按照网上的资料不一定能设置成功,下面的例子是在linux环境下使用httpd-2.0.59和Resin-3.1.6进行负载均衡设置的,如果使用其他版本请参考apache和resin官方网站的配置说明

  需要准备3台linux机器(如果是在没有,可以先用一台机器熟悉一下),每台机器都要安装apache和resin(其实1台装apach,另外2台装resin就够用了,,之所以要全装是为了以后的扩展考虑),其中一台作为前端服务器(apache),另外2台作为后台服务器(resin)
内核中进程调度模块的负载均衡行为分为“拉”和“推”,推这里不考虑,关于拉均衡有一篇文章特别好,具体出处就不记得了,我当时用的百度快照,那篇文章我认为最精彩的部分就是下面摘录的这段话:

  当某个 cpu 负载过轻而另一个 cpu 负载较重时,系统会从重载 cpu 上"拉"进程过来,这个"拉"的负载均衡操作实现在 load_balance() 函数中。load_balance() 有两种调用方式,分别用于当前 cpu 不空闲和空闲两种状态,我们称之为"忙平衡"和"空闲平衡":

  无论当前 cpu 是否繁忙或空闲,时钟中断(rebalance_tick()函数中)每隔一段时间(BUSY_REBALANCE_TICK)都会启动一次 load_balance() 平衡负载,这种平衡称为"忙平衡"。

  Linux 2.6 倾向于尽可能不做负载平衡,因此在判断是否应该"拉"的时候做了很多限制:

  1.系统最繁忙的 cpu 的负载超过当前 cpu 负载的 25% 时才进行负载平衡;

  2.当前 cpu 的负载取当前真实负载和上一次执行负载平衡时的负载的较大值,平滑负载凹值;

  3.各 cpu 的负载情况取当前真实负载和上一次执行负载平衡时的负载的较小值,平滑负载峰值;

  4.对源、目的两个就绪队列加锁之后,再确认一次源就绪队列负载没有减小,否则取消负载平衡动作;

  5.源就绪队列中以下三类进程参与负载均衡情况计算,但不做实际迁移:

  5.1.正在运行的进程

  5.2.不允许迁移到本 cpu 的进程(根据 cpu_allowed 属性)

  5.3.进程所在 cpu 上一次调度事件发生的时间(runqueue::timestamp_last_tick,在时钟中断中取值)与进程被切换下来的时间(task_struct::timestamp)之差小于某个阀值(cache_decay_ticks的nanosecond值),--该进程还比较活跃,cache 中的信息还不够凉。
感觉内核负载均衡的设计非常完美,然后我很迫切的翻起代码寻找一些蛛丝马迹,可是却没有找到明显的上面说到的东西,很是郁闷,然后我又研究了一下新内核的代码,发现了linux内核在做负载均衡的时候一个很巧妙的技巧,相比2.6.2内核只能说有过之而无不及。首先先说说负载均衡的策略,和2.6.2一样,也是尽量避免做负载均衡,除非非做不可了,因为负载均衡只是一个优化吞吐量和性能手段,它不是目的,因此没有必要让它占用太多的处理器时间,当然也没有必要提供编程接口了,机器有几个cpu,是否做负载均衡这些信息对用户是不可见的,但是用户可以通过设置一些微调参数从而影响内核负载均衡的行为,这种方式在linux中是很常见的。下面就来说一下新内核的负载均衡,linux有一个特点,如果一个特性是好的,那么即使高版本的内核也要向下兼容它,这里的兼容只是原理上,新版本的内核可能通过一种不同的方式实现这种老的理念,那么我们就在2.6.28内核中找一下2.6.2的负载均衡的影子吧。

  在新内核中,有一个函数特别有意思,就是update_cpu_load,这个函数更新了rq数据结构中的cpu_load数组字段,这个cpu_load数组在负载均衡中很重要,它代表了该队列所属cpu的负载,其实负载在cfs之前就是该cpu上运行的进程的数量,在cfs中代表当前cpu上所有的进程的权值之和,不过一个负载为何用一个数组而不仅仅是一个数字呢,这就是技巧所在,linux不仅仅根据当前这次负载均衡时的各个cpu负载来决定如何行动,linux还不丢失cpu以前的负载,因为这个涉及到缓存的热度等等cpu亲和相关的概念,但是负载均衡并不是在一个条件下触发的,它在很多条件下都会被触发,而这些条件对cpu亲和的要求并不相同,比如新创建进程的时候就不用考虑什么亲和的问题,还有如果是在运行idle的时候进行的负载均衡,那可能要考虑cpu亲和,但是考虑的程度绝对没有运行非idle进程时进行的负载均衡考虑cpu亲和的程度高,于是一个数字就不能代表这一切了,必须有个地方保留曾经的cpu负载信息,如果仅仅为了将曾经的负载信息考虑进去,那么也没有必要用一个数组,类比LRU的理论算法,用一个整数就可以了,每个时钟嘀嗒中,原来的cpu负载右移若干位,然后当前的负载加上去,负载均衡的时候用这个值作为参考进行一些变换后(因为要和当前cpu负载的单位一致,如果不变换的话,那么曾经的负载信息就会无故地加到上次时钟嘀嗒时cpu负载的低位上)和当前的cpu负载进行平滑行为就可以了



 

相关信息:

关于负载均衡服务

IDC提供的负载均衡服务

负载均衡运行的进程

负载均衡集群系统架构

负载均衡的服务器


  • 相关文章:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新留言

最近发表