背景
Dataway 的 /v1/aggregate 功能主要依赖 cliutils aggregate 包。梳理 dataway 接入路径后,cliutils 侧有几处需要优先处理的可靠性和资源消耗问题。
隐患 / Bug
-
Cache.GetExpWidows() 删除过期 bucket 后,外部会通过 WindowsToData() 无锁遍历 window.cache;同时 GetAndSetBucket() 在释放 Cache.lock 后仍可能拿着旧 *Windows 调 AddCal()。时间边界上存在旧 bucket 被继续写入、同时被遍历的风险,可能产生 data race 或 concurrent map iteration and map write。
-
WindowsToData() 在某个 window 的所有 calculator Aggr() 都失败时,仍会返回一个 PTS 为空的 PointsData。调用方如果默认非空,容易触发空 batch 下标 panic。stdev 单样本返回错误是一个可复现触发点。
-
newCalculators() 默认 AggregationBatch、batch.Points、AggregationAlgo 都非 nil。外部收到字段缺失但 protobuf 合法的 payload 时,当前路径容易 nil deref。建议在 cliutils 内部做防御式校验,避免把结构合法性完全交给调用方。
-
Window 通过 sync.Pool 获取,但过期窗口没有统一 reset/put 的释放路径,pool 当前基本没有复用价值;同时窗口内 map 可能长期保留高水位容量。
内存 / CPU 优化点
-
quantiles 当前保存全量样本并在每个 percentile 计算时排序,窗口大时内存 O(n),CPU 至少 O(n log n),多个 percentile 还会重复排序。建议改成一次排序后复用,或引入近似分位算法/可配置上限。
-
stdev 当前保存全量样本,实际可以用 Welford/在线方差算法维护 count、mean、M2,将内存降到 O(1)。
-
count_distinct 当前使用无界 map[any]struct{},高基数字段下内存不可控。建议提供最大 distinct 数保护,或引入近似 distinct 方案。
-
Window.Reset() 只清 map,不重置 calculator;如果后续要归还 pool,需要明确 calculator 生命周期,避免保留大 slice/map。
建议优先级
P0:修复过期窗口并发风险、空 PointsData 输出、nil payload 防御。
P1:补齐窗口对象释放/复用策略。
P2:优化 stdev、quantiles、count_distinct 的内存模型和 CPU 成本。
关联
dataway 侧对应 issue:https://gitlab.jiagouyun.com/cloudcare-tools/dataway/-/issues/71
背景
Dataway 的
/v1/aggregate功能主要依赖 cliutilsaggregate包。梳理 dataway 接入路径后,cliutils 侧有几处需要优先处理的可靠性和资源消耗问题。隐患 / Bug
Cache.GetExpWidows()删除过期 bucket 后,外部会通过WindowsToData()无锁遍历window.cache;同时GetAndSetBucket()在释放Cache.lock后仍可能拿着旧*Windows调AddCal()。时间边界上存在旧 bucket 被继续写入、同时被遍历的风险,可能产生 data race 或concurrent map iteration and map write。WindowsToData()在某个 window 的所有 calculatorAggr()都失败时,仍会返回一个PTS为空的PointsData。调用方如果默认非空,容易触发空 batch 下标 panic。stdev单样本返回错误是一个可复现触发点。newCalculators()默认AggregationBatch、batch.Points、AggregationAlgo都非 nil。外部收到字段缺失但 protobuf 合法的 payload 时,当前路径容易 nil deref。建议在 cliutils 内部做防御式校验,避免把结构合法性完全交给调用方。Window通过sync.Pool获取,但过期窗口没有统一 reset/put 的释放路径,pool 当前基本没有复用价值;同时窗口内 map 可能长期保留高水位容量。内存 / CPU 优化点
quantiles当前保存全量样本并在每个 percentile 计算时排序,窗口大时内存 O(n),CPU 至少 O(n log n),多个 percentile 还会重复排序。建议改成一次排序后复用,或引入近似分位算法/可配置上限。stdev当前保存全量样本,实际可以用 Welford/在线方差算法维护 count、mean、M2,将内存降到 O(1)。count_distinct当前使用无界map[any]struct{},高基数字段下内存不可控。建议提供最大 distinct 数保护,或引入近似 distinct 方案。Window.Reset()只清 map,不重置 calculator;如果后续要归还 pool,需要明确 calculator 生命周期,避免保留大 slice/map。建议优先级
P0:修复过期窗口并发风险、空
PointsData输出、nil payload 防御。P1:补齐窗口对象释放/复用策略。
P2:优化
stdev、quantiles、count_distinct的内存模型和 CPU 成本。关联
dataway 侧对应 issue:https://gitlab.jiagouyun.com/cloudcare-tools/dataway/-/issues/71