【问题标题】:Determine the number of "logical" bytes read/written in a Linux system确定 Linux 系统中读/写的“逻辑”字节数
【发布时间】:2015-04-16 16:18:08
【问题描述】:

我想确定所有进程通过系统调用(例如read()write())读取/写入的字节数逻辑。这与实际从存储层获取的字节数不同(由 iotop 等工具显示),因为它包括(例如)命中页面缓存的读取,并且在识别写入时也不同:逻辑写入 IO 立即发生当发出write 调用时,实际的物理IO 可能会在一段时间后发生,具体取决于各种因素(Linux 通常会缓冲写入并在一段时间后执行物理IO)。

我知道如何在每个进程的基础上执行此操作(例如,请参阅 this question),但不知道如何获取系统范围的计数。

【问题讨论】:

    标签: linux performance io


    【解决方案1】:

    如果您想使用/proc 文件系统来计算总计数(而不是每秒计数),这很容易。

    这也适用于相当老的内核(在 Debian Squeeze 2.6.32 内核上测试)。

    # cat /proc/1979/io
    rchar: 111195372883082
    wchar: 10424431162257
    syscr: 130902776102
    syscw: 6236420365
    read_bytes: 2839822376960
    write_bytes: 803408183296
    cancelled_write_bytes: 374812672
    

    对于系统范围,只需将所有进程的数字相加,但这仅在短期内就足够了,因为随着进程死亡,它们的统计信息会从内存中删除。您需要启用进程记帐才能保存它们。

    这些文件的含义记录在内核源文件Documentation/filesystems/proc.txt

    rchar - I/O 计数器:读取的字符

    此任务导致的字节数 从存储中读取。这只是这个字节的总和 进程传递给 read() 和 pread()。它包括诸如 tty IO 之类的东西 并且它不受实际物理磁盘 IO 是否为 必需(可能已从页面缓存中满足读取)

    wchar - I/O 计数器:写入的字符

    此任务拥有的字节数 导致或将导致写入磁盘。类似的警告适用 这里和 rchar 一样。

    syscr - I/O 计数器:读取系统调用

    尝试计算读取 I/O 的数量 操作,即像 read() 和 pread() 这样的系统调用。

    syscw - I/O 计数器:写入系统调用

    尝试计算写入 I/O 的次数 操作,即像 write() 和 pwrite() 这样的系统调用。

    read_bytes - I/O 计数器:读取的字节数

    尝试计算字节数 这个过程确实导致从存储层获取。 在 submit_bio() 级别完成,因此对于块支持是准确的 文件系统。

    write_bytes - I/O 计数器:写入的字节数

    尝试计算字节数 这个过程导致被发送到存储层。这是在 页面弄脏时间。

    cancelled_write_bytes

    这里最大的不准确之处是截断。如果一个进程将 1MB 写入文件 然后删除文件,它实际上不会执行写出。但它 将被视为造成 1MB 的写入。其他 words:此过程导致不发生的字节数,由 截断页面缓存。任务也可能导致“负”IO。

    【讨论】:

    • 这些字段代表什么?我实际上对每个进程的编号感兴趣,所以如果它是逻辑 IO 那就太好了,但我找不到这些字段的含义。
    • 我已经添加了解释。前 2 个字段是来自进程的逻辑请求,无论它们是否导致磁盘 I/O。
    • 很抱歉,这是一个很好的答案,也是我一直在寻找的,但是 SO 的超级严格的赏金系统意味着我错过了将全部赏金分配给您的机会,因为我在到期时不在。所以我猜你必须对 25 次代表感到满意......
    【解决方案2】:

    这是一个跟踪逻辑 IO 的 SystemTap 脚本。它基于https://sourceware.org/systemtap/SystemTap_Beginners_Guide/traceiosect.html的脚本

    #! /usr/bin/env stap
    # traceio.stp
    # Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
    # Copyright (C) 2009 Kai Meyer <kai@unixlords.com>
    #   Fixed a bug that allows this to run longer
    #   And added the humanreadable function
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License version 2 as
    # published by the Free Software Foundation.
    #
    
    global reads, writes
    
    probe vfs.read.return {
      if ($return > 0) {
        reads += $return
      }
    }
    
    probe vfs.write.return {
      if ($return > 0) {
        writes += $return
      }
    }
    
    function humanreadable(bytes) {
      if (bytes > 1024*1024*1024) {
        return sprintf("%d GiB", bytes/1024/1024/1024)
      } else if (bytes > 1024*1024) {
        return sprintf("%d MiB", bytes/1024/1024)
      } else if (bytes > 1024) {
        return sprintf("%d KiB", bytes/1024)
      } else {
        return sprintf("%d   B", bytes)
      }
    }
    
    probe timer.s(1) {
      printf("reads: %12s writes: %12s\n", humanreadable(reads), humanreadable(writes))
      # Note we don't zero out reads and writes,
      # so the values are cumulative since the script started.
    }
    

    【讨论】:

    • 谢谢,但我不能在这个应用程序中使用 systemtap。我的首选方法是使用 /proc 文件系统。
    • @BeeOnRope 然后你可以查看system calls tracing。否则,您将需要制作一个内核模块,因为据我所知,没有办法从/proc 中检查聚合的read()write()
    猜你喜欢
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 2015-04-08
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多