token bucket 算法简析

最近在解决一个Linux下DHCP无法获取IPv6地址的问题。在分析过程中发现,把IPv6防火墙停掉的话,用dhclient就可以给网卡获取到IPv6地址,否则就无法获取。初步判断,是IPv6的防火墙的问题。

在查看/var/log/iptables.log时,发现里面的log很少,几乎没有什么有用的log。在查看ip6tables rules时,发现有如下的一条规则用于控制log的输出:

-A LOGGING6 -m limit –limit 2/hour -j LOG –log-prefix “IP6TABLES DROP:”

INPUT,OUTPUT,FORWARD chain的最后一条规则就jump到LOGGING chain。而LOGGING chain在记录了一下LOG后,就直接DROP packet了。我对limit这个module不熟悉,就查看一下iptables extensions的man文档。看到了一句话:

This module matches at a limited rate using a token bucket filter.

这个token bucket是个什么东西?经过多翻查找,终于知道token bucket是一个流量控制算法。这里做一个简单介绍。

  1. bucket是个缓冲器,所有的数据都要经过bucket进行输出。
  2. 数据进入到bucket中,必须从bucket中取一个token做为进入bucket的钥匙。
  3. token是按照一定的rate来自动产生的,比如:1秒钟产生10个token。
  4. bucket既然是个缓冲器,它就有一定的大小限制,最多能处理的数据也是有限制的。因此,bucket中token的个数是有限制的,当bucket中token数达到一个值后,token就不会自动产生,而是等待数据消耗token。
  5. 当数据进入bucket的rate小于token产生的rate时,所有数据都可以被bucket处理,并且还会有多余的token留在bucket中。
  6. 当数据进入bucket的rate等于token产生的rate时,所有数据都可以被bucket处理,这时不会有多余的token留在bucket中。
  7. 当数据进入bucket的rate大于token产生的rate时,只有获致到token的数据可以被bucket处理,而那些没有获取到token的数据只能等待或者被drop掉。
  8. 对于第5种case,当token被累积时,可以留给临时的burst数据,这样数据rate比较大时,仍然可以被bucket短暂的处理。

在我的这个iptables例子中,数据就对应着iptables的DROP LOG,–limit对应着token产生的rate, –limit-burst对应着bucket中最多的token数。当然–limit-burst这个option没有在上面的规则中,它的默认值是5.所以如果要提高iptables产生LOG的数据,就把–limit这个rate提高就好,比如:20/second。

当时查询token bucket这个算法时,是用google查询的英文资料,可惜没有找到比较好的文章。找到的几篇都相对晦涩难懂。这里推荐几篇相对比较好的中文文章。

参考资料:
http://www.javaranger.com/archives/1769
http://blog.sina.com.cn/s/blog_5564d85e0100mkbb.html
https://blog.csdn.net/andylau00j/article/details/73958599