这篇文章提出了一个用梗概(sketch)来测量数据流的延迟的方法. 为测量数据流的延迟, 我们首先需要确定一个场景, 就是我们有两个网络节点A和B, 数据流有 个数据包, 每个数据包经过这两个节点都会经历一个延迟, 而我们需要测量的是这 个数据包所经历的延迟的平均值. 这里的A和B两个节点可以定义成为任意网络节点, 而不一定是数据包的发送方和接收方, 也不一定是一个网络的入口和出口. 此外, 我们假设网络节点有现成的方案来分辨我们需要测量的数据包, 即如果网络节点B能够分辨出没有经过网络节点A的数据包, 因此不会对它们进行测量. 最后, 我们假设网络节点A和B的时钟是同步的, 因此我们可以用数据包经过B时候的时间戳和经过A时候的时间戳的差来表示数据包的延迟.
这篇文章实际上提出了两个不同的方案来测量流级别的网络延迟. 第一种方案假设数据包携带了它到达网络节点A时候的时间戳, 但是修改数据包并使其携带一个时间戳在很多情况下并不可行, 所以本文提出了第二种方案, 这种方案不要求数据包携带时间戳. 以下我们将对这两个方案进行简要的介绍.
Simple Delay Sketch (SDS)
我们维护了
个哈希表, 每个哈希表对应于一个不同的哈希函数. 这些哈希表中, 每个哈希桶都包含两个域
和
. 当一个数据包到达网络节点A的时候, 它就会把当前时间以时间戳的形式写入数据包. 之后, 数据包到达B的时候, B就会将这个时间戳提取出来, 并用当前时间减去这个时间戳来获取一个数据包的传输延迟
. 接着, B将数据包的流标识符依次映射到这
个哈希表中. 对于每一个这个数据包映射到哈希桶, 我们都进行如下操作:
如下图所示.
最后, 当我们要估计一个数据流的延迟的时候, 我们将这个数据流的流标识符分别映射到这
个哈希表, 这样我们就会得到
个不同的哈希桶. 在这些哈希桶中, 我们选取
的值最小的哈希桶, 并使用
的方式来计算当前数据流的延迟, 具体的算法流程可见下图. 这里我们选取
的值最小的哈希桶, 是因为这个哈希桶中当前数据流所占的权值最高, 所以一般情况下这个值最接近当前数据流的传输延迟.
Lossy Difference Sketch (LDS)
如前所述, SDS要求每个数据包都必须携带它经过节点A时候的时间戳, 但是这在很多场景下是不可行的, 因此文章提出了一个改进的方案 LDS. 和SDS类似, 在LDS中我们也维护了
个哈希表, 每个哈希表都包含
个哈希桶. 当一个数据包到达的时候, 我们也会将它的流标识符映射到每个哈希表, 但是和
不同的是, 我们在节点A和B上分别维护了一个这样的数据结构, 且A和B的数据结构的大小(包括
和
)相同. 当数据包到达A的时候, 我们将它映射到每个哈希表. 假设当前的时间戳为
, 则我们对哈希桶的更新方式如下:
即
记录的是数据包到达时刻的时间戳之和, 而不是数据包的传输延迟之和. 我们在网络节点B上的操作也是类似的.
当一个测量周期结束的时候, 网络节点A会将它的数据结构传给B, B计算对应的哈希桶的 值的差值, 并将这个差值除以 的值获得的结果作为对数据流的延迟的估计. 但是这里马上就会有一个问题, 那就是由于丢包的存在, A的哈希表和B的哈希表中对应的哈希桶的 值可能不一致. 为解决这一问题, 本文采取的方法是, 当 的值不相等的时候, 我们就放弃这个哈希桶, 即不对这个哈希桶所对应的数据流的传输延迟进行估计.
以上方法存在的另一个问题是, 即使对应的哈希桶的 值相同, 它们实际测量的数据包也可能会有一定的差异, 比如B记录了上一个测量周期的最后若干个数据包 (A并没有记录这些数据包), 而没有记录这个测量周期的最后若干个数据包 (A已经记录了这些数据包), 但是A和B的哈希桶的 值却是相等的. 为了避免这种情况, 我们在每个哈希桶中加入了另一个域 . 当A或B记录一个数据包的时候, 我们会把将这个数据包 (包括有效载荷) 生成一个固定长度的摘要, 并将这个摘要异或到这个哈希桶的 域中. 最后, 在对一个数据流的延迟进行估计的时候, 我们会比较A的哈希桶和B的哈希桶的 域. 如果它们的 域不相同, 则我们也不会对这个哈希桶对应的数据流的延迟进行估计. 假设 域长度为 , 则A和B的哈希桶的不一致性不被检出的概率仅为 .
为了使对数据流传输延迟的估计更具有鲁棒性, 在这篇文章中我们还提出了一个小技巧, 即在同一个哈希表中, 我们将一个数据流映射到
个不同的哈希桶中, 因此最后即使有部分哈希桶因为丢包或者维护数据包的不一致性而失效, 我们也能够为数据流估计一个相对准确地传输延迟. 具体做法是, 当我们把数据包映射到一个哈希表的时候, 我们首先使用一个哈希函数
对数据包 (包括有效载荷进行处理), 得到一个索引值
, 之后再使用和这个哈希表关联的哈希函数
对这个数据包的流标识符进行处理, 得到另一个索引值
. 最后我们再更新这个哈希表中索引为
的哈希桶如下:
其中
是数据包到达时候的网络节点的当前时间. 对数据结构的具体更新过程可见下图.
当需要对一个数据流的传输延迟进行估计的时候, 在剔除了存在丢包和维护数据包不一致性的哈希桶以后, 我们得到了
个哈希桶. 我们找出这
个哈希桶中最小的
值, 记为
. 之后我们在这
个哈希桶中找出所有
值小于等于
的哈希桶, 并将它们的
值和
值分别相加, 得到
和
, 其中文章所给出的
的经验值为0.1. 最后我们对这个数据流的传输延迟的估计值为
. 以上所述方法的具体算法描述可见下图, 其中我认为
的取值应该为
.