【发布时间】:2016-12-07 22:07:21
【问题描述】:
我需要了解哪些文件消耗了我的硬盘的 iops。仅仅使用“strace”并不能解决我的问题。我想知道,哪些文件真正写入磁盘,而不是页面缓存。我尝试使用“systemtap”,但我不明白如何找出哪些文件(文件名或 inode)消耗了我的 iops。有什么工具可以解决我的问题吗?
【问题讨论】:
标签: linux profiling strace systemtap
我需要了解哪些文件消耗了我的硬盘的 iops。仅仅使用“strace”并不能解决我的问题。我想知道,哪些文件真正写入磁盘,而不是页面缓存。我尝试使用“systemtap”,但我不明白如何找出哪些文件(文件名或 inode)消耗了我的 iops。有什么工具可以解决我的问题吗?
【问题讨论】:
标签: linux profiling strace systemtap
是的,您绝对可以使用 SystemTap 进行跟踪。当上层(通常是 VFS 子系统)要发出 I/O 操作时,它会调用submit_bio 和generic_make_request 函数。请注意,这些并不一定意味着单个物理 I/O 操作。例如,来自相邻扇区的写入可以由 I/O 调度程序合并。
诀窍是如何确定generic_make_request 中的文件路径名。读取非常简单,因为此函数将在与read() 调用相同的上下文中调用。写入通常是异步的,因此write() 将简单地更新页面缓存条目并将其标记为脏,而submit_bio 被不具有原始调用进程信息的写回内核线程之一调用:
可以通过查看bio 结构中的page 引用来推断写入——它具有mapping 和struct address_space。对应于打开文件的struct file 也包含f_mapping,它指向同一个address_space 实例,它还指向包含文件名的dentry(这可以通过使用task_dentry_path 来完成)
所以我们需要两个探针:一个捕获读取/写入文件和保存路径的尝试,并将address_space 捕获到关联数组中,第二个捕获generic_make_request 调用(这是由探针ioblock.request 执行的)。
这是一个计算 IOPS 的示例脚本:
// maps struct address_space to path name
global paths;
// IOPS per file
global iops;
// Capture attempts to read and write by VFS
probe kernel.function("vfs_read"),
kernel.function("vfs_write") {
mapping = $file->f_mapping;
// Assemble full path name for running task (task_current())
// from open file "$file" of type "struct file"
path = task_dentry_path(task_current(), $file->f_path->dentry,
$file->f_path->mnt);
paths[mapping] = path;
}
// Attach to generic_make_request()
probe ioblock.request {
for (i = 0; i < $bio->bi_vcnt ; i++) {
// Each BIO request may have more than one page
// to write
page = $bio->bi_io_vec[i]->bv_page;
mapping = @cast(page, "struct page")->mapping;
iops[paths[mapping], rw] <<< 1;
}
}
// Once per second drain iops statistics
probe timer.s(1) {
println(ctime());
foreach([path+, rw] in iops) {
printf("%3d %s %s\n", @count(iops[path, rw]),
bio_rw_str(rw), path);
}
delete iops
}
此示例脚本适用于 XFS,但需要更新以支持 AIO 和卷管理器(包括 btrfs)。另外,我不确定它将如何处理元数据读取和写入,但这是一个好的开始;)
如果您想了解更多关于 SystemTap 的信息,可以查看我的书:http://myaut.github.io/dtrace-stap-book/kernel/async.html
【讨论】:
也许 iotop 会提示您哪个进程正在执行 I/O,因此您对相关文件有所了解。
iotop --only
--only 选项用于仅查看实际执行 I/O 的进程或线程,而不是显示所有进程或线程
【讨论】: