当前位置: 首页 > 科技观察

带你快速了解:限流中的漏桶和令牌桶算法

时间:2023-03-17 16:57:42 科技观察

转载本文请联系脑筋急转弯公众号。前言理论上,每个提供外部/内部功能的资源点都需要一定的流量控制。否则,在业务的不断迭代中,可能会出现突发流量场景(比如年初某些行业带来的突变,导致业务流量突然激增):如果突发流量不限流,则有会出现一些奇怪的问题。实际上是系统承受不住这一波流量,逐渐崩溃,导致系统假死。最常见的真实场景就是日常生活中随处可见的排线和插座。内置保险丝又称电流保险丝,主要用于过载保护。当电流异常时,保险丝会上升到一定高度并发热。到时,自熔丝切断电流,从而保护电路的安全运行。因此,在现实世界中,与软件工程中的限流熔断场景有很多相似之处。也是要控制量,多了就砍掉。你也可以想想你在现实生活中是否遇到过其他类似的例子?Fuse(图片来自网络)LeakyBucketLeakyBucket是网络中流量整形(TrafficShaping)或速率限制(RateLimiting)中常用的一种算法。其主要目的是控制数据注入网络的速率,平滑网络上的突发流量。漏桶算法通过其算法对流量的接入进行调控,使突发的流量进行整形、去毛刺,转为相对适度的流量,为网络提供稳定的流量。漏桶算法的存储桶主要由三个参数定义,即:桶的容量、水流出桶的速率、桶的初始满度。核心理念正如其名:漏水的水桶。图片来自geeksforgeeksBurstyFlow在上图中,水龙头代表BurstyFlow。当网络中没有任何规律地突发流量时,就会出现类似于BurstyData的场景。主机以12Mbps的速率发送数据2秒,总共24Mbits的数据。然后主机暂停发送5秒,然后以2Mbps的速度再发送数据3秒,最后发送总共6Mbits的数据。因此主机在10秒内发送了总共30Mbits的数据。但是这里有个问题,就是数据传输不顺畅,有一个很大的峰值。如果所有的流量都这样传输,就会“旱涝保收”,对系统不是特别友好。FixedFlow以解决BurstyFlow场景的问题。漏桶(LeakyBucket)出现了,漏桶有固定的流出率和固定的容量。在上图中,漏桶在相同的10秒内以3Mbps的速度持续发送数据以平滑流量。如果水(流速)来得太快,但是水流(漏水)不够快,最后的结果就是水直接溢出,就是拒绝请求/排队等候的表现。另外,当Buckets为空时,有可能一次性倒入达到Bucket容量极限的水,此时也可能出现峰值。简单的说,一个漏桶,水往里流,但是漏桶只有固定的流量流出水。如果容量满了就拒绝,否则流量继续流出。令牌桶算法令牌桶算法也是网络中流量整形或限速中常用的一种算法。它的主要目的是控制发送到网络的数据数量,并允许发送突发数据。令牌桶算法以恒定的速率将令牌放入桶中。如果有新的请求进来,想要处理,必须先从桶中拿到一个可用的token,才能继续处理。如果桶中没有可用令牌,则请求被拒绝/排队。图片来自gateoverflow。每1/r秒向桶中添加一个新令牌。桶最多可以容纳b个令牌。如果桶已满,则新添加的令牌将被丢弃(即不需要新令牌)。当主机发送n个字节的数据包时,如果桶中有n个令牌,则获取所需的令牌并成功发送n个字节。当可用令牌少于n字节时,将不会从桶中提取任何令牌,请求将被拒绝/排队。LeakyBucketvsTokenBucket漏桶算法和令牌桶算法本质上都是为了流量整形(TrafficShaping)或者限速(RateLimiting),防止系统因为大流量而崩溃,但是两者最核心的区别在于电流限制的方向是相反的。令牌桶限制流量的平均流入速率,允许一定程度的突发流量。最大速率是桶的容量和生成令牌的速率。漏桶限制了流量的流出速率,流量相对固定。因此,也会带来一个相对的问题。在某些场景下,漏桶算法不能有效利用网络资源,因为漏桶的漏率相对固定,所以网络状况较好,不会出现拥塞,漏桶还是有限制的,没有办法放量。令牌桶算法不同。可以限制平均速率,同时支持一定程度的突发流量。综上所述,在软件系统中,限流往往代表流量整形和限速,是一种很常见的控制方式。一般前期我们会把它集成到统一的框架、网关、Mesh中。所以建议接触业务的同学考虑这个区域,方便后续快速使用/访问。毕竟业务流量的爆发总是来得突然,甚至可能是恶意攻击。本文提到的leakybucket和tokenbucket都是很常用的方法,虽然这两个是独立分析的。但是从软件开发的角度,你觉得两者可以融合,结合各自的优势吗?