当前位置: 代码迷 >> 综合 >> Round robin
  详细解决方案

Round robin

热度:97   发布时间:2024-01-11 02:47:14.0

本篇文章先讲述轮询调度算法 (Round-Robin)及其在此基础上改进型的权重轮询算法 (Weighted Round-Robin)。

  轮询调度算法(Round-Robin Scheduling)

  轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。

  算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

  轮询调度算法流程

  假设有一组服务器N台,S = {S1, S2, …, Sn},一个指示变量i表示上一次选择的服务器ID。变量i被初始化为N-1。其算法如下:

j = i;

do 

{

j = (j + 1) mod n;

i = j;

return Si;

} while (j != i);

return NULL;

  这种算法的逻辑实现如图1所示:

  

                                             图1 轮询调度实现逻辑图示

  轮询调度算法假设所有服务器的处理性能都相同,不关心每台服务器的当前连接数和响应速度。当请求服务间隔时间变化比较大时,轮询调度算法容易导致服务器间的负载不平衡。

  所以此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。


2

This recipe implements a round-robin generator, a generator that cycles through N iterables until all of them are exhausted:

>>> list(roundrobin('abc', [], range(4),  (True,False))) ['a', 0, True, 'b', 1, False, 'c', 2, 3] 
Python, 11 lines
Download
 
Copy to clipboard
 123456789
10
11
from itertools import cycle, islicedef roundrobin(*iterables):pending = len(iterables)nexts = cycle(iter(iterable).next for iterable in iterables)while pending:try:for next in nexts: yield next()except StopIteration:pending -= 1nexts = cycle(islice(nexts, pending))

Round-robin is one of the simplest scheduling algorithms, where the scheduler assigns resources (e.g. processes) to each consumer in equal portions and in order. There is already a roundrobin recipe (http://docs.python.org/lib/deque-recipes.html) that uses a deque for popping iterables from the one end and pushing them to the other as long as they are not exhausted. This recipe uses itertools.cycle instead and is more efficient for long streams as it avoids all the pushing and popping.

nginx负载均衡策略分析[一](round_robin模块概要)

2013年10月03日  ? 综合 ? 共 2246字 ? 字号  小 中 大  评论关闭
id="iframeu1788635_0" src="http://pos.baidu.com/acom?rdid=1788635&dc=2&di=u1788635&dri=0&dis=0&dai=2&ps=337x846&dcb=BAIDU_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1457151442277&ti=nginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%AD%96%E7%95%A5%E5%88%86%E6%9E%90%5B%E4%B8%80%5D%EF%BC%88round_robin%E6%A8%A1%E5%9D%97%E6%A6%82%E8%A6%81%EF%BC%89%20%7C%20%E5%AD%A6%E6%AD%A5%E5%9B%AD&ari=1&dbv=0&drs=1&pcs=1240x672&pss=1240x672&cfv=19&cpl=11&chi=1&cce=true&cec=UTF-8&tlm=1457122642&ltu=http%3A%2F%2Fcncc.bingj.com%2Fcache.aspx%3Fq%3Dround%2Brobin%25e7%25ad%2596%25e7%2595%25a5%26d%3D4585055220334717%26mkt%3Dzh-CN%26setlang%3Den-US%26w%3DqembYKIegLMlCoKd5h7_dAUsu0Oo939n&ltr=http%3A%2F%2Fcn.bing.com%2Fsearch%3Fq%3Dround%2Brobin%25e7%25ad%2596%25e7%2595%25a5%26qs%3DHS%26pq%3Dround%26sc%3D8-5%26sp%3D1%26cvid%3DA05B43D91B6848788D08489ABC593B99%26FORM%3DQBRE&ecd=1&psr=1280x800&par=1280x734&pis=-1x-1&ccd=24&cja=true&cmi=51&col=en-us&cdo=-1&tcn=1457151442&qn=bfbb70a203148b35&tt=1457151442263.44.276.276" width="336" height="280" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; border-width: 0px; background-color: transparent; vertical-align: bottom;">

1.基本情况

模块名:round_robin

文件位置:ngx_http_upstream_round_robin.c

运行阶段:content_phase

RR策略做为默认策略

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
例如:
 upstream tomcats {
 server 10.1.1.107:88  max_fails=3 fail_timeout=3s weight=9;
 server 10.1.1.132:80  max_fails=3 fail_timeout=3s weight=9;
 }

上游调用:Ngx_http_upstream.c Ngx_http_upstream_ip_hash_module.c
功能:nginx在用作反向代理服务器时,对于后端的服务器可以采用两种分流策略:加权分流和ip hash。本模块主要完成加权分流功能。对于权重较高的机器,被选中的概率大,对于权重相同的机器,则采用轮询方式。
亮点:
1、在数据结构中设置了single字段,判断是否是只有一台后端服务器。如果是,则无需走分流策略模块,直接返回即可;
2、同时设置了失败次数和失败时间的上限。如果达到了失败次数上限,在一段时间内该server不参与分流。
3、backup服务器的使用。只有在现有server都无效时,才会请求backup服务器

2.关键数据结构

typedef struct {
//基本socket信息struct sockaddr                *sockaddr;socklen_t                       socklen;ngx_str_t                       name;
//当前权重值和设定权重值ngx_int_t                       current_weight;ngx_int_t                       weight;
//失败次数和访问时间ngx_uint_t                      fails;time_t                          accessed;
//失败次数上限值和失败时间阈值ngx_uint_t                      max_fails;time_t                          fail_timeout;
//服务器是否参与<span style="background-color: rgb(255, 204, 153);">策略</span>ngx_uint_t                      down;          /* unsigned  down:1; */
//ssl相关
#if (NGX_HTTP_SSL)ngx_ssl_session_t              *ssl_session;   /* local to a process */
#endif
} ngx_http_upstream_rr_peer_t; //后台服务器的具体信息//<span style="background-color: rgb(255, 255, 102);">round robin</span>后端服务器信息
typedef struct ngx_http_upstream_rr_peers_s  ngx_http_upstream_rr_peers_t;struct ngx_http_upstream_rr_peers_s {ngx_uint_t                      single;             //该群是否只有一台服务器ngx_uint_t                      number;             //该群后端服务器数量ngx_uint_t                      last_cached;	/* ngx_mutex_t                    *mutex; */ngx_connection_t              **cached;ngx_str_t                      *name;ngx_http_upstream_rr_peers_t   *next;               //下个upstream节点,即下一个服务器群的指针,next 一般指向backupserver(备份服务器群)ngx_http_upstream_rr_peer_t     peer[1];            //服务器群中的第一个服务器,如果还有其它的服务器,则会连续申请其它的peer
};typedef struct {ngx_http_upstream_rr_peers_t   *peers;              //所有服务器群的指针ngx_uint_t                      current;            //当前服务器uintptr_t                      *tried;              //服务器位图指针,用于记录服务器当前的状态uintptr_t                       data;               //tried位图实际存储位置
} ngx_http_upstream_rr_peer_data_t;

3.函数功能说明

主要的函数列表如下

ngx_int_t   ngx_http_upstream_init_<span style="background-color: rgb(255, 255, 102);">round</span>_<span style="background-color: rgb(102, 255, 255);">robin</span>(ngx_conf_t *cf,    ngx_http_upstream_srv_conf_t *us)ngx_int_t   ngx_http_upstream_init_<span style="background-color: rgb(255, 255, 102);">round</span>_<span style="background-color: rgb(102, 255, 255);">robin</span>_peer(ngx_http_request_t *r,    ngx_http_upstream_srv_conf_t *us)ngx_int_t   ngx_http_upstream_create_<span style="background-color: rgb(255, 255, 102);">round</span>_<span style="background-color: rgb(102, 255, 255);">robin</span>_peer(ngx_http_request_t *r,    ngx_http_upstream_resolved_t *ur)ngx_int_t   ngx_http_upstream_get_<span style="background-color: rgb(255, 255, 102);">round</span>_<span style="background-color: rgb(102, 255, 255);">robin</span>_peer(ngx_peer_connection_t *pc, void *data)static ngx_http_upstream_rr_peer_t *   ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)void   ngx_http_upstream_free_<span style="background-color: rgb(255, 255, 102);">round</span>_<span style="background-color: rgb(102, 255, 255);">robin</span>_peer(ngx_peer_connection_t *pc, void *data,    ngx_uint_t state)

参考资料:

nginx round_robin模块剖析

开源中国ngx_http_upstream_round_robin.c

  权重轮询调度算法(Weighted Round-Robin Scheduling)

  上面所讲的轮询调度算法并没有考虑每台服务器的处理能力,在实际情况中,可能并不是这种情况。由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。

  权重轮询调度算法流程

  假设有一组服务器S = {S0, S1, …, Sn-1},W(Si)表示服务器Si的权值,一个指示变量i表示上一次选择的服务器,指示变量cw表示当前调度的权值,max(S)表示集合S中所有服务器的最大权值,gcd(S)表示集合S中所有服务器权值的最大公约数。变量i初始化为-1,cw初始化为零。其算法如下:

while (true) {

  i = (i + 1) mod n;

  if (i == 0) {

     cw = cw - gcd(S); 

     if (cw <= 0) {

       cw = max(S);

       if (cw == 0)

         return NULL;

     }

  } 

  if (W(Si) >= cw) 

    return Si;

}

  这种算法的逻辑实现如图2所示,图中我们假定四台服务器的处理能力为3:1:1:1。

  

                                        图2 权重轮询调度实现逻辑图示

  由于权重轮询调度算法考虑到了不同服务器的处理能力,所以这种均衡算法能确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。所以,在实际应用中比较常见。


  相关解决方案