限流算法

主要有以下5种算法,各有利弊。

  • 令牌桶算法
  • 漏桶算法
  • 固定窗口计数器
  • 滑动窗口log
  • 滑动窗口 计数器

令牌桶算法

令牌桶算法被广泛用于速率限制。它简单易懂,是互联网公司普遍采用的算法。亚马逊和Stripe都使用这个算法来限制他们的API请求。 令牌桶算法的工作原理如下:

  • 令牌桶是一个具有预定义容量的容器。令牌按照预设速率定期放入桶中。一旦桶满了,就不再添加令牌。如下图所示,令牌桶容量为4。填充器每秒将2个令牌放入桶中。一旦桶满,额外的令牌将溢出。

  • 每个请求消耗一个令牌。当请求到达时,我们检查令牌桶中是否有足够的令牌。下图解释了它是如何工作的。 • 如果有足够的令牌,我们为每个请求取出一个令牌,然后请求继续。 • 如果没有足够的令牌,请求将被丢弃。

下图展示了 令牌如何消费,重填以及限流的逻辑。下面的案例中,令牌桶大小为4,重填率是1分钟4个。

令牌桶算法需要两个参数:

• 桶的大小:桶中允许的令牌最大数量

• 补充速率:每秒放入桶中的令牌数量 我们需要多少个令牌桶?这取决于速率限制规则,因此会有所不同。以下是一些例子:

• 通常需要为不同的API端点使用不同的令牌桶。例如,如果允许用户每秒钟发1篇帖子、每天添加150个朋友和每秒钟点赞5次,则每个用户需要3个桶。 • 如果我们需要基于IP地址限制请求速率,则每个IP地址都需要一个桶。 • 如果系统允许最多每秒10,000个请求,则最好拥有一个全局桶,供所有请求共享。

优点: • 该算法易于实现。 • 存储空间使用效率高。 • 令牌桶允许在短时间内进行短暂的流量突发。只要令牌没有用完,请求就可以继续通过。

缺点: • 算法中的两个参数是桶大小和令牌补充速率。然而,适当地调整它们可能会具有挑战性

漏桶算法

和令牌桶很像,可以理解为加了一个水龙头,以固定速率流出。 本质上就是加了一个先进先出的队列,队列下游负责处理请求。可以想象Java中ThreadPool中的队列。流程如下:

如果队列满了,直接扔掉请求。

否则入队列,等待处理。

漏桶算法同样有两个参数:

  • 桶大小:其实就是队列大小
  • 处理速率

Shopify这家公司就用了这个算法。

优点:队列空间大小有限,可以节省内存;另外固定的处理速率很适合一些需要稳定处理的场景

缺点:面临突发流量,如果queue里有old 请求,突发请求可能会被drop掉。另外就是两个参数不是那么容易就能调整好。

固定窗口计数器算法

算法工作如下:

• 算法将时间线分成固定大小的时间窗口,并为每个窗口分配一个计数器。

• 每个请求将计数器增加一。

• 一旦计数器达到预定义的阈值,新请求将被丢弃,直到一个新的时间窗口开始。 让我们用一个具体的例子来看看它是如何工作的。

在下图中,时间单位为1秒,系统允许每秒最多3个请求。在每秒的窗口中,如果收到超过3个请求,则会丢弃额外的请求。

这个算法一个比较大的问题是,如果突发流量出现在 上一个窗口end和下一个窗口start,会导致超过limit的请求通过。如图所示

上图里面,每分钟最大请求设为5,2:00:58进来3个请求,2:00:59 进来2个。2:01:01进来一个,2:01:02进来4个。在这个不到1min的时间段内就有10个请求通过,比设定的大一倍。

优点:内存小,容易理解,每过单位时间就reset适合特定场景

缺点:上图所示,突发流量可能导致比预设更多的请求通过。

滑动窗口log算法

为了解决固定窗口算法的问题,滑动窗口log算法出现了,解决办法如下:

• 该算法会跟踪请求的时间戳。时间戳数据通常存储在缓存中,例如 Redis 的sorted set

• 当一个新的请求进来时,删除所有过时的时间戳。过时的时间戳被定义为早于当前时间窗口开始时间的时间戳

• 将新请求的时间戳添加到日志中

• 如果日志大小等于或小于允许的计数,则接受请求。否则,该请求被拒绝。

假如每分钟设定2个请求,图1请求允许。

图2请求在1:00:30也被允许,目前计数为2,没有超过limit;

图3请求1:00:50 不被允许,因为加进来计数为3,超过limit;

图4请求1:01:40 被允许,因为在[1:00:40, 1:01:40)范围内请求数量在limit以内。同时移除掉过时的请求。

优点:限流非常精确,在任意的滑动窗口里,都不会超过limit(注意和固定窗口对比)

缺点:耗内存,被drop掉的请求也被存在了内存里,想象一下DDoS打过来会怎么样

滑动窗口计数算法

滑动窗口计数算法是一种混合方法,结合了固定窗口计数器滑动窗口log。该算法可以通过两种不同的方法实现。本节将介绍一种实现方法,并在本节末尾提供另一种实现的参考。下图说明了该算法的工作原理。

假设速率限制器允许每分钟最多7个请求,在前一分钟有5个请求,在当前分钟有3个请求。对于到达当前分钟30%位置的新请求,使用以下公式计算滚动窗口中的请求数量:

• 当前窗口中的请求+上一个窗口中的请求*滚动窗口和前一个窗口的重叠百分比

• 使用这个公式,我们得到3 + 5 * 0.7% = 6.5个请求。根据使用情况,数量可以四舍五入为整数或小数。在我们的例子中,它被四舍五入为6。 由于速率限制器允许每分钟最多7个请求,所以当前请求可以通过。然而,在接收到另一个请求后,限制将被达到。

优点: • 它可以平滑流量峰值,因为速率是基于前一个窗口的平均速率计算的。 • 内存效率高。

缺点: • 它仅适用于不太严格的回溯窗口。它是实际速率的近似值,因为它假设前一个窗口中的请求是均匀分布的。然而,这个问题可能并没有看起来那么严重,根据Cloudflare的实验,在4亿个请求测试中,只有0.003%的请求被错误的允许。

[系统设计Alex Xu] 限流器 Rate Limiter 学习笔记-中相关推荐

  1. Elasticsearch7学习笔记(中)

    Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开放REST和JAVA API等结构提供高效搜索功能,可扩展的分布式系统.它构建于Apache Lucene ...

  2. [转]Verilog数字系统设计教程(大连理工一博士学习笔记)

    写在前面 学习Verilog HDL有一些时间,大概一年前的的这个时候开始的吧,从一点都不懂开始学,主要还是看夏宇闻老师的这本书入的门--<Verilog数字系统设计教程>,书写的特别好. ...

  3. 34_pytorch,动量与lr衰减(momentum,learning rate)--学习笔记

    1.31.动量与学习率衰减 1.31.1.动量 1.31.2.学习率衰减 1.31.动量与学习率衰减 1.31.1.动量 (1)没有引入动量 (2)引入动量后 从图中可以看到,引入动量后loss函数更 ...

  4. 疯狂python讲义学习笔记——中十章完结

    #第十一章 thinker import tkinter as tk print(help(tk.Button.__init__))#以按扭为例查看有什么属性 class myApplication( ...

  5. String类的学习笔记(中):介绍字符串的不可变性和字符串常量池

    本文介绍了String类字符串的不可变性和字符串常量池,主要包括 如何保证字符串不可变, 如何对字符串的修改. 为什么字符串要设置不可变, 字符串常量池的创建和了解,简单的字符串常量池图, 以及如何将 ...

  6. jQuery基础学习笔记(中)

    5.CSS操作及jQuery的盒子模型 1.jQuery CSS方法 <div></div> css.css .style1{width: 100px;height: 100p ...

  7. LwIP学习笔记——STM32 ENC28J60移植与入门

    0.前言 去年(2013年)的整理了LwIP相关代码,并在STM32上"裸奔"成功.一直没有时间深入整理,在这里借博文整理总结.LwIP的移植过程细节很多,博文也不可能一一详解个别 ...

  8. Linear-time zero-knowledge proofs for arithmetic circuit satisfiability 学习笔记

    1. 引言 Bootle等人2017年论文<Linear-time zero-knowledge proofs for arithmetic circuit satisfiability> ...

  9. linux添加自己的库,Linux学习笔记——例叙makefile 增加自定义共享库

    Linux学习笔记--例说makefile 增加自定义共享库 0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己 ...

最新文章

  1. MySQL B+树索引和哈希索引的区别
  2. 《那些年啊,那些事——一个程序员的奋斗史》——59
  3. java使用jsp servlet来防止csrf 攻击的实现方法
  4. 【原】如何实现IE6下块级元素的内容自动收缩
  5. micropython入门教程-Micropython入门实操心得
  6. Git和Github代码管理实践
  7. VB / VS 多语言软件设计
  8. [转]引用 VC 对话框设置位图背景并透明控件
  9. Qt_编辑器配色方案
  10. AP6212 蓝牙调试步骤
  11. C语言99乘法表,求指点
  12. excel 柱状图 多个水滴图组合
  13. 提交到dockerHub
  14. 一线城市与三线城市的IT生活——从《机器灵 砍菜刀》说开去
  15. L1-054 福到了
  16. python excel模板_如何利用Excel与Python制作PPT
  17. Android利用zxing生成二维码
  18. Android打包混淆压缩
  19. 内存申请与释放(转)
  20. 10款优秀的WordPress企业主题推荐

热门文章

  1. 五款资深高效的Web性能测试工具
  2. 字典序全排列算法(非递归全排列算法)
  3. 如何基于Avalon总线完成QSYS IP定制
  4. 手把手教你看懂自然语言处理-NLP(4个典型应用+5个难点+6个实现步骤)
  5. 解决配置了ssh但git clone时依旧要输入密码
  6. CSS3 border-radius圆角
  7. powerpoint无法从_如何重用或从另一个PowerPoint演示文稿导入幻灯片
  8. 医美、房产、新能源,服装企业的跨界能有多夸张?
  9. 资讯APP走出同质化怪圈,精细化用户画像成契机
  10. 显卡及相关硬件产品价格