分布式系统架构设计 – 第5式 - 服务治理之横向限流模式

导读

日拱一卒,功不唐捐,分享是最好的学习,一个知识领域里的 “道 法 术 器” 这四个境界需要从 微观、中观以及宏观 三个角度来把握。微观是实践,中观讲套路,宏观靠领悟。本系列文章我把它命名为《分布式系统架构设计三十六式》,讲诉分布式系统里最重要的三十六个虚数的中观套路,而微服务的本质也是分布式,因此搞明白这三十六个最重要的知识点也就同时能搞明白微服务。

实现一个分布式系统通常会面临三大难题: 故障传播性、业务拆分与聚合以及分布式事务 。本系列中的服务治理章节主要是为了解决故障传播性的难题,它包括: 隔离、熔断、降级、限流、容错以及资源管控 ,本文将讲诉服务治理里的 “限流-横向限流” 模式,下一篇将讲诉 “容错” 模式。

动机

上一篇文章讲诉了纵向限流,那么为什么还需要横向限流呢?如下图所示:

流量控制

解决限流不均匀问题 : 如上图所示纵向限流只解决了网关-服务1,网关-服务2,网关-服务N的纵向路径的限流问题,但是并没有解决 这几个服务路径的限流是否均匀的问题,比如在某些情况下,网关-服务1 QPS 是 200,网关-服务2 QPS是 500,网关-服务N QPS 是 20,但是服务1-服务N的配置都是一样的,很明显,这里的限流并不均匀。

更细粒度的用户/租户的限流问题 : 如上图所示,用户1-用户N都发请求到网关,但是想限制每个用户可以进入系统的请求的个数,这里纵向限流并没有办法统计并控制每个用户的可以进入系统的请求数,纵向限流只能限制整体的进入网关的请求数,因此需要一个计数中心用于登记每个用户的请求数,从而进行更细粒度的流量控制,控制每个用户的请求数。


横向限流模式

如下图,通常采用一个类似配置中心或分布式事务中心的方式实现横向限流。

限流中心

  • 如左图所示,将集群限流服务中心实现在一个网关实例里,与网关一起提供服务,好处是无需再独立部署一个限流实例,缺点是网关如果挂掉,那么限流服务也会一起挂掉,而且无法对网关进行横向限流,只实现了网关底下的服务的横向限流;

  • 如右图所示,独立拉起一个集群限流服务中心实例,用于提供全局限流计数服务,好处是与业务解耦,缺点是在集群内增加了一个额外的服务实例,增加了系统复杂度。

横向限流模式设计思路

常用的横向限流算法有计数算法以及时间标签算法。

计数算法

如图所示,独立的限流服务中心,拉起一个独立的分布式配置中心/事务中心,在里头实现限流算法,比如固定窗口算法、滑动窗口算法、漏桶算法、令牌桶算法等用于全局计数,而且保证这个计数是全局唯一的,不管集群规模多大,保证每个服务所使用的计数器和计时器都是唯一的,服务拿到这个计数ID后在进行限流调度。


全局限流算法

  • CP模式:采用独立的限流中心,如果每个用户进入系统的请求都需要去远程的限流服务中心取一个计数返回,这就多了一个远程读取限流计数值的过程,很明显增加的这一步会影响请求的性能,但是在某些对限流可靠性比较苛刻的场景里,这是以牺牲请求性能的方式换取限流的可靠性;

  • AP模式:计数还是在限流服务中心,但在本地维护了一个限流计数的缓存,这样每个用户进来的请求并不是去远程读取计数值,而是直接在本地获取限流计数,而这个限流计数是通过一个独立的调度线程维护着的,这里这个本地的限流计数与远程限流服务中心的限流计数是不保证一致性的,这种方式牺牲了限流的可靠性,但是保证了请求的性能,在对限流要求不是很苛刻的场景下比较合适,而且配合纵向限流,还是可以解决绝大部分的系统的限流调度问题的。

时间标签算法

计数算法只是实现了限制用户或者服务请求量的最大值,并不能提供最小值保障,因此基于时间标签的算法被提出,例如DMCLOCK算法[1]。
在dmclock算法里,不只实现了限流,还实现了用户权重的划分以及最小值的预留。

例如在云服务里,用户1与用户2,付费不一样,因此给提供的最大限流上限是不一样的,但是采用计数限流算法,并不能保证付费多的用户就一定能得到最低的服务质量保证,在系统负载高的时候,付费高的用户与付费低的用户一样难以得到服务资源保底,这是不合理的,因此需要一个可以预留资源的算法。如下图所示,系统里流量资源的调度可以按 “预留、权重、上限” 这三个维度进行调度。


流量预留

例如,在时间标签算法里, 有三个用户:user1, user2,user3 根据付费的高低,给他们分别分配了不同的权重与预留值。如果系统里最大的QPS资源量是 4000,用户1与拥护2的QPS预留值是 1000,权重比例是 1:2:3.那么应当如何分配这些QPS资源? 按dmclock算法可以这样计算:

用户1 : (4000/(1+2+3)) 1 = 667 < 1000,但是保底的QPS是1000,因此分配了1000 QPS 给用户1.
用户2:( (4000-800) / (2+3))
2 = 1200 QPS
用户 3:4000-1200 – 667 = 2133 QPS

基本的计算思路是,先保证最低的预留值,再根据权重划分剩下的资源,并且保证不要超过最大值。

算法实践

  • 通常如非必要或者业务场景要求苛刻,纵向限流就够,实现横向限流会引入新的组件,增加复杂度,同时还影响系统性能;

  • 如果必须实现横向限流,那么性能要求高就采用AP模式,限流可靠性要求高就采用 CP模式;

  • 权衡利弊,根据业务场景合理组合纵向限流与横向限流,才是最佳实践。

小结

本文讲诉了服务治理里的 “横向限流”模式,在前一篇《分布式系统架构设计三十六式之服务治理-纵向限流模式》里讲诉了分布式系统服务治理的纵向限流模式。另作者能力与认知都有限,欢迎大家拍砖留念。

作者简介

常平,中科大硕,10年+数据相关经验,主要工作背景为分布式系统、存储、缓存、微服务、云计算以及大数据,现就职于DELL EMC。个人技术博客:https://changping.me

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh ,可以自由阅读、分享、转发、复制、分发等,限制是需署名、非商业使用(以获利为准)以及禁止演绎。

参考资料

[1]https://github.com/ceph/dmclock