分布式环境中的负载均衡策略

在分布式系统中相同的服务常常会部署很多台,每一台被称为一个服务节点(实例)。通过一些负载均衡策略将服务请求均匀地分布到各个节点,以实现整个系统支撑海量请求的需求。本文描述一些简单的负载均衡策略。

Round-robin

简单地轮询。记录一个选择位置,每次请求来时调整该位置到下一个节点:

curId = ++curId % nodeCnt

随机选择

随机地在所有节点中选择:

id = random(nodeCnt);

本机优先

访问后台服务的访问者可能本身是一个整合服务,或者是一个proxy,如果后台服务节点恰好有节点部署在本机的,则可以优先使用。在未找到本机节点时则可以继续走Round-robin策略:

if (node->ip() == local_ip) {
    return node;
} else {
    return roundRobin();
}

一旦遍历到本机节点,则后面的请求会一直落到本机节点。所以这里可以加上一些权重机制,仅是保证本机节点会被优先选择,但不会被一直选择。例如:

// initial
cur_weight = 100;
...
// select node
cur_weight -= 5;
if (cur_weight <= 0)
    cur_weight = 100;
if (cur_weight > 50 && node->ip() == local_ip) {
    return node;
} else {
    return roundRobin();
}

本机房优先

服务节点可能会被部署到多个机房,有时候确实是需要考虑跨机房服务。同本机优先策略类似,本机房优先则是优先考虑位于相同机房内的服务节点。该请求是从哪个机房中的前端服务发送过来的,则需要前端在请求参数中携带上机房ID。

在服务节点对应的数据结构中,也最好按照机房来组织。

本机房优先策略实际上会作为节点选择的第一道工序,它可以把非本机房的节点先过滤掉,然后再传入后面的各种节点选择策略。这里还可以考虑节点数参数,如果本机房的节点过少,则可以不使用该策略,避免流量严重不均。

Weighted Round-Robin

加权轮询。相对于普通轮询而言,该策略中每一个节点都有自己的权重,优先选择权重更大的节点。权重可以根据机器性能预先配置。摘抄一下网上的算法:

假设有一组服务器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;
}

遍历完所有节点后权重衰减,衰减到0后重新开始。这样可以让权重更大的节点被选择得更多。

Consistent Hash

一致性哈希。一致性哈希用于在分布式环境中,分布在各个节点上的请求,不会因为新增节点(扩容)或减少节点(节点宕机)而变化。如果每个服务节点上都有自己的缓存,其保存了该节点响应请求时的回应。正常情况下,这些缓存都可以很好地被运用,也即cache命中率较高。

如果某个节点不可用了,我们的选择策略又是基于所有节点的公平选择,那么原来一直分配在节点A上请求就很可能被分配到节点B上,从而导致节点A上的缓存较难被命中。这个时候就可以运用一致性哈希来解决。

其基本思想是,在节点选择区间内,在找节点时以顺时针方向找到不小于该请求对应的哈希值的节点。在这个区间里增加很多虚拟节点,每一个虚拟节点相当于一个物理节点的引用,这样相当于把物理节点变成了一个哈希值区间。这个哈希值区间不会因为增加节点和减少节点而变化,那么对某个请求而言,它就会始终落到这个区间里,也就会始终被分配到原来的节点。

至于这个不可用的节点,其上的请求也会被均匀地分配到其他节点中。

摘抄网上的一段代码:

// 添加一个物理节点时,会随之增加很多虚拟节点
template <class Node, class Data, class Hash>
size_t HashRing<Node, Data, Hash>::AddNode(const Node& node)
{
    size_t hash;
    std::string nodestr = Stringify(node);
    for (unsigned int r = 0; r < replicas_; r++) {
        hash = hash_((nodestr + Stringify(r)).c_str());
        ring_[hash] = node;  // 物理节点和虚拟节点都保存在一个std::map中
    }
    return hash;
}

// 选择data对应的节点,data可以是请求
template <class Node, class Data, class Hash>
const Node& HashRing<Node, Data, Hash>::GetNode(const Data& data) const
{
    if (ring_.empty()) {
        throw EmptyRingException();
    }
    size_t hash = hash_(Stringify(data).c_str()); // 对请求进行哈希
    typename NodeMap::const_iterator it;
    // Look for the first node >= hash
    it = ring_.lower_bound(hash); // 找到第一个不小于请求哈希的节点
    if (it == ring_.end()) {
        // Wrapped around; get the first node
        it = ring_.begin();
    }
    return it->second;
}

参考一致性 hash 算法(consistent hashing)Consistent Hash Ring

原文地址: http://codemacro.com/2014/08/25/lb-policy/

written by Kevin Lynx  posted at
http://codemacro.com

时间: 2024-10-10 12:45:50

分布式环境中的负载均衡策略的相关文章

Netflix中的负载均衡策略

Spring Cloud的负载均衡策略可以通过配置Ribbon搞定,也就是注入实现com.netflix.loadbalancer.IRule的类,当前包含的策略包括 1.RandomRule 随机策略 在while循环内,如果服务地址不为空会不停的循环直到随机出一个可用的服务. @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"}) public Server choose(ILoadBalancer lb, Obje

分布式进阶(十九) 基于集群的动态反馈负载均衡策略

基于集群的动态反馈负载均衡策略 基于动态反馈机制的集群负载均衡算法研究 目前应用最为广泛的集群计算技术主要分为三大类:高可用性集群技术.高性能计算集群技术和负载均衡集群技术. 德国的CarlAdamPetri于1962年在他的博士论文<自动机通信>中提出了Petri网的概念,它是一种适合于描述异步.并发.分布式系统的图形数学工具. 动态WRR调度算法 这是一个目前普遍使用的调度算法,算法在WRR的基础上加入了根据服务器端的负载信息周期性地调整服务器性能权值的过程.其基本思想是:根据CPU利用率

分布式的几件小事(四)dubbo负载均衡策略和集群容错策略

1.dubbo负载均衡策略 ①random loadbalance 策略 默认情况下,dubbo是random loadbalance 随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权重来进行负载均衡,权重越大分配的流量越高,一般就用这个默认的就可以了. ②roundrobin loadbalance策略 这个策略默认会将请求均匀的分布到各个provider上面,但是如果各个机器的性能不一样,很容易到杭州性能差 的机器负载过高. ③leastactive loadba

Tigase负载均衡策略

Tigase负载均衡策略 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs Tigase从5.2.0版开始,引入了负载均衡功能,可以把终端访问用户重定向到最适合的集群节点上.此负载均衡功能依赖于see-other-host的XMPP流错误消息(stream error message).此机制背后的基本原则是如果用户当前正尝试连接的节点与返回消息的节点不是集群中 的同一个节点,那么用户将被重定向.此原则需要获得用户的J

几种软负载均衡策略分析

公司去年上了F5,好用是好用,但是费用太高昂了,所以最近一直在研究软负载均衡这一块儿,恰巧今年年初谷歌开源了seesaw,让自己可以绕过很多弯路.特此总结下之前了解的负载均衡策略. -Sunface 在分布式系统中,负载均衡是非常重要的环节,通过负载均衡将请求派发到网络中的一个或多个节点上进行处理.通常来说,负载均衡分为硬件负载均衡及软件负载均衡.硬件负载均衡,顾名思义,在服务器节点之间安装专门的硬件进行负载均衡的工作,F5便为其中的佼佼者.软件负载均衡则是通过在服务器上安装的特定的负载均衡软件

搞懂分布式技术7:负载均衡概念与主流方案

搞懂分布式技术7:负载均衡概念与主流方案 负载均衡的原理 原创: 刘欣 码农翻身 4月23日 这是1998年一个普通的上午. 一上班,老板就把张大胖叫进了办公室,一边舒服地喝茶一边发难:"大胖啊,我们公司开发的这个网站,现在怎么越来越慢了? " 还好张大胖也注意到了这个问题,他早有准备,一脸无奈地说: "唉,我昨天检查了一下系统,现在的访问量已经越来越大了,无论是CPU,还是硬盘.内存都不堪重负了,高峰期的响应速度越来越慢." 顿了一下,他试探地问道:"老

Nginx专题(2):Nginx的负载均衡策略及其配置

摘要:本文介绍了Nginx的负载均衡策略,一致性hash分配原理,及常用的故障节点的摘除与恢复配置. 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第一期-宜信支付结算八方数据团队高级技术经理 周恒<Nginx的细枝末节> 分享者:宜信支付结算八方数据团队高级技术经理 周恒 原文首发于支付结算技术团队公号:野指针 前篇Nginx专题(1):Nginx之反向代理及配置详细介绍了Nginx功能之一--反向代理.本篇文章将重点介绍Nginx功能之二--负载均衡. 为了增加对负载均衡的好

Nginx的负载均衡策略及配置

转:https://www.cnblogs.com/yixinjishu/p/12028327.html 为了增加对负载均衡的好感,我们先了解负载均衡能实现什么. 将多个服务器节点绑定在一起提供统一的服务入口. 故障转移,在意外发生的时候,可以增加一层保险,减少损失. 降低上线运维复杂度,实现平滑上线.运维和开发同学都喜欢. 下面正式进入主题. 一.Nginx的负载均衡策略 负载均衡就是将请求“均衡”地分配到多台业务节点服务器上.这里的“均衡”是依据实际场景和业务需要而定的. 对于Nginx来说

负载均衡策略

在实际应用中,我们可能不想仅仅是把客户端的服务请求平均地分配给内部服务器,而不管服务器是否宕机.而是想使Pentium III服务器比Pentium II能接受更多的服务请求,一台处理服务请求较少的服务器能分配到更多的服务请求,出现故障的服务器将不再接受服务请求直至故障恢复等等. 选择合适的负载均衡策略,使多个设备能很好的共同完成任务,消除或避免现有网络负载分布不均.数据流量拥挤反应时间长的瓶颈.在各负载均衡方式中,针对不同的应用需求,在OSI参考模型的第二.三.四.七层的负载均衡都有相应的负载