论文链接:https://ieeexplore.ieee.org/abstract/document/10355581
开源代码:无
0. 问题和关键见解
- 问题:大多数已有的草图方法都忽略了流优先级之间的区别,尽管高优先级的流相对稀少,但却蕴含着重要信息。因此,最近出现了一系列优先级感知草图的工作,旨在为不同优先级的流提供不同的测量精度。目前已有的优先级感知草图难以在准确性和吞吐量之间取得良好的平衡。
- 见解:根据流的优先级去分配不同数量的哈希函数:即为高优先级的流分配更多的哈希函数,以实现更高的测量精度;而为低优先级的流分配较少的哈希函数,以减少哈希操作的开销。
1. 已有工作和存在的问题
MC-Sketch 和 Cuckoo Sketch 都属于优先级感知的草图方案,它们相较于传统的草图方案来说,会考虑流的优先级,旨在为不同优先级的流提供不同的测量精度。
- MC-Sketch 的工作原理
MC-Sketch 的第一部分由顺序的优先级表所组成,表中的每个桶包含三个字段:流键(fid)、优先级(cid)和流大小(cnt)。对于到达的流 f5 来说,由于其优先级低于 f5 哈希到的桶中所存的现有流的优先级,因此 f5 必须在 Fine Part 中按顺序中被反复驱逐,直到最终到达 Coarse Part (即 CM Sketch)。
- Cuckoo Sketch 的工作原理
Cuckoo Sketch 会用高优先级流去替换低优先级流。例如,由于 f1 的优先级较低,即使它一开始就存储在桶中,也会被不断 kickout(踢出),以寻找一个空的条目。如果 f1 的 kickout 次数超过给定的 kickout 阈值,它将被驱逐到 CM Sketch 中。
综上来看,为了给高优先级的流提供更多保护,需要在 MC-sketch 中设置更多的优先级表,或是在 Cuckoo Sketch 中设置较大的 kickout 阈值。但是,低优先级的流必须通过 MC-Sketch 中更多的优先级表,或在 Cuckoo Sketch 中哈希到更多的桶中。对于当前服从 Zipf 分布的流量来说,低优先级流的数量远远多于高优先级流,这使得针对低优先级流的哈希运算量将变得巨大,从而导致吞吐量较低。因此,现有的优先级感知的草图方案很难在准确性和吞吐量之间取得良好的平衡,而且准确性和吞吐量是当前网络测量中两个相互正交的性能要求。
2. 框架设计和处理逻辑
2.1 框架设计
这篇文章设计了一种具有优先级感知哈希的双层结构,称之为 PA-Sketch。该数据结构由精度不同的两层组成。在高层,根据流的优先级为其分配不同数量的哈希函数。具体来说,通过给高优先级流分配更多的哈希函数,确保 PA-Sketch 即使在内存使用量较小的情况下,也能为其提供更低的 ARE 和更高的 F1 分数,这表明在识别高优先级流时会在精度和召回率之间进行权衡。对于低优先级流来说,PA-Sketch 则为其分配了少量的哈希函数,这些流可能还会被驱逐到低层,以便在可接受的误差范围内尽量减少哈希计算开销。
在上层 L1 中,B(1,j)
由三个字段组成:(i) B(1,j).id
存储潜在高优先级流的流键,它对应于映射到桶 B(1,j)
的所有流中优先级最高的那个流。(ii) B(1,j).pr
是潜在高优先级流的优先级。(iii) B(1,j).c
是一个计数器,记录着潜在高优先级流的数据包总数。上层 L1 与一组哈希函数 h(.) 相关联,其中所使用的 h(.) 的个数取决于到达流的优先级。下层 L0 的每个桶只有一个字段,该字段记录了在 L1 保存失败的那些流(从 L1 驱逐出来的流,也就是优先级比较低的)的数据包数量。L0 与 d 个哈希函数 g(.) 相关联。上述的所有哈希函数都是两两独立的。
2.2 处理流程
-
插入:最初,PA-Sketch 中的所有字段都设置为 0 或 null。当优先级为 p 的流 f 到达时,PA-Sketch 会使用优先级感知哈希来确定分配适当数量的哈希函数 k 给流 f ,然后将流 f 映射到 L1 层的 k 个桶中。具体来说,有四种可能的情况:
- 情况 1:如果 f 不在 B(1, hz(f)) (1 ≤ z ≤ k) 的任何存储桶中,并且这 k 个存储桶中至少有一个空的存储桶。那么 PA-Sketch 会将 f 插入到一个空的存储桶中,即把该存储桶的流键字段设为 f,优先级字段设为 p,计数字段设为 1。在图 4 中,由于 f6 未存储在 L1 中,且 B(1, h2(f6)) 为空,因此 PA-Sketch 将 < f6, 3, 1 > 插入到空的存储桶中。
图 4:插入到 L1 中的一个空的存储桶中 - 情况 2:如果 f 已存储在 L1 中的 B(1, hz(f)) (1 ≤ z ≤ k) 的某个存储桶中,PA-Sketch 会直接将 B(1, hz(f)).c 增加 1。如图 5 所示,当 f2 哈希到 L1 时,发现 B(1, h2(f2)).id 字段的值等于 f2,因此该存储桶的计数字段将直接增加 1。
图 5:已经存储在 L1 中并更新其计数 如果流 f 没有存储在 L1 中的任何存储桶中,且这 k 个存储桶都不是空的,则 PA-Sketch 将首先找到这 k 个哈希存储桶中优先级最低的存储桶。假设优先级最低的存储桶是 B(1, h1(f))。然后 PA-Sketch 将流 f 的优先级 p 与 B(1, h1(f)).pr 进行比较,根据比较的结果可进一步分为情况 3 和情况 4。
- 情况 3:如果 p ≤ B(1, h1(f)).pr,则表示流 f 无法记录到 L1 中,因此它将被驱逐到 L0,而 L0 则使用固定数量 (d 个) 的哈希函数。然后,PA-Sketch 会将 L0 中每个哈希到的存储桶的计数字段增加 1。如图 6 所示,由于 f7 的优先级为 2,小于 L1 中哈希桶所存的最低优先级,因此 f7 无法成功存储在 L1 中,它将被驱逐到 L0 中。因此,B(0, g1(f7)).c 和 B(0, g2(f7)).c 均递增 1。
图 6:因优先级比较低无法存在 L1 中 - 情况 4:如果 p > B(1, h1(f)).pr,PA-Sketch 会将 B(1, h1(f)).id 驱逐到 L0,并根据 B(1, h1(f)).c 的值去增加 L0 中的 d 个哈希到的存储桶的值。然后,通过将 B(1, h1(f)).id 设置为 f,将 B(1, h1(f)).pr 设置为 p,将 B(1, h1(f)).c 设置为 1,从而实现将 f 存储到 B(1, h1(f)) 中。在图 7 中,f8 替换了 L1 中的 f1,并将其驱逐到 L0。
图 7:因优先级比较高而驱逐已存在 L1 中的某个流 - 情况 1:如果 f 不在 B(1, hz(f)) (1 ≤ z ≤ k) 的任何存储桶中,并且这 k 个存储桶中至少有一个空的存储桶。那么 PA-Sketch 会将 f 插入到一个空的存储桶中,即把该存储桶的流键字段设为 f,优先级字段设为 p,计数字段设为 1。在图 4 中,由于 f6 未存储在 L1 中,且 B(1, h2(f6)) 为空,因此 PA-Sketch 将 < f6, 3, 1 > 插入到空的存储桶中。
-
查询:在查询流 f 时,PA-Sketch 首先使用 k 个哈希函数获得哈希到的存储桶 B(1, hz(f)) (1 ≤ z ≤ k)。然后,PA-Sketch 会检查在这 L1 中的 k 个哈希到的存储桶中,是否存在一个流键字段为 f 的存储桶(又称匹配桶)。如果答案是肯定的,PA-Sketch 会报告匹配桶的计数字段。否则,这意味着 L1 中没有匹配的桶。然后,PA-Sketch 会报告 L0 中 d 个哈希到的存储桶的最小计数,即 min{ B(0, gz(f)).c, z ∈ [1, d] } 。
3. 设计存在的问题讨论
-
问题:如何设计一个根据流的优先级去分配哈希函数个数的函数,既要做到为不同的流提供不同的服务,同时避免不必要的哈希开销?
-
方案:这篇文章使用线性函数
gen(p) = p
来做分配,也就是流优先级的大小便是分配哈希函数的个数,并且在后续的实验中证明了其实现了令人满意的性能。同时,如果优先级的数量很多的话,作者提出可以先对这么多优先级进行分组,再根据分组的情况去分配哈希函数的个数。
4. 未来可能的改进方向
- 降低哈希开销:作者认为优先级感知哈希技术仍有一定的局限性,比如在处理大量的具有优先级的流时,哈希开销会增加。因此,如何进一步降低哈希操作所带来的开销有待优化。
- 更广泛的数据集评估:这篇文章目前仅在网络流量和优先级服从倾斜分布的数据集上进行了评估,后续可以在不同类型的数据集上进行更广泛的测试。