令牌桶算法
Python的collections模块包含了许多实用的集合类。namedtuple可以定义一个简单的类,比直接定义一个类更简单,且减少了初始化类的很多初始化方法,所以速度更快。namedtuple继承于tuple,所以也拥有tuple的性质namedtuple还可以使用类方法_make方法来传入可迭代的对象创建类namedtuple还可以使用_asdict方法将namedtutple对象转化成字
在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送。令牌桶算法就实现了这个功能,可控制发送到网络上数据的数目,并允许突发数据的发送。
CAR(Committed Access Rate)三色模式
为控制网络速率,首先我们需要对进入网络的用户流量的速率限制在约定的范围之内,从而避免引起网络拥塞。
根据进入网络的流量进行评估,分为三个等级:红,绿,黄
- 红色: 表示流量严重超速,将报文打上红色,并丢弃报文
- 绿色: 表示流量未超速,将报文打上绿色,并直接转发
- 黄色: 表示流量稍微超速,将报文打上黄色,降低报文转发优先级,排队转发
如何判断流量的速率呢,这就需要用到令牌桶了
令牌桶
令牌桶可以看作是一个存放一定数量令牌的容器。系统按设定的速度向桶中放置令牌。当桶中令牌满时,多出的令牌溢出,桶中令牌不再增加。

在使用令牌桶对流量规格进行评估时,是以令牌桶中的令牌数量是否足够满足报文的转发为依据的。每个需要被转发的报文,都要从令牌桶中领取一定数量的令牌(具体数量视报文大小而定),才可以被正常转发。如果桶中存在足够的令牌可以用来转发报文,称流量遵守或符合约定值,否则称为不符合或超标。

例如在秒杀活动中,用户的请求速率是不固定的,这里我们假定为10r/s,令牌按照5个每秒的速率放入令牌桶,桶中最多存放20个令牌,那系统就只会允许持续的每秒处理5 个请求,或者每隔4 秒,等桶中20 个令牌攒满后,一次处理20个请求的突发情况,保证系统稳定性。
按照系统向令牌桶投放令牌的速率和令牌桶的数量划分,实现令牌桶的方式有三种:单速单桶,单速双桶,双速双桶
令牌桶算法都有两种工作模式——色盲模式(Color-Blind)与非色盲模式(Color-Aware,也叫“色敏模式”),其中色盲模式是较常用的,也是默认的模式。
单速单桶
单模式下只有一个令牌桶C桶
CIR(Committed Information Rate):
承诺信息速率,表示向C桶中投放令牌的速率,即C桶允许传输或转发报文的平均速率
CBS(Committed Burst Size):
承诺突发尺寸,表示C桶的容量,即C桶瞬间能通过的承诺突发流量。
单模式下,系统按照CIR速率向C桶投放令牌
- 如果可用令牌的总数量(Tc)小于CBS,则令牌继续增加
- 如果令牌桶已满,则令牌不再增加
对于到达的报文(报文大小为B):
色盲模式下
- 如果B <= Tc, 则报文被标记为绿色,且Tc减少B
- 如果B > Tc,则报文被标记为红色,Tc不减少
色敏模式下
- 如果报文已经被标记绿色且B<=Tc, 报文标记为绿色,Tc减少B
- 如果报文已经被标记未绿色且B>Tc,则报文被标记为红色
- 如果报文被标记为黄色或红色,则直接标记为红色
单速双桶(srTCM)
在单速单桶模式中,如果一直没有报文请求,那么令牌桶在满了之后就会一直不断溢出浪费,这个时候我们可以增加一个E桶,在C桶满了之后,多出的令牌会放在E桶内,当C桶内的令牌不够用时,会切换到E桶领取令牌。(C桶和E桶不能同时使用)
EBS(Excess Burst Size):
超额突发尺寸,表示E桶的容量,即E桶瞬间能通过的超出突发流量
当EBS=0,E桶的令牌数始终为 0,相当于只使用了一个令牌桶——C桶,这种情况也称为单速单桶。
在单速双桶模式下,系统按照CIR速率向桶中投放令牌。
- 如果C桶中的Tc小于CBS, 则C桶中令牌数增加
- 如果Tc等于CBS且E桶的可用令牌总数(Te)小于EBS,则C桶令牌数不增加,E桶令牌数增加
- 如果Tc=CBS & Te=EBS,增两个桶令牌数都不增加
对于到达的报文:
色盲模式下
- 如果B <= Tc, 报文被标记为绿色,且Tc减少B
- 如果Tc < B < Te, 报文被标记为黄色,且Te减少B
- 如果B > Te, 报文被标记为红色,Tc和Te都不减少
色敏模式下
- 如果报文已经被标记为绿色且B<=Tc,则报文被标记为绿色,Tc减少B
- 如果报文已经被标记为绿色且Tc<B<=Te, 则报文被标记为黄色,Te减少B
- 如果报文已经被标记为黄色且B<=Te,则报文被标记为黄色,Te减少B
- 如果报文已经被标记为黄色且B>Te,则报文被标记为红色
- 如果报文已经被标记为红色,直接将报文标记为红色
双速双桶(trTCM)
双速率三色标记算法业界都使用两个令牌桶,但它关注的是速率的突发,所以不像单速率三色标记算法那样把第一个桶中溢出的令牌放到第二个桶中,而是使用两个独立的令牌桶,存在两个令牌填充速率。为方便将两个令牌桶称为C桶和P桶,C桶容量为CBS,令牌填充速率为CIR,P桶容量为PBS,令牌填充速率为 PIR。
PIR(Peak Information Rate):
表示峰值信息速率,表示端口允许的突发流量的最大速率,单位是 bit/s。该值必须不小于CIR的设置值。
PBS(Peak Burst Size):
表示峰值突发尺寸,用来定义每次突发所允许多最大流量尺寸

在双速双桶模式中,系统按照PIR速率向P桶中投放令牌,按照CIR速率向C桶中投放令牌。
- 如果P桶中可用令牌的总数量(Tp)小于PBS,则P桶中令牌数增加。
- 如果C桶中可用令牌的总数量(Tc)小于CBS,则C桶中令牌数增加。
对于到达的报文:
色盲模式下:
- B>Tp,则报文红色
- Tc<B<=Tp,报文黄色,Tp减少B
- B<=Tc,报文绿色,Tc减少B,Tp减少B
色敏模式下:
- 报文绿色且B>Tp,报文红色
- 报文绿色且Tc<B<=Tp,报文黄色,Tp减少B
- 报文绿色且B<Tc,报文绿色,Tc减少B,Tp减少B
- 报文黄色,则只比较P桶,B>Tp,报文红色
- 报文黄色,则只比较P桶,B<=Tp,报文黄色,Tp减少B
- 报文红色,则直接红色
三种令牌桶模式的区别和应用场景
| 单速单桶 | 单速双桶 | 双速双桶 | |
|---|---|---|---|
| 关键参数 | CIR,CBS | CIR,CBS,EBS | CIR,CBS,PIR,POB |
| 令牌投放 | 以CIR速率向C桶投放令牌。C桶满时令牌溢出。 | C桶满时令牌投放到E桶。C桶和E桶都不满时,只向C桶投放令牌。 | 以CIR速率向C桶投放令牌,以PIR速率向P桶中投放令牌。两个桶相对独立。桶中令牌满时令牌溢出。 |
| 是否允许流量突发 | 不允许流量突发。报文的处理以C桶中是否有足够令牌为依据。 | 允许报文尺寸的突发。先使用C桶中的令牌,C桶中令牌数量不够时,使用E桶中的令牌。 | 允许报文速率的突发。C桶和P桶中的令牌足够时,两个桶中的令牌都使用。C桶中令牌不够时,只使用P桶中的令牌。 |
| 报文颜色标记结果 | 绿色或红色 | 绿色、黄色或红色 | 绿色、黄色或红色 |
| 令牌桶模式 | 功能 | 选用场景 |
|---|---|---|
| 单速单桶 | 限制带宽 | 优先级较低的业务(如企业外网HTTP流量),对于超过额度的流量直接丢弃保证其他业务,不考虑突发。 |
| 单速双桶 | 限制带宽,还可以容许一部分流量突发,并且可以区分突发业务和正常业务 | 较为重要的业务,容许有突发的业务(如企业邮件数据),对于突发流量有宽容。 |
| 双速双桶 | 限制带宽,可以进行流量带宽划分,可以区别带宽小于CIR还是在CIR ~PIR之间 | 重要业务,可以更好的监控流量的突发程度,对流量分析起到指导作用。 |
Tips
⭐️令牌桶只是一种流量测量方法,并不能对流量进行过滤或采取某种措施,比如说丢弃数据包等,这些操作由其他功能完成,而且令牌桶中装的是令牌而不是报文分组。
⭐️单速双桶模式中,如果EBS等于0,其效果和单速单桶是一样的。
⭐️双速双桶模式中,如果PIR等于CIR,其效果和单速单桶时一样的。
参考
更多推荐

所有评论(0)