| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux TC 流量控制与排队规则 qdisc 详解(以HTB和RED为例) -> 正文阅读 |
|
[系统运维]Linux TC 流量控制与排队规则 qdisc 详解(以HTB和RED为例) |
1. 背景Linux 操作系统中的流量控制器 TC (Traffic Control) 用于Linux内核的流量控制,它规定建立处理数据包的队列,并定义队列中的数据包被发送的方式,从而实现对流量的控制。 每个网络接口会有一个入队列(ingress)和一个出队列(egress),入队列功能较少。Linux流量控制主要是在输出接口进行处理和实现的。本文也都是基于出队列。 TC 模块实现流量控制功能使用的排队规则分为两类:无分类排队规则、分类排队规则。无分类排队规则相对简单,而分类排队规则则引出了分类和过滤器等概念,使其流量控制功能增强。 2. 流量控制组件2.1 qdisc 排队规则qdisc(队列规则,queueing discipline)是 Linux 流量控制系统的核心。实际就是一个队列上面附加的排队规则,下文有时也直接称为队列。 qdisc其实就是一个调度器,每个网络接口都会有一个调度器,qdisc会根据调度器的规则重新排列数据包进入队列的顺序。
Linux默认的排队规则是pfifo_fast,这是一种比FIFO稍微复杂一点的排队规则。一个网络接口上如果没有设置qdisc,pfifo_fast就作为缺省的qdisc。 由于项目需要这里主要讨论在输出口使用 RED 和 HTB。 2.2 class 分类类(class)仅存在于可分类的 qdisc 之下,过滤器(filter)也只能附加在有分类排队规则上。 类组成一个树,理论上能无限扩展。一个类可以仅包含一个叶子qdisc(默认为pfifo_fast),也可以包含多个子类,子类又可以包含一个叶子qdisc或者多个子类。 这就给 Linux 流量控制系统予以了极大的可扩展性和灵活性。 每个 class 和有类 qdisc 都需要一个唯一的标识符,称为句柄(handle)。标识符由一个主编号和一个子编号组成,编号必须是数字。句柄仅供用户使用,内核会使用自己的一套编号来管理流量控制组件对象。习惯上,需要为有子类的qdisc显式的分配一个句柄。 qdisc 的子编号必须为0,而分类的子编号必须是非0值。同一个qdisc对象下所有子类对象的主编号必须相同。 例如 root qdisc句柄为 特别地,ingress qdisc (入队列)的编号总是 ffff:0。 这个结构会在后面详细说明。 2.3 filter 过滤器**过滤器(filter)**即根据数据包的某属性进行匹配,进行分类后送到不同的队列上。过滤器能与 有分类qdisc 相关联,也可以和 class 相关联。 树的每个节点都可以有自己的过滤器,但是高层的过滤器也可以直接用于其子孙类。所有的出站数据包首先会通过 root qdisc,接着被与 root qdisc 关联的过滤器进行分类,进入子分类,并被子分类下的过滤器继续进行分类。如果数据包没有被成功归类,就会被排到这个类的叶子qdisc的队中。或者也可以只对根分类提供一个过滤器,然后为每个子分类提供路由映射。 过滤器使用**分类器(classifier)**进行数据包匹配,最常用的分类器是 u32 分类器,它可以根据数据包中的各个字段对数据包进行分类,例如源IP等。 **决策器(policer)**只能配合 filter 使用。当流量高于用户指定值时执行一种操作,反之执行另一种操作。在 Linux 流量控制系统中,想要丢弃数据包只能依靠决策器。决策器可以把进入队列的数据包流速限定在一个指定值之下。另外,它也可以配合分类器,丢弃特定类型的数据包。 3. 树型结构详解流量控制(Traffic Control, TC)以 当Linux内核接收数据包时,先根据过滤器进行分类,符合条件的数据包就被归为相应的类,而每一个类都对应一个相应的排队规则。如果一个数据包对于所有的过滤条件都不满足,则该数据包会被归为缺省类,将会使用缺省的队列规定对其进行处理(默认pfifo_fast)。 Linux在实现TC的时候,对“队列”进行了抽象,基本上它维护了两个回调函数指针,一个是enqueue入队操作,一个是dequeue出队操作。不管是enqueue还是dequeue,都并不一定真正将数据包排入队列,而仅仅是“执行一系列的操作”:
所以对于非叶子节点的qdisc,实际上是一个“不存在的队列”,数据包没有实际在此排队,只是递归调用子类的队列。只有在叶子节点上的队列才是真正能存放发出数据包的队列。 所以实际的树状结构如下: 一般为有子类的qdisc显式的分配一个句柄,方便添加过滤器和子类。 root qdisc 只是一个抽象队列,句柄为 同一个 qdisc 对象中,父节点的 filter 可以直接作用于子孙类,例如图中 root qdisc 的过滤器直接调用句柄为 数据包流入过程如下:
3. qdisc算法及使用3.1 RED随机早期探测(Random Early Detection,RED)是一种无分类qdisc。 当队列达到特定的平均长度,入队列的报文会有一定的(可配置)概率会被丢弃,这个概率会线性地增加到某一点,称为最大平均队列长度。 这种方式在队列增长时就开始随机丢包,使队列不至于太长,可以避免在流量突增之后导致的丢包重传(而这些重传会导致更多的重传)。 如果使用 用法
参数:
通过计算最高可接受的基本排队延迟来设置 ( 64 × 200 / 8 = 1600 64×200/8=1600 64×200/8=1600)。 设置 3.2 HTBHTB(Hierarchy Token Bucket,分层令牌桶)是一种有分类排队规则,允许把一条物理链路模拟成几条更慢的链路,或者是把发出的不同类型的流量模拟成不同的连接。 它使用了令牌和桶的概念,并使用了基于类的系统和过滤器对流量进行复杂和细粒度的控制。通过一个复杂的借用模型,HTB可以实现各种复杂的流量控制技术。另一种最简单的方式是在整流时使用HTB。 用法添加 htb qdisc:
添加类:
举例HTB是典型的
然后才能在之下建立子分类,这里为方便后续讲解手动设置
这些类的关系如下。随后可以使用filter和 u32 分类器把来自不同源 IP 的数据包送到不同的类。 所有数据包最后只能从叶子类(leaf class)排队,其他内部类(inner class)起到和子类共享带宽的作用。 当网卡比较空闲时,leaf class可以以高于 原理某个时刻每个类可以处于三种状态中的一种:
htb是如何决策哪个类出包的?
多个子类共享父类带宽也就体现在这里了。假设父类富余了10MB,子类1的quantum为30000,子类2的quantum为20000。那么父类帮子类1发送30000byte,再帮子类2发送20000byte。依次循环,最终效果就是子类1借到了6MB,子类2借到了4MB。因此上文说,当子类之间共享带宽时,rate/quantum共同决定它们分得的带宽。rate决定处于CAN_SEND状态时能发送多少字节,quantum决定处于MAY_BORROW状态时可借用令牌发送多少字节。 实例这里直接看这篇文章吧 参考Traffic Control HOWTO [1]郑辉. 基于 Linux 下的简单网络行为管理–Tc流量控制[J]. 软件:教育现代化(电子版), 2013(5):2. |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 22:18:07- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |