1 流量整形的概念
流量整形是一种控制发送速率和数量的机制。通过流量整形能够调节数据传输速度减少拥塞。
有两种类型的流量整形算法:
- 漏桶
- 令牌桶
2 漏桶算法介绍
假设我们有一个桶,我们希望以随机的速率向桶中倒水,并以恒定的速率从桶中取水。因此我们需要在桶底部打一个固定大小的洞,这样来保证水流处的速率是恒定的。由于桶的体积有限,因此倒满后就停止。
水流入的速率可以改变,但输出的速率是恒定的。这种平滑输出流量的方法称为漏桶技术。突发进入的流量存储在桶中,并以稳定的速率输出。
上图中,假设主机产生突发流量,速率是每秒12M,持续两秒。总共24M的数据。5秒后,又开始以每秒2M的速率发送数据,持续3秒,总共发了6M数据。最终经过了10秒,主机一共发了30M数据。通过漏桶最终可以平滑这些流量,以每秒3M的数据,持续10秒,平滑的输出这些数据。如果没有漏桶,最开始的突发流量可能会使系统因流量突增出现问题。
最简单的漏桶算法可以通过队列来实现。队列来存储输入的数据包。如果流量由固定大小的数据包组成,那么每次总队列中删除固定数量的包即可。如果流量由大小不同的包组成,那么恒定的输出速率需要通过一个恒定的大小数据包大小来保证。
下面的算法描述数据包大小不确定的情况:
- 初始化一个计数器n,给定一个初始值。
- 如果n大于输入数据包的大小,那么则可以发送包,随后减少计数器的大小,减少的量为包的大小。 重复这一步,直到n小于包的大小。
- 重置计数器为初始大小,并从第一步重新开始。
例子:
另n = 1000, 输入数据包如下图:
第一个包大小为200,n > 200,因此 n = 1000 - 200 = 800
大小为200的包被发送到网络。
接着,队列头部的包大小为400,n > 400。 n = 800 - 400 = 400
队列头的包被发送到网络。
接下来,由于n < 队头包(450),因此停止,在下一个周期,重新初始化 n = 1000。重复上述过程,直到队列中的数据包都发送到网络中。
下面是使用Java对上述算法描述的一个简单实现:
public class Leakybucket {
@Test
public void testLeakyBucket() {
int no_of_queries = 4; // 请求次数
int storage = 0; // 桶中数据量
int bucket_size = 10; // 桶大小
int output_pkt_size = 1; // 每次流出桶中的数据量
int input_pkt_size = 4; // 每次进入到桶中包的数量
int size_left; // 桶剩余空间
for (int i = 0; i < no_of_queries; i++) {
size_left = bucket_size - storage; //space left
if (input_pkt_size <= (size_left)) {
storage += input_pkt_size;
System.out.println("Buffer size= " + storage +
" out of bucket size= " + bucket_size);
} else {
System.out.println("Packet loss = "
+ (input_pkt_size - (size_left)));
//full size
storage = bucket_size;
System.out.println("Buffer size= " + storage +
" out of bucket size= " + bucket_size);
}
storage -= output_pkt_size;
}
}
}
输出结果:
Buffer size= 4 out of bucket size= 10
Buffer size= 7 out of bucket size= 10
Buffer size= 10 out of bucket size= 10
Packet loss = 3
Buffer size= 10 out of bucket size= 10
3 漏桶与令牌桶的比较
对比 | 漏桶 | 令牌桶 |
---|---|---|
输入 | 以任意速率向桶中输入流量 | 以固定速率向桶中增加令牌,通过获取令牌进而获取处理流量的许可 |
输出 | 以恒定速率向外输出流量 | 输出可以一个取多个令牌,最大为桶中令牌数量,从而可以处理对应大小的流量 |
使用场景 | 突发输入流量转换为平滑的速率固定的输出流量 | 输入令牌速率固定,可一次取多个令牌,批量处理大小非均匀的突发流量 |
4 令牌桶相对漏桶的一些优点
- 如果令牌桶满了,那么令牌将被丢弃,而不是数据包。而在漏桶中,令牌被丢弃。
- 令牌桶可以以较快速率发送大量突发流量,而漏桶总是以恒定速率发送数据。
通过对比可以看到,令牌桶对流量的处理转换为通过对令牌数量的控制来操作最终的流量。