主要是针对WAN场景,利用eBPF实现了in-band主动被动测量。
performance = end hosts/data center servers + WAN性能
其中WAN性能一般需要主动测量。
现有的WAN性能异常用户态工具存在semantic gap
- suboptimal precision和high measurement overhead
- integration需要efforts
- 发送的流量会收到WAN的影响,但是测不出来
第一个工具:noobprobe。一个high-performance in-kernel and in-band active measurement tool。 有以下几个设计点
- in-band
- 和以前的libpcap对比
- resilient to the operational policies
- eBPF safe
- 依赖tc/cls-bpf和XDP,开销小
第二个工具:XDP-based passive flow collector
Motivation and Scope
一些点:
- 现有的工具completely oblivious to WAN path dynamics。但是routing changes,routing-induced delays,load balancing,link outages,queuing delays都会影响到应用的吞吐
- semantic gap:
- traceroute identified的路由路径不一定是同一条应用经过的路径
- 由ping等得到的latency measurements不一定是应用的延时
- 像可编程交换机这种,does not apply to WAN paths
总而言之,state-of-the-art measurement tools
- provide coarse-grained information such as latency and bandwidth, making applications unaware of transient network congestion at certain hops, load balancing issues, etc.;
- warrant changes to internal mechanisms of applications;
- are prone to operational policies (e.g., occasionally blocked, traffic shaping) of WAN providers.
ACTIVE MONITORING WITH NOOBPROBE
Design Approach: In-band Measurement
为了解决最先进的测量工具(在第 2 节中介绍)存在的缺陷,我们采用带内测量方法来设计 noobprobe。 这种方法的主要思路是向现有流量中注入数据包(探测器),使探测器具有相同的 5 元组(源/目的地址、协议和源/目的端口号),确保它们将遵循与应用流相同的路由器级路径,并绕过广域网运营商的操作和管理策略。
(核心想法:在用户态测延迟因为上下文切换及其他开销,测量结果不准确)。 需要注意的是,之前的工作侧重于测量应用流的特定路由器级路径,方法是在outgoing探针中设置 TTL,与跟踪路由方法和收集 ICMP 超时消息的方法类似。 虽然使用这些工具也能收集延迟测量值,但它们使用的是 libpcap 或类似方法,如 [36] 所示,由于内核和用户空间之间的上下文切换以及其他开销,可能会在探针发射过程中引入不希望出现的变化 [28]。(真的会有吗,我有一些怀疑) 同样,文献[11]中的方法需要用户/内核空间混合方法,这会给测量过程带来变异性和不必要的上下文切换开销。
我们的方法采用了 ELF [36] 的新方法:noobprobe 采用 eBPF 实现,因此其核心功能位于操作系统内核中,从而使探测和应用程序数据包在时间上间隔很近。因此,应用流量所体验到的性能(如延迟和损耗)很可能也会被探测器体验到--这是 noobprobe 的关键见解和特点,也是我们认为它非常适合解决应用网络惰性问题的原因。
noobprobe Implementation Details
noobprobe是基于bcc实现的。 给定要使用的网络接口、感兴趣的目标主机名和要运行的可选程序/应用程序,Python 控制程序就会使用 bcc 编译并安装 eBPF 程序,用于出口和入口数据包处理。出口处理和发送探测由 tc 子系统完成,入口处理由 XDP 完成。 此外还可以指定每跳/全局的最大探测速率。
有几个 BPF 映射用于跟踪互联网间的目的地、管理目的地信息并为测量提供临时存储。
- 其中一个映射将每个感兴趣的目标 IP 地址(v4 或
v6)与一个唯一的整数标识符关联起来;
- 该整数标识符被用作 BPF 结构数组的索引,每个结构数组都包含最近发送到给定目标的探针的纳秒时间戳、到目标的估计跳数(根据从目标接收到的数据包中的 TTL/ 跳数推断)、要使用的下一个探针序列以及到目标的下一跳探针。
- 此外,还存储了已收到 ICMP 超时信息的目的地跳数bit map。该位图用于检测无响应的跳数,避免重复探测这些跳数。
- 另一个 BPF map存储已发送但尚未收到响应的探测信息。
- 另一个map存储已收到的探测信息,包括时间戳、响应主机的 IP 地址、收到的 TTL/跳数等。
- 最后一个map是per CPU map,在收到探测响应时无需加锁来更新映射。
一共是这几个BPF program
- 初始程序检查数据包是否为 IP,然后跳转到处理 IPv4 或 IPv6 的单独程序。
- 在出口处,这些程序会在目的地 IP 地址 BPF
map中执行查找,并检查是否应向目的地发射探针,以满足配置的探针速率。
- 如果应该发出探测,与目的地相关的整数 BPF array index就会存储在 skb 元数据中,控制权就会移交给第三个程序。
- 第三个程序负责处理特定协议(ICMP、TCP、UDP)数据包操作。
- 在这第三个程序中,会查询 skb 元数据,以避免再次查找目标地址,并克隆和发送数据包。因此,原始应用数据包在确定应创建探针后很快就会被发送出去。克隆数据包的大小会被截断到最小长度(如 IPv4 TCP 的 40 字节),IP TTL/ 跳数也会被修改,以便在源点和目的地之间的每一跳之间循环。此外,还会重新计算校验和,记录序列号和纳秒级时间戳,并将其存储在另一张map上。
需要注意的是,在 tc 处理程序中调用的第一个程序会检查 skb 元数据是否已设置了目的地(整数)标识符;如果已设置,该数据包将被忽略,以避免重新克隆已被克隆的数据包。在 XDP 中,程序映射也以类似方式用于数据包入口,提供了一些代码模块化。
在网络中,ICMP 时间超限信息通常会在 TTL 过期的路由器接口上生成,这些信息会在入口(XDP)组件中接收 。此外,还要匹配序列和原始目的地,记录时间戳,并将数据添加到包含测量结果的每 CPU BPF map中。
对于与传出探针匹配的 ICMP 超时报文,默认情况下会在 XDP 处理路径中丢弃该报文,以免给主机带来额外的处理负荷。 这种行为(丢弃传入的 ICMP 超时报文)是可配置的;作为调试辅助工具,从其他程序中观察这些数据包可能会有所帮助。
此外,值得注意的是,与使用 libpcap 和类似方法相比,这种在测量流量进入操作系统网络协议栈之前就将其消除的能力是基于 eBPF 的测量的一个显著优势。 只要交给 Python 控制程序的应用程序继续运行,或直到中断,通往相关目的地的路径就会继续受到监控。Python 控制程序会定期从 BPF map中读取结果数据,并将这些数据添加到 CSV 文件中。
我们考虑过的另一种设计是直接在内核中实现,这在之前的工作中已有应用(如 [35])。 虽然这种方法由于避免了用户/内核边界交叉而降低了开销,但其实现将与特定的内核版本紧密耦合,从根本上说是不可移植的。 使用 libpcap 或类似软件的用户空间实现(参见 [11, 30])将是可移植的,但如 [36] 所示,即使数据包速率不大,性能成本也太高。 我们选择并倡导的 eBPF 方法在高性能与使用稳定且理论上可移植的 API2 实现之间取得了平衡。
EVALUATION
Internet Experiments
这边其实就是结合一些WAN场景,看看这个东西有什么用。
Data collection
we found no statistical differences between the NDT output with or without in-band monitoring
Evaluation of Hop-by-Hop Latencies
我们首先评论一下如何通过 noobprobe 揭示队列动态。 与 NDT 不同的是,fast.com 在吞吐量测试中使用了标准的多 TCP 流量最佳实践,使客户端与一组动态选择的 Netflix 边缘服务器之间的链路达到饱和。 在这次测试中,共创建了 5 个并行流;图中显示的是其中一个流的结果。 我们可以看到,在第 4 跳出现了大量的排队振荡(为了便于阅读,图中省略了一些跳),这表明网络路径上的这一点出现了拥塞。 有趣的是,第 3-5 跳都在同一提供商内,这表明这些流量的拥塞并不发生在提供商之间的边界,而先前的研究表明边界是网络拥塞的常见地点[17, 26]。 我们还观察到,在 13.5-14 秒时,跳 2 处出现了类似于 [36] 中图 2 中图的效果。
Load Balancing Effects
图 2 描述了大学客户端与加拿大温哥华 M-Lab 服务器之间的流量逐跳延迟,并捕捉了流量进行过程中域间路由变化的影响。我们观察到,在大约 12 秒时,第 7-9 跳的延迟发生了重大变化,第 6 跳的响应停止。我们还发现,在 12-13 秒之间生成的探测很少。由于探测是从应用程序生成的数据包中克隆出来的,因此我们推断,在路由发生变化时,应用程序流的发送速率出现了大幅下降(可能是 TCP 超时)。在我们收集的所有数据中,我们观察到大学客户端与加拿大温哥华 M-Lab 站点之间发生了 9 次域间路由变更。目前,遇到路由变更的应用程序可能只会观察到吞吐量、延迟或数据包丢失方面的一些变化,而对观察到的变化发生的原因一无所知。然而,有了像 noobprobe 这样的系统提供的信息,应用程序就有可能做出调整,避免或适当地应对障碍。
Observation of Route Changes
最后,由于带内流量测量能够识别单个流量所遵循的接口级路径,因此我们可以直接比较通往相同目的地的不均衡负载平衡路径可能导致的性能差异。图 3 显示了通过 NDT 测量的克莱姆森 CloudLab 客户端与德克萨斯州达拉斯沃斯堡 M-Lab 站点之间四条负载平衡路径的出站流量经验 CDF。图例中显示了确定遵循特定路径的测试实例数量,我们注意到每条路径的长度(以跳为单位)相同(8)。 从图中我们可以看到,两对路由的下载吞吐量相似(1/2 和 3/4),但路由 1 和 2 的性能经常比路由 3 和 4 低得多。我们还注意到,Kolmogorov-Smirnov 2 样本测试表明,必须拒绝 "1/2 和 3/4 路由的测量值来自同一分布 "的零假设。在研究其他负载平衡路径时(因篇幅限制未显示),我们发现,虽然不同负载平衡路径上的流量性能相似,但也有更多类似图 3 所示的性能差异巨大的实例。 在我们的数据中,我们观察到的许多负载平衡实例都是流量级负载平衡:同一流量的所有数据包都遵循相同的接口级路径。对于大多数客户和一个特定的目的地(荷兰阿姆斯特丹),我们观察到的接口级路径与每个数据包的负载平衡一致。但有趣的是,由于特定自治系统内跳数的变化,路由似乎也发生了根本性的变化。
PASSIVE MONITORING WITH NOOBFLOW
noobflow Implementation Overview
noobflow 包括两个部分:一个用户空间程序和一个基于 XDP 的内核/网络组件。用户空间部分使用 BPF 编译器库(bcc)[7] 实现,并充当内核组件的管理器。在我们的原型中,该组件由 Python 编写,可用于动态加载、配置和重新配置内核组件。在全系统的边缘云设置中,该组件将通过逻辑上集中的控制器进行配置。
用户空间组件创建per-CPU map,用于存储被动收集的网络流记录。 使用per-CPU map,noobflow 可以根据部署在边缘/云上的虚拟机的可用计算资源进行良好扩展。 可以动态重新配置捕获信息的流量,并存储标准流量信息,如源/目的 IP 和端口、接收的字节数和数据包数、时间戳等。 采用双缓冲方案,每个 CPU 有两个map;当一个map积累新到达的数据包时,另一个map中的数据可以被检索和清除。 用户空间程序会定期原子交换map角色,从而实现连续、无锁的流量收集。
Evaluation
没什么好看的了