论文链接:https://ieeexplore.ieee.org/document/9651963
开源代码:https://github.com/LGN520/deltaint
0. 问题和关键见解
- 问题:如何减少带内网络遥测在数据平面中产生的带宽开销?
- 关键见解:状态变化在大多数情况下通常可以忽略不计,因此仅当状态变化(可以理解为某个状态在某两个时刻的状态值的差值)被认为很重要时,它才会将状态嵌入到数据包中。
1. 已有工作和存在的问题
-
原始 INT 框架:在每个节点的基础上将完整的状态嵌入到转发路径上的每个数据包中。存在的问题有:
- 高带宽开销:数据包大小以及带宽开销随路径长度而呈线性增长。
- IP 分片:如果数据包大小超过最大传输单元(MTU),则会增加 IP 分片的可能性。
-
基于采样的方法:将 INT 信息仅嵌入到采样到的数据包所构成的子集中。存在的问题有:
- 收敛速度较慢:其需要收集足够数量的数据包来进行准确的测量决策。
- 通用性差:其无法支持细粒度的每数据包测量方式,从而损害了原始 INT 设计针对各种应用的通用性。
2. 框架设计和处理逻辑
2.1 框架设计
设计理念:通过在可编程数据平面中记录状态信息并跟踪状态变化,DeltaINT 仅在存在重大状态变化时才将 INT 信息嵌入到数据包中。DeltaINT 旨在实现下面的三个设计目标:
- 通用性(generality):支持网络管理中的各种数据包级别和流级别的应用。
- 收敛性(convergence):监控可编程数据平面中每个经过的数据包并收集实时的遥测数据。
- 兼容性(compatibility):能够与现有的 INT 技术兼容,例如路径规划和值近似,以进一步节省带宽。
下图为 DeltaINT 在单个节点的架构设计
对于每个状态,它计算当前状态和嵌入状态之间的增量。仅当增量超过预定义的阈值时,DeltaINT 才会将当前状态嵌入到数据包中,并用当前状态去更新嵌入状态。如果接收方收到数据包,它会提取 INT 信息并向控制平面中的监控系统发送事件。
-
当前状态(Current States)的定义:当前状态由节点直接提供,而不使用其状态内存。具体地,在接收到数据包时,节点检索其设备的内部状态作为当前状态。
-
嵌入状态(Embedded States)的定义:嵌入状态用于对所有遍历的数据包进行有状态跟踪。DeltaINT 在每个节点的状态内存中按 per-flow 来记录嵌入状态,以支持数据包级别和流级别的带内网络遥测。本文使用基于草图的技术来在有限的数据平面资源中存储嵌入状态,如第 4 点所述。
-
增量(Delta)的定义:DeltaINT 监视节点中每个状态的增量,定义为节点为每个遍历的数据包所提供的状态(称为当前状态)与最近嵌入到某个数据包中的状态(称为嵌入状态)之间的变化。
-
数据结构和报头定义:
- 草图数据结构:DeltaINT 中的每个节点都会维护一个草图,用于使用有限的有状态内存来跟踪每个流的嵌入状态。草图 A 是一个二维数组,由 d 行组成,每行有 w 个桶。每个桶中记录着流标识符
Flowkey
和一系列嵌入状态Embstates
。设 A[i][j] 为第 i 行中的第 j 个桶,其中1 ≤ i ≤ d
且1 ≤ j ≤ w
。当节点收到Flowkey
的值为 x 的数据包时,草图中的每一行会使用独立的哈希函数 hi(.) 来将 x 映射到第 i 行的 A[i][hi(x)] 桶中,其中1 ≤ i ≤ d
。 - INT 报头:对于每个携带 INT 信息的数据包,它包含多个条目,每个条目都包含一个位图
Bitmap
和一系列要嵌入的状态States
。Bitmap
用于跟踪正在携带的那些状态。具体来说,Bitmap
使用等于要遥测的状态的数量的比特数进行初始化。如果在 INT 报头中嵌入了相应的状态,则Bitmap
中对应的比特等于 1,否则为 0。
- 草图数据结构:DeltaINT 中的每个节点都会维护一个草图,用于使用有限的有状态内存来跟踪每个流的嵌入状态。草图 A 是一个二维数组,由 d 行组成,每行有 w 个桶。每个桶中记录着流标识符
2.2 处理流程
2.2.1 伪代码解读
我们对网络中的某一台可编程交换机设备进行分析:
-
首先,当一个数据包到达时,该节点需要根据此数据包计算出对应的流键
Flowkey
,并获取该数据包对应的当前状态CurStates
。接着,节点根据Flowkey
将对应位置的嵌入状态从状态内存加载到EmbStates
中。同时将位图Bitmap
中的所有的比特初始化为 1 ,这意味着默认情况下将每个当前状态都要嵌入到 INT 报头中。 -
接着,DeltaINT 继续检查是否需要嵌入每个当前状态到该数据包中。如果某个状态的
EmbStates
存在,则 DeltaINT 会计算该状态的EmbStates
和CurStates
之间的增量。如果增量在预先设定的阈值内(也就是没有发生重大的状态变化),DeltaINT 会将位图Bitmap
中的相应比特设置为 0,表明不需要将当前状态嵌入到 INT 报头中。 -
然后,经过了上述计算操作,如果位图
Bitmap
中的比特为 1(即增量不可忽略并且需要嵌入当前状态到 INT 报头中)或者是哈希到的桶中没有存储当前计算的流键Flowkey
(例如当发生哈希冲突时,可能会覆盖对应的流键及嵌入状态),则 DeltaINT 会更新草图中所有哈希到的桶中的嵌入状态。 -
最后,DeltaINT 根据位图中的比特值将相应的当前状态嵌入到数据包 p 的 INT 报头中。
2.2.2 示例解读
下面这个示例中,草图 A 有 d = 2 行,每行有 w = 3 个桶。DeltaINT 负责跟踪两个状态,所设定的阈值分别为 0 和 2。两个流 x1 和 x2 的每个数据包是按照从上到下的顺序依次到达并进行处理的。
-
首先,DeltaINT 接收 x1 的第一个数据包,此时当前状态为 5 和 10。通过计算流键索引到两个哈希桶处,即A[1][1] 和 A[2][3]。由于没有哈希桶与 x1 匹配,因此 DeltaINT 直接将 <x1, 5, 10> 存储到这两个哈希桶中,同时将值为 <1, 1> 的位图和当前状态 <5, 10> 嵌入到数据包中。
-
接着,DeltaINT 接收 x2 的第一个数据包,此时当前状态为 6 和 15。通过计算索引到 A[1][1] 和 A[2][2] 这两个哈希桶处。DeltaINT 使用 <x2, 6, 15> 来更新对应的哈希桶(由于出现了哈希碰撞,因此 A[1][1] 原先存储的值将被新的值所覆盖),同时将值为 <1, 1> 的位图和当前状态 <6, 15> 嵌入到数据包中。
-
然后,DeltaINT 接收 x1 的第二个数据包,此时当前状态为 8 和 12。由于当前 A[1][1] 中存储的流键为 x2,因此DeltaINT 将从哈希桶 A[2][3] 中加载 5 和 10 的这两个嵌入状态,通过计算得出对应的增量分别为 3 和 2。请注意,第 2 个状态的变化增量是在阈值内的。因此,DeltaINT 使用 <x1, 8, 10> 来更新对应的哈希桶(即 A[1][1] 和 A[2][3]),并将值为 <1, 0> 的位图和第 1 个当前状态 8 嵌入到数据包中。
-
最后,DeltaINT 收到 x2 的第二个数据包,处理流程与上面类似。
3. 问题讨论和适用场景
3.1 设计中存在的问题讨论
-
哈希碰撞:如果接收到的数据包的
flowkey
与草图中的某个桶所记录的flowkey
不匹配,则 DeltaINT 可能会覆盖该桶所存储的值,但此类哈希冲突对 DeltaINT 的影响是有限的。如果某个流的数据包与任何桶中所记录的flowkey
都不匹配,则它们无法加载对应的嵌入状态以进行增量计算。在这种情况下,DeltaINT 必须嵌入所有的当前状态(即默认情况)并且无法减轻 INT 的带宽开销。为了减轻哈希冲突的影响,DeltaINT 可以在草图中分配更多行(即更大的 d 值),作者证明了至少存在一个桶还保存着某个流键的嵌入状态的可能性是随着 d 呈指数增长的。 -
增量阈值的敏感度:我们认为 DeltaINT 对增量阈值的选择并不敏感。对于保持不变的静态状态来说(例如设备 ID),可以将阈值设置为 0 来阻止这种静态状态的嵌入。而对于经常变化的动态状态来说(例如单跳时延),由于它们在大多数情况下的变化是有限的,因此可以设定相当小的阈值便足以避免将该状态嵌入到数据包中。
-
位图大小:DeltaINT 在转发路径中每个节点处都会将一个
Bitmap
嵌入到数据包中,但来自Bitmap
的额外 INT 带宽开销是有限的。其具体的带宽消耗情况要视带内网络遥测的应用场景而定。 -
数据包分片:由于 DeltaINT 减少了数据平面中的 INT 带宽,因此与原始 INT 相比,它更不容易引起 IP 分片。同时为了避免 IP 分片,DeltaINT 还可以配置更大的最大传输单元(MTU)大小或限制记录 INT 信息的每路径跳数(per-path hops)的最大数量。
3.2 适用的应用场景
这里仅给出作者在文章中提到的四个场景,具体如何将 DeltaINT 融入到这些场景/应用中请参见原文。
- Per-packet-per-node Monitoring
- Per-packet Aggregation
- Static per-flow aggregation
- Dynamic per-flow aggregation
4. 未来可能的改进方向
-
动态变化的阈值:能否在满足应用程序或场景的测量精度和需求的前提下,实时地对某些状态的阈值进行自适应的动态调整,使其能够进一步减少所消耗的数据平面带宽。
-
更加灵活的数据结构:对本文所提的草图数据结构进行更进一步的改进和优化,使其更好地服务于 DeltaINT 的运行逻辑。