头部采样和尾部采样差在哪?采样率降到 1% 会丢掉多少出错的 trace?多个服务的采样决定不一致会怎样?尾部采样要付出什么代价?出错的 span 来晚了会怎么样?这篇用 OpenTelemetry SDK 和 Collector 的 tail_sampling 逐项量出来。
采样比例 | 保留的 trace 数 | 保留的 span 数 | 出错的 trace 保留 | 慢 trace 保留 | 正常 trace 保留 -----+-------------+------------+--------------+------------+------------ 100% | 3000 | 12000 | 49 / 49 | 95 / 95 | 2856 / 2856 10% | 271 | 1084 | 11 / 49 | 6 / 95 | 254 / 2856 1% | 31 | 124 | 0 / 49 | 0 / 95 | 31 / 2856 头部采样在 trace 开始时按 trace id 做决定,那时还不知道这个 trace 之后会不会出错、会不会变慢,所以出错和慢的 trace 和正常的 trace 以同样的比例被丢弃
在 trace 开始时按 trace id 决定,不知道之后的错误和耗时,出错和慢的 trace 同样被丢掉。
配置 | 后端收到至少 1 个 span 的 trace 数 | 收到 3 个 span 的(完整) | 收到 2 个 span 的 | 只收到 1 个 span 的 ---------------------------+---------------------------+-------------------+---------------+--------------- (a)A 按 10% 决定,B、C 跟随父 span | 291 | 291 | 0 | 0 (b)各自独立:A 10%、B 50%、C 100% | 3000 | 308 | 1173 | 1519 (c)各自独立,同一个比例 10% | 308 | 308 | 0 | 0 跟随父 span 的采样标志(或者所有服务使用同一个确定性比例)时,一个 trace 要么三个 span 都在,要么都不在;各服务用不同的比例独立决定,就会出现只有一部分 span 的残缺 trace
跟随父 span 的采样标志或者所有服务使用同一个确定性比例,trace 要么完整要么没有;不同比例各自独立会产生大量残缺 trace。
指标 | 尾部采样后 | 备注 ----------------------------+------------+--------------- 保留的 trace 数 | 288 | 全部 3000 出错的 trace | 49 / 49 | 慢 trace | 95 / 95 | 正常 trace | 144 / 2856 | 目标 5%(约 142 个) 保留下来的 trace 中 span 完整(4 个)的 | 288 / 288 | file exporter 文件大小(字节) | 399,817 | 全量 2,761,015 应用生成 3000 个 trace 花了 0.2 s;从应用 flush 完到 Collector 的采样输出文件第一次有内容用了 3.2 s(decision_wait 3 s);Collector 内存(RSS)在应用发完之后 185 MB
等 trace 到齐再决定,出错和慢的全留,存储量只有全量的一小部分,代价是延迟和 Collector 的内存。
出错的 span 比其他 span 晚发出 | 保留的 trace 数(共 100 个出错的) | 其中含出错 span 的 | 其中 4 个 span 都在的
----------------------+-------------------------+--------------+----------------
0.5 s | 100 | 100 | 100
4.0 s | 5 | 5 | 5
tail_sampling 在 decision_wait 到期时按当时收到的 span 做决定;出错 span 比 decision_wait 还晚到,决定时这个 trace 里还没有错误,出错的 trace 就按 5% 的概率保留
ERRORS {}span 晚于 decision_wait 到达时,决定已经做出,出错的 trace 可能被丢掉。