7.4 KiB
新疆实验局:功能端处理100Gbps+流量,traffic skech相关接口单核占用超过30%
| ID | Creation Date | Assignee | Status |
|---|---|---|---|
| OMPUB-1339 | 2024-06-24T18:21:00.000+0800 | 陈子瞻 | 开放 |
CPU : Intel 6338
MEM: 1TB
Worker:47 cores
Traffic:110~120Gbps
[^traffic_sketch.perf.svg]
单核火焰图如下所示,整体占用已经接近100%,排名靠前的接口与heavy keeper相关
^!image-2024-06-24-18-18-50-191.png|width=610,height=379!^gitlab commented on 2024-10-14T14:40:33.159+0800:
[陈子瞻|https://git.mesalab.cn/chenzizhan] mentioned this issue in [a commit|d9e74a817f] of [TSG / tsg-os-buildimage|https://git.mesalab.cn/tsg/tsg-os-buildimage] on branch [fs4.6.7|https://git.mesalab.cn/tsg/tsg-os-buildimage/-/tree/fs4.6.7]:{quote}OMPUB-1339 fs4.6.7{quote}
gitlab commented on 2024-10-14T14:41:25.405+0800:
[陈子瞻|https://git.mesalab.cn/chenzizhan] mentioned this issue in [a merge request|https://git.mesalab.cn/tsg/tsg-os-buildimage/-/merge_requests/2760] of [TSG / tsg-os-buildimage|https://git.mesalab.cn/tsg/tsg-os-buildimage] on branch [fs4.6.7|https://git.mesalab.cn/tsg/tsg-os-buildimage/-/tree/fs4.6.7]:{quote}OMPUB-1339 fs4.6.7{quote}
chenzizhan commented on 2024-10-14T16:33:38.782+0800:
h2. 优化说明 h2. 版本
在环境中的是4.5.10 版本,本次性能优化仅在4.6.7 的更新版本中。在老版本上优化没有太大意义。把版本升级到24.10 以应用性能优化。 h2. h2. 分析 h3. 是否对一次操作的反复查找进行优化
注意到:“添加非primary 的metric,没有找到cell,然后添加一个新cell 成功“的cube 操作分支上有冗余的哈希查找操作,可以把这个分支上的3次HASH_FIND 调用优化,最激进可以优化到1次。
使用模拟生成的流量进行了测试,测试环境:192.168.40.40,使用版本:fieldstat4.6.5。分别统计了fieldstat topk cube 上操作的4个分支的总次数(所谓总次数,就是全部线程、全部cube、全部metric、全部cell 上的次数均在一起统计,使用全局变量实现)。
分别使用1500并发 2G 流量,1500并发 5G 流量和2700并发 2G 流量进行了测试。次数占比的定义是,操作满100万次后printf 打印运行情况,进入分支个数占统计个数总数的比值。
得到结果是:
"添加非primary 的metric, 并找到了cell" 分支: 在测试开始初期占比较少,之后迅速稳定到80%~87%之间,分别对应3000并发会话和1500并发会话。
"添加primary 的metric"分支: 占比17%左右
这两个分支占据了几乎全部的分支。添加非primary 的metric,且没有找到cell后,添加dummy cell{}成功{}占比在1%左右,而添加失败的分支则个数非常少,以至于在实验中没有发生过关于它的报警。
注意,此时TopK 的参数为K=1000,理论上,应当有更多的cell 作为小流量没有储存在heavy keeper中。我认为这是reset 的作用效果,它使得并发的流量个数还不足以在1秒内填满heavy keeper。然而,因为测试仪器的性能限制,这个流量大小已经是能测试的极限。但是,哪怕再增加流量大小,添加dummy cell 成功分支的占比只会更小,所以我们已经可以通过这样的情况估计:“添加非primary 的metric,且没有找到cell后,添加dummy cell{}成功{}”分支的占比很小,没必要对这一分支上的冗余调用做优化。
因为优化会影响函数的调用逻辑,让查找和分配接口的职责不清晰,而另一方面,涉及到的问题分支的占比很小。对代码美观和接口设计的负面影响大于对性能的提高,所以不进行优化。 h3. 是否开启uthash BLOOM filter 功能
按照讨论时的指标,在新疆实验局的流量中,并发会话数可达10万,而调用fieldstat_counter_incrby 的频率是固定每秒一次,和会话的流量几乎无关。那么,绝大多数调用时,在哈希表中查找时应该都是找不到,这说明似乎BLOOM FILTER 可以大大加速这个查找不到的分支,因为根据火焰图,必有一次的hash find 占据了相当大的比重。见下图的get_exdata 部分,这个函数代表了仅查找而不添加的情况的占比。
[^百分比.png]
[^0.svg]
然而,BLOOM filter 是不会被清空的,而且也不能被清空。因为在reset 的时候,heavy keeper 内的元素不是被从哈希表中删除,而是被设置为dying 状态,所以reset 也不是清除掉uthash table 中内置bloom filter sketch 的时机。一个越填越满的bloom filter 最终会失去效果,成为运行的负担。
因此,结论是不开启。
也许额外自己实现一个可删除的bloom filter?它涉及到对ut hash 内部函数的修改,工作量较大,且风险高。在运行时间较短,且流量并发数远大于cube容量的测试程序中开启了BLOOM_FILTER 宏,性能仅提高了7% 左右,衡量工作量和优化难度,决定不进行此优化。 h3. 是否解决重复运算哈希值的问题
因为XXhash 类运算占火焰图比重很低(只占7%左右),实际上多数分支上也只进行了一次哈希值运算,所以优化后的性能提升肯定还远小于7%。而为了优化这个问题,必将引入一个结构体,会破坏heavy keeper 和 spread sketch API定义的美观性,所以不进行优化。 h3. 瓶颈究竟在哪?
分析火焰图占比,heavy_keeper_add 函数缺乏可以优化的点,它单纯是完整的一个算法流程,多个函数均占有一定比重,没有明显的性能瓶颈。get0_exdata 接口本身就是一个HASH_FIND,提高它一次调用的性能无从下手,可是也许可以从降低其调用次数触发。
结合https://jira.geedge.net/browse/TSG-22728 中给出的指标,一个会话在调用节点,居然要针对同一个dimension,进行174次fieldstat_counter_incrby 调用,做同样的dimension拼接,同样的哈希值计算174次,这里才是影响性能的关键。这174次的组成是:
对于TOPK-METRIC:
对于24个cube的每个cube: 对于每个cube中的7个metric: 调用fieldstat_counter_incrby
DOS-SKETCH-METRIC:(同上)对2个cube,3个metric,调用6次。
h2. 方案 h3. 暂不修改struct field 定义
如果修改struct field 的定义方式,则可以把174次的拼接和哈希值计算缩减为1次。但是这个修改会直接不兼容的改变接口。而且,实际上,拼接tag 只占了火焰图的14.5%,似乎为了这14.5%的性能提升,完全修改接口调用方式也没有太大必要。 h3. 对一个cube 上的重复cell 查找做cache
至少,对同一个cube 上若干(在产品中是7次)次cell 的查找可以缩短为一次。在cube上添加了struct cached_cell,每次查找cell时,就先寻找是否是上一次传入的dimension,如果是,就直接使用上一次的cell指针(对于primary metric重新得到了新的cell指针的情况,会直接清空cache,同样的还有merge和reset等影响记录内容的操作)。
Attachments
63509/0.svg
59292/image-2024-06-24-18-18-50-191.png
59293/traffic_sketch.perf.svg
63508/百分比.png