0

0

Linux ftrace 的 ring buffer size 与 trace_pipe_raw 的低开销采集方式

冷炫風刃

冷炫風刃

发布时间:2026-02-14 20:41:27

|

557人浏览过

|

来源于php中文网

原创

trace_pipe_raw 更适合高吞吐采集,因其跳过内核格式化与字符串拼接,直接输出二进制事件流,避免 sprintf 级开销,cpu 占用低一个数量级,但需按事件边界原子读取并配合用户态解析工具。

linux ftrace 的 ring buffer size 与 trace_pipe_raw 的低开销采集方式

trace_pipe_raw 为什么比 trace_pipe 更适合高吞吐采集

因为 trace_pipe_raw 跳过了内核的格式化和字符串拼接,直接输出二进制事件流,避免了每条 trace 都触发 sprintf 级别的开销。在高频事件(如 sched_switchirq_handler_entry)场景下,trace_pipe 容易成为瓶颈,而 trace_pipe_raw 的 CPU 占用通常低一个数量级。

常见错误现象:cat /sys/kernel/tracing/trace_pipe 在压测时卡住或丢事件,但 cat /sys/kernel/tracing/trace_pipe_raw 仍能稳定读出数据;这是因为前者依赖 trace_event_printk,后者只做 memcpy + ring buffer copy。

  • 必须配合用户态解析工具(如 perf script -F 或自研 parser),不能直接 human-read
  • trace_pipe_raw 输出的是 per-CPU 二进制流,头部含 struct trace_entry 和 event-specific payload,无换行、无时间戳文本
  • 若用 ddhead -c 截断,可能切在事件中间,导致后续解析错位 —— 必须按完整事件边界读取

ring buffer size 设置不当会直接导致 trace_pipe_raw 丢事件

环形缓冲区大小不是“越大越好”,而是要匹配采集速率与消费速率的差值。默认的 buffer_size_kb(通常 1408 KB)在开启高频事件时几秒就满,一旦 buffer 满且 reader 没及时消费,新事件就会覆盖旧事件 —— trace_pipe_raw 不报错、不阻塞,只静默丢弃。

使用场景:监控 1000+ QPS 的系统调用入口(sys_enter),实测 buffer 需设为 8192 KB 以上才能撑过 30 秒采集窗口。

  • 设置方式:echo 8192 > /sys/kernel/tracing/buffer_size_kb(注意:单位是 KB,不是字节)
  • 该值对每个启用的 tracer(如 function_graph、event)独立生效,但 trace_pipe_raw 读取的是所有启用事件共用的主 buffer
  • 过大的 buffer 会占用不可交换的内核内存(kmalloc-backed),在内存紧张机器上可能触发 OOM killer
  • 可通过 cat /sys/kernel/tracing/buffer_total_size_kb 查看当前总占用(含 per-CPU 备份)

如何安全读取 trace_pipe_raw 并避免解析错位

直接 catdd bs=1 会破坏事件结构,必须按事件长度原子读取。Linux 内核在 trace_pipe_raw 中每个事件前写入 struct trace_entry(固定 12 字节),其中 size 字段标明整条事件长度(含 header)。

FineVoice语音克隆
FineVoice语音克隆

免费在线语音克隆,1 分钟克隆你的声音,保留口音和所有细微差别。

下载

示例关键逻辑(C 伪代码):

while (read(fd, &entry, sizeof(entry)) == sizeof(entry)) {
    int len = entry.size;
    uint8_t *buf = malloc(len);
    if (read(fd, buf, len) != len) break; // 必须一次读完
    parse_event(buf); // 自定义解析
    free(buf);
}
  • 不能用 stdio 缓冲(如 fread),必须用 read() 系统调用直通 fd
  • 务必检查每次 read() 返回值是否等于预期长度,否则说明 buffer 已被覆盖或 reader 落后太多
  • trace_pipe_raw 是阻塞式 fd,但 buffer 满时新事件会覆盖旧事件 —— 所以“阻塞”不等于“安全”,仍需监控丢弃计数
  • 丢弃计数路径:/sys/kernel/tracing/trace_buffer_overrun(全局)或 per-CPU 的 /sys/kernel/tracing/per_cpu/cpu*/trace_buffer_overrun

function graph tracer 开启后对 trace_pipe_raw 的影响

启用 function_graph 会显著增加 ring buffer 压力:每个函数进出各记一条事件,且 payload 更大(含 call depth、parent ip 等)。此时即使 buffer_size_kb 相同,trace_pipe_raw 的丢事件概率也会飙升。

性能影响:在 4GHz CPU 上,function_graph 可使单核额外增加 5–15% 的开销,远高于普通 event tracer;其二进制格式也更复杂(含 struct ftrace_graph_ent / struct ftrace_graph_ret 两种 header)。

  • 开启方式:echo function_graph > /sys/kernel/tracing/current_tracer,之后再 echo event 名到 set_event
  • 务必先调大 buffer(建议 ≥16384 KB),并优先关闭非必要函数(echo ':mod:ext4' > /sys/kernel/tracing/set_ftrace_filter
  • trace_pipe_raw 中的 function graph 事件无法用 perf script 直接解析,需用 kernel source 中的 scripts/ftrace/ftrace-to-dot.pl 或自研 parser
  • 如果只要函数调用关系图,不如用 perf record -e 'ftrace:function',它底层也走类似路径但封装了 buffer 管理

真正难的是平衡:buffer 太小,丢事件;太大,吃内存又拖慢系统;不用 trace_pipe_raw,开销压不住;用了,又得自己啃二进制格式和边界对齐。没人替你扛这些细节。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

531

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1552

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

640

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

885

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

836

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

185

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

89

2025.08.07

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

76

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 9.1万人学习

Git 教程
Git 教程

共21课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号