直方图统计延迟
用进入与返回两个探针配对:在入口记录当前时间戳,在返回时算出耗时,交给直方图函数按对数分桶统计。得到的是分布而不是平均值,长尾一眼可见。凡是关心「偶发很慢」而不是「平均多快」的场合,直方图都是首选形态。
基本信息
| 适用平台 | Linux,需要内核 eBPF 支持与相应权限 |
|---|---|
| 探针配对 | 入口探针记录时刻,返回探针计算差值 |
| 计时单位 | 纳秒时间戳,直方图函数按对数分桶 |
| 聚合键 | 常用线程号或进程号 |
| 程序形态 | 多行程序写成文件更清晰易维护 |
典型使用场景
- 统计内核函数或用户态函数的耗时分布,确认长尾。
- 评估读写路径延迟,判断是偶发还是整体抬高。
- 观察锁等待时长的分布形态,区别于正常的短等待。
- 优化前后对比同一函数的分布,验证长尾是否收敛。
- 与块层或网络的延迟分布对照,确认延迟来源在同一层。
函数耗时分布
函数耗时分布
bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }'
# 多行程序建议存成 .bt 文件后执行,便于维护与复用
bpftrace -e 'uprobe:/opt/app/bin/server:handle_request { @s[tid] = nsecs; }' # 先记录入口时刻
bpftrace -e 'kprobe:vfs_write { @bytes = hist(arg2); }' # 参数取值分布同样适用直方图读法
| 观察点 | 含义 | 判读要点 |
|---|---|---|
| 主体落在哪个桶 | 典型量级 | 与业务预期对比 |
| 桶的跨度 | 整体离散程度 | 跨度过大说明波动剧烈 |
| 高位桶是否有计数 | 长尾规模 | 决定优化是否值得做 |
| 双峰形态 | 两类路径混在一起 | 按线程或参数拆开再看 |
配对方式隐含假设:同一线程在记录与返回之间不会嵌套同类调用。存在重入时用线程号做键会互相覆盖,需要改用键值栈或者换用其它观测点。
忘记在返回探针里清理记录会造成映射变量无界增长,长时间运行后内存占用持续上升,最终影响被测系统。