微服务学习总结-> 负载均衡/熔断/限流

1,588 阅读6分钟

参考

负载均衡

  • 随机(Random)
  • 轮询(RoundRobin)
  • 哈希(Hash)
  • 加权(Weighted)
  • 一致性哈希(ConsistentHash)

一致性Hash

一致性Hash算法(Consistent Hashing Algorithm)是一种分布式算法,常用于负载均衡中。

特性

  • 平衡性(Balance):哈希的结果尽可能分布到所有节点中
  • 单调性(Monotonicity):如果一些内容已经分派到了响应的节点中,此时又有新的节点加入,Hash结果应能够保证原有分派的内容可以被映射到新的节点中去,而不会被映射到旧的节点中去。比如求余Hash(object % N)无法满足单调性
  • 平滑性(Smoothness):服务节点数目平滑改变和负载的平滑改变一致

原理

以三台缓存服务器缓存所有的对象,如下图:

  1. 构建环形Hash空间:Hash算法将一个value映射为一个32位的key值,即0key<2320 \le key \lt 2^{32},可以将此空间想象成一个首付相接的圆环,如上图
  2. 将服务器映射到Hash空间:一般可以使用服务器节点的IP或者服务器名作为Hash输入
  3. 将对象映射到Hash空间:同服务器映射同样的Hash算法
  4. 将对象映射到服务器:由对象在Hash环上的位置,顺时针,遇到到第一个服务器即为目标服务器

服务器变动

  • 增加一个服务器:假设在C和A之间增加了一个服务器,如下图所示,会影响C和之间的节点,之前映射到A的,现在C和D之间的映射到D,其他节点不变

  • 减少一个服务器:假设删除了B节点,则之前A和B之间的节点将全部映射到了C。

虚拟节点

Hash算法并不能保证绝对的平衡性,如果节点减少的话,对象并不能被均匀的映射到各个节点上。为此一致性Hash算法引入了虚拟节点

  • 虚拟节点(virtual node)是实际节点在Hash空间的复制品(replica):一个节点对应了若干个虚拟节点,对应的个数称为复制个数,虚拟节点在Hash空间中以Hash值排列。虚拟节点缓解了映射不均的情况

假设复制个数为2:

引入虚拟节点后,映射关系从【对象 \rightarrow 服务器节点】,变为了【对象 \rightarrow 虚拟节点 \rightarrow 服务器节点】。

负载均衡方式

  • 服务端负载均衡:传统方式是将负载均衡放在服务器端。最基础的算法是随机算法。大部分的负载均衡器会综合硬件、软件特性控制。

  • 客户端负载均衡:服务器之间是有不同的
    • Availability:没有服务器一直可用
    • Performance:不同服务器之间性能不同
    • Geography:服务器部署在不同的地方。 客服端的负载均衡器通常将请求发送到同一个区的服务器,或者根据响应速度。

dzone.com/articles/go…

应用Ribbon

Ribbon 是netflix 公司开源的基于客户端的负载均衡组件,是Spring Cloud大家庭中非常重要的一个模块。

限流

限流通常是一种保护服务的手段,维持服务可用。防止超出服务频率的调用。在一个可扩展的系统中,在一些层级也要做限流,以减少级联失败(cascading failure)的概率。

大型分布式系统上,客户端和服务器端同时限流,对于最大化吞吐量同时最小化端到端的延迟,至关重要。

作用

防止资源匮乏(Resource Starvation)

在大型系统中,许多无意的基于负载的拒绝服务事件,是由于软件中的错误,或者配置问题,而不是恶意的攻击(比如基于网络的拒绝服务攻击),并非由恶意攻击而引起的资源匮乏,也被称为 friendly-fire denial of service(DOS)。

一般,在受限资源服务前应用一个具有一定预警安全余量的限流。由于负载滞后,余量是必须的,这样限流保护在资源发生严重竞争之前,就可以起到作用。

管理策略和配额

当服务被多个客户端共享使用,就可以在每个客户端做限流,以提供公平而又合理的服务,互不影响。这种限流被称为配额。

流控

在处理大量数据或消息的复杂链路系统中,可以通过流控合并多个流到一个服务,或拆分一个工作到多个工作流。

避免超额

策略

漏桶(Leaky Bucket)

漏桶算法能够限制请求调用的速率

  • 漏桶的容量固定,按照固定速率流出水滴(请求)
  • 可以以任意速率流入水滴到漏桶
  • 如果流入水滴(请求)超过漏桶的容量,则溢出(请求被丢弃)

令牌桶(Token Bucket)

令牌桶算法能够在限制请求调用的平局速率的同时,还允许一定程度的突发调用

  • 令牌桶的容量固定
  • 令牌按照固定的速率放入令牌桶中
  • 当桶满时,新添加的令牌被丢弃或拒绝
  • 令牌桶根据放令牌的速率来控制访问速率
  • 请求到达后,首先从令牌桶中获取令牌,获取成功后才可以进行请求处理,处理完成后,将令牌直接删除

对比

令牌桶漏桶
请求何时拒绝令牌桶中令牌不够流入请求数累积超过漏桶容量
速率限制限制平均速率,允许一定程度的突发请求(支持一次拿多个令牌)限制常量流出速率,从而平滑突发流入速率
丢包问题

Fixed Window Counter

比如一小时限制3000个请求,但是,有可能3000个请求都同时出现在第一分钟。

  • 将timeline切分为固定的时间窗口,并在每个窗口设置计数器
  • 每个请求,根据请求时间,被映射到一个窗口
  • 如果这个窗口的计数已经达到上限,请求被拒绝

假设每分钟的请求上限是2,则请求过程如下图:

很明显,Fixed Window Counter算法仅保证了每个窗口平均速率,但没有跨窗口。

Sliding Window Log

  • 保存了每个请求的时间戳
  • 一个请求到来时,首先弹出所有超时的时间戳,然后再将当前请求时间加入Log
  • 然后再决定这个请求是否应该被处理,如果Log的大小大于上限,则不处理

Sliding Window

Sliding Window既有Fixed Window的优势,又可以将突发请求,通过滚动的时间窗变的平滑。比如Redis就在过期Keys使用了此技术。

分布式系统中的限流

在含有多个节点的集群中,当需要设置一个全局的限流器时,需要一个全局的存储(比如Redis),这样就存在着以下问题

  • Synchronized
  • Race Condition:set-then-get
  • 中心化计数带来的延迟

使用最终一致性:每个节点周期同步计数。

应用Ribbon

应用Kong

参考 How to Design a Scalable Rate Limiting Algorithm

熔断

断路器Hystrix

线程池模型

  • 检查策略

网关Zuul

未完待续