如何监控哪些文件消耗iops?

时间:2016-12-07 22:07:22

标签: linux profiling strace systemtap

我需要了解哪些文件占用了我硬盘的iops。只需使用" strace"不会解决我的问题。我想知道,哪些文件真正写入光盘,而不是页面缓存。我尝试使用" systemtap",但我无法理解如何找出哪些文件(文件名或inode)消耗我的iops。有什么工具可以解决我的问题吗?

2 个答案:

答案 0 :(得分:2)

是的,您绝对可以使用 SystemTap 进行追踪。当上层(通常是VFS子系统)想要发出I / O操作时,它将调用submit_biogeneric_make_request函数。请注意,这些并不意味着单个物理I / O操作。例如,来自相邻扇区的写入可以由I / O调度程序合并。

诀窍是如何在generic_make_request中确定文件路径名。读取非常简单,因为此函数将在与read()调用相同的上下文中调用。写入通常是异步的,因此write()将简单地更新页面缓存条目并将其标记为脏,而submit_bio由一个没有原始调用进程信息的回写内核线程调用:

可以通过查看page结构中的bio引用来推断写作 - 它具有mapping struct address_space。对应于打开文件的struct file还包含f_mapping,它指向同一个address_space实例,并且它还指向包含文件名称的dentry(这可以通过使用{{3}来完成}})

因此我们需要两个探测器:一个用于捕获读取/写入文件的尝试并将路径和address_space保存到关联数组中,另一个用于捕获generic_make_request个调用(这由探测器{{执行3}})。

这是一个计算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的更多信息,可以查看我的书:task_dentry_path

答案 1 :(得分:0)

也许iotop会给你一个关于哪个进程正在进行I / O的提示,因此你对相关文件有所了解。

iotop --only

--only选项用于仅查看实际执行I / O的进程或线程,而不是显示所有进程或线程