HackToTech

Hack To Technology

BPF本を読みながら学ぶ8

8章、 ファイルシステムについて

目次

用語

  • Read Ahead
    • シーケンシャルなアクセスを行う際に、次に読み込まれるページを先に読み込み、パフォーマンスを向上させる
    • readahead syscall
  • Write Back
    • ディスクによるI/Oで、アプリケーションをブロックしないように、バッファをメモリに書き込んで、カーネルのワーカースレッドによってディスクへフラッシュする

ファイルシステムのキャッシュ

  • ページキャッシュ
    • ファイルとI/Oバッファーの内容(バッファーキャッシュ)を含む仮想メモリページが含まれ、ファイルおよびディレクトリI/Oのパフォーマンスが向上する
  • inodeキャッシュ
    • ファイルに対しての権限チェックやその他のメタデータを頻繁に読み込むために使用する
  • ディレクトリキャッシュ
    • ディレクトリエントリ名からVFS inodeへのマッピングをキャッシュ、パス名によるルックアップのパフォーマンスを向上させる

ディスクのパフォーマンス分析

  1. ファイルシステムの特定をする df / mount
  2. ファイルシステムの容量を確認する ファイルシステム次第では使用量が100%に近づくにつれ、検索アルゴリズムによるパフォーマンスの問題が発生する
    1. ZFSは80%未満が良い
  3. fioを使ってアイドル状態のシステムで既知のファイルシステムのワークロードを再現する
  4. opensnoopを実行して開いているファイルを確認する
  5. filelifeを実行して、寿命の短いファイルを確認する
  6. 異常に遅いファイルシステムへのI/Oを特定する ext4slower / btrfsslower / zfsslower / fileslower
  7. ファイルシステムのレイテンシの分布を調べる ext4dist / btrfsdist / zfsdist
  8. ページキャッシュのヒット率を調べる cachestat
  9. 論理I/Oと物理I/Oのレートを比較する(基本的には論理I/O > 物理I/Oが高いことが望ましい) vfsstat
  10. bpftoolを実行する

df

ファイルシステムのディスクスペースの使用量を表示する

❯ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            3.9G     0  3.9G   0% /dev
tmpfs           796M  1.9M  794M   1% /run
/dev/sda1       290G  110G  167G  40% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/loop0       90M   90M     0 100% /snap/core/8213
/dev/loop1       11M   11M     0 100% /snap/kubectl/1357
/dev/loop2       90M   90M     0 100% /snap/core/8268
/dev/loop3       11M   11M     0 100% /snap/kubectl/1373
/dev/loop4      100M  100M     0 100% /snap/bpftrace/29
tmpfs           796M   20K  796M   1% /run/user/1000

mount

マウントされた全てのファイルシステムを表示する

❯ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=4045620k,nr_inodes=1011405,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=814152k,mode=755)
/dev/sda1 on / type ext4 (rw,relatime,errors=remount-ro)

fatrace

システム全体のファイルアクセスイベントを表示する
プロセス名(プロセスID): イベントタイプ ファイルパス

オプション

-t タイムスタンプの表示
-p PID 指定したプロセスを除外する

イベントタイプ

O Open
R Read
W Write
C Close
❯ sudo fatrace
chrome(4527): O /home/atrophy/.cache/google-chrome/Default/Cache/index-dir/temp-index
chrome(4527): CW /home/atrophy/.cache/google-chrome/Default/Cache/index-dir/temp-index
vmtoolsd(736): W /var/log/vmware-vmsvc-root.log
chrome(4471): CWO /home/atrophy/.config/google-chrome/Default/.com.google.Chrome.g1yHPA
chrome(4471): CWO /home/atrophy/.config/google-chrome/.com.google.Chrome.c6ba3F
chrome(4471): W /home/atrophy/.config/google-chrome/Default/.com.google.Chrome.g1yHPA
chrome(4471): CW /home/atrophy/.config/google-chrome/Local State
chrome(4471): CW /home/atrophy/.config/google-chrome/Default/Preferences
gnome-terminal-(3903): RCO /usr/share/icons/ubuntu-mono-dark/actions/16/window-close-symbolic.svg
gnome-terminal-(3903): R /usr/share/icons/ubuntu-mono-dark/actions/16/window-close-symbolic.svg
gnome-terminal-(3903): C /usr/share/icons/ubuntu-mono-dark/actions/16/window-close-symbolic.svg
gnome-terminal-(3903): O /usr/share/icons/Adwaita/scalable/actions/tab-new-symbolic.svg
gnome-terminal-(3903): RC /usr/share/icons/Adwaita/scalable/actions/tab-new-symbolic.svg
gnome-terminal-(3903): RO /usr/share/icons/Adwaita/scalable/actions/tab-new-symbolic.svg
gnome-terminal-(3903): C /usr/share/icons/Adwaita/scalable/actions/tab-new-symbolic.svg
gnome-terminal-(3903): RCO /usr/share/icons/Adwaita/scalable/actions/pan-down-symbolic.svg
gnome-terminal-(3903): C /usr/share/icons/Adwaita/scalable/actions/pan-down-symbolic.svg
pool(7940): RCO /etc/nsswitch.conf
pool(7940): CO /etc/ld.so.cache
pool(7940): RO /lib/x86_64-linux-gnu/libnss_compat-2.27.so
pool(7940): RO /lib/x86_64-linux-gnu/libnss_nis-2.27.so
pool(7940): RO /lib/x86_64-linux-gnu/libnsl-2.27.so
pool(7940): RO /lib/x86_64-linux-gnu/libnss_files-2.27.so
pool(7940): CO /etc/group
pool(7940): O /bin/bash
pool(7940): R /bin/bash
pool(7940): RO /lib/x86_64-linux-gnu/ld-2.27.so
bash(7940): C /lib/x86_64-linux-gnu/libnss_compat-2.27.so
bash(7940): C /lib/x86_64-linux-gnu/libnss_nis-2.27.so
bash(7940): C /lib/x86_64-linux-gnu/libnsl-2.27.so
bash(7940): C /lib/x86_64-linux-gnu/libnss_files-2.27.so

statsnoop

stat() syscallをトレースし、どのプロセスがどのファイルに関する情報を読み取ろうとしているかを表示する

オプション

-x 失敗した統計のみ表示
-t タイムスタンプの表示
-p PID 指定したプロセスのみ表示

フィールド

TIME 呼び出し時間(秒単位)
PID プロセスID
COMM プロセス名
FD ファイルディスクリプタ(失敗時は-1)
ERR Error number(errno.h)
PATH 開いたパス
❯ sudo /usr/share/bcc/tools/statsnoop -t
TIME(s)       PID    COMM               FD ERR PATH
0.000000000   736    vmtoolsd            0   0 /etc/vmware-tools/tools.conf
0.000445262   13535  statsnoop          -1   2 /usr/lib/python2.7/encodings/ascii
1.975937867   3583   vmtoolsd            0   0 /etc/vmware-tools/tools.conf
5.000724336   736    vmtoolsd            0   0 /etc/vmware-tools/tools.conf
6.743327313   13310  ThreadPoolForeg     0   0 /etc/resolv.conf
6.743624226   729    systemd-resolve     0   0 /etc/hosts
6.743682672   729    systemd-resolve     0   0 /etc/resolv.conf
6.743698833   729    systemd-resolve     0   0 /etc/resolv.conf
6.977109934   3583   vmtoolsd            0   0 /etc/vmware-tools/tools.conf
10.002457003  736    vmtoolsd            0   0 /etc/vmware-tools/tools.conf

syncsnoop

ファイルシステムバッファをストレージデバイスにフラッシュするsync() syscallをトレースする

フィールド

TIME(s) 呼び出し時間(秒単位)
CALL 呼び出しのトレース
❯ sudo /usr/share/bcc/tools/syncsnoop
TIME(s)            CALL
23751.034417000    sync()
23751.770298000    sync()
23752.147148000    sync()
23752.378717000    sync()
23755.794625000    sync()
23759.138742000    sync()

filelife

ファイルの作成と削除をトレースし、ファイルを削除したユーザー、ファイルの経過時間、ファイル名に関する情報を表示する

オプション

-p PID 指定したプロセスのみ表示

フィールド

TIME 削除された時刻
PID ファイルを削除したプロセスID
COMM プロセス名
AGE(s) 作成されてから削除されるまでの時間(秒単位)
FILE ファイル名
❯ sudo /usr/share/bcc/tools/filelife 
TIME     PID    COMM             AGE(s)  FILE
00:09:36 16063  bash             0.00    sh-thd.aglEmZ
00:09:36 18969  rm               4.36    hoge
00:09:45 18610  anacron          0.00    fileNpHdSz
00:09:45 495    systemd-udevd    0.00    queue
00:09:45 495    systemd-udevd    0.00    queue
00:09:45 495    systemd-udevd    0.00    queue
00:09:45 495    systemd-udevd    0.00    queue
00:09:45 19187  gpg              0.00    .#lk0x000055fe6b0679f0.ubuntu.19
00:09:45 19187  gpg              0.00    .#lk0x000055fe6b066f70.ubuntu.19
00:09:45 495    systemd-udevd    0.00    queue
00:09:45 19191  gpg              0.00    .#lk0x000055ebc43c8e70.ubuntu.19
00:09:45 19253  rm               0.05    trustdb.gpg
00:09:45 19253  rm               0.05    pubring.kbx
00:09:45 19253  rm               0.05    pubring.gpg

vfscount

VFS呼び出しをカウントする
VFSへの操作の一般的なワークロードの特性評価に役立つ

フィールド

ADDR トレースされた命令ポインタ(instruction pointer)のアドレス
FUNC カーネルのファンクション名
COUNT トレース中に呼び出された回数
❯ sudo /usr/share/bcc/tools/vfscount 10
Tracing... Ctrl-C to end.

ADDR             FUNC                          COUNT
ffffffffa7af28f1 vfs_statfs                        1
ffffffffa7ac5b01 vfs_unlink                        3
ffffffffa7aefd91 vfs_fsync_range                   5
ffffffffa7ac4651 vfs_rmdir                         7
ffffffffa7b1df91 vfs_lock_file                    24
ffffffffa7acb121 vfs_readlink                     49
ffffffffa7ab7a11 vfs_write                       274
ffffffffa7abc3d1 vfs_statx                       299
ffffffffa7ab5de1 vfs_writev                      325
ffffffffa7ab7751 vfs_read                        365
ffffffffa7abc351 vfs_statx_fd                    868
ffffffffa7ab3541 vfs_open                       1100
ffffffffa7abc311 vfs_getattr                    1133
ffffffffa7abc281 vfs_getattr_nosec              1139

fileslower

VFSインターフェイスで同期読み取りおよび書き込みをカーネルの動的トレースを使用して、
ファイルシステムへの遅いファイル読み込みと書き込みを見分ける

フィールド

TIME(s) 最初のI/Oが開始してからI/Oが完了するまでにかかった時間(秒単位)
COMM プロセス名
PID プロセスID
D I/Oの方向
R(Read)
W(write)
BYTES I/Oのサイズ
LAT(ms) I/Oのlatency
FILENAME キャッシュされたカーネルのファイル名(dentry->d_iname)
❯ sudo /usr/share/bcc/tools/fileslower 
Tracing sync read/writes slower than 10 ms
TIME(s)  COMM           TID    D BYTES   LAT(ms) FILENAME
26.288   dd             21861  W 1048576   10.30 swapfile
26.979   dd             21861  W 1048576   11.35 swapfile
28.525   dd             21861  W 1048576   38.75 swapfile
28.622   dd             21861  W 1048576   11.50 swapfile
28.644   dd             21861  W 1048576   12.38 swapfile
28.682   dd             21861  W 1048576   30.95 swapfile
28.698   dd             21861  W 1048576   15.74 swapfile
28.720   dd             21861  W 1048576   19.20 swapfile

filetop

プロセスとファイル名による読み込みと書き込み
Topコマンドのファイル版

オプション

-a 通常ファイル以外のファイルタイプも含める(sockets, FIFOs, etc)
-p PID 指定したプロセスのみ表示

フィールド

loadavg /proc/loadavgの内容
TID スレッドID
COMM プロセス名
READS インターバル中の読み込み回数
WRITES インターバル中の書き込み回数
R_Kb インターバル中の読み込み(Kbytes)の合計
W_Kb インターバル中の書き込み(Kbytes)の合計
T ファイルのタイプ
R(Regular)
S(Socket)
O(Other(pipe, etc))
❯ sudo /usr/share/bcc/tools/filetop -a

01:10:17 loadavg: 0.05 0.11 0.07 1/725 22487

TID    COMM             READS  WRITES R_Kb    W_Kb    T FILE
3903   gnome-terminal-  8      1      62      0       O ptmx
1707   InputThread      8      0      56      0       O event1
22487  clear            2      0      8       0       R xterm-256color
3404   gmain            2      0      8       0       O inotify
22484  filetop          2      0      2       0       R loadavg
22487  clear            1      0      0       0       R libtinfo.so.5.9
22487  clear            1      0      0       0       R libc-2.27.so
22487  filetop          3      0      0       0       R clear
22487  filetop          2      0      0       0       R ld-2.27.so
3188   gdbus            12     28     0       0       O [eventfd]
3279   gdbus            6      10     0       0       O [eventfd]
3903   gnome-terminal-  7      8      0       0       O [eventfd]
3312   gnome-shell      6      8      0       0       O [eventfd]
3905   gdbus            6      8      0       0       O [eventfd]
3180   ibus-daemon      8      4      0       0       O [eventfd]
1127   acpid            6      0      0       0       O event1
22484  filetop          0      3      0       0       O 0
3404   gmain            2      6      0       0       O [eventfd]
3275   ibus-engine-sim  2      2      0       0       O [eventfd]
3903   gnome-terminal-  0      2      0       0       O [eventfd]

dcstat

ディレクトリエントリキャッシュ(dcache)の統計

フィールド

TIME タイムスタンプ
REFS/s dcacheのルックアップ数(秒間)
SLOW/s lookup_fast()に失敗し、
代わりにlookup_slow()を実行したdcacheのルックアップ数(秒間)
MISS/s ミス数(lookup_fast/lookup_slowの両方に失敗した場合)
HIT% dcacheのヒット率
❯ sudo /usr/share/bcc/tools/dcstat
TIME         REFS/s   SLOW/s   MISS/s     HIT%
01:21:12:        36        0        0   100.00
01:21:13:         8        0        0   100.00
01:21:14:        66        0        0   100.00
01:21:15:       404        0        0   100.00
01:21:16:        13        0        0   100.00
01:21:17:        40        0        0   100.00
01:21:18:        63        1        0   100.00
01:21:19:        23        0        0   100.00
01:21:20:      7218       72       63    99.13
01:21:21:         8        0        0   100.00

dcsnoop

ディレクトリエントリキャッシュ(dcache)ルックアップをトレースする

オプション

-a 失敗したルックアップだけでなく、参照もトレースに含める

フィールド

TIME(s) ルックアップした時間(秒単位)
PID プロセスID
COMM プロセス名
T タイプ
R(Reference) -aオプションの場合のみ表示
M(Miss)
FILE ルックアップしていたファイル名コンポーネント
❯ sudo /usr/share/bcc/tools/dcsnoop -a
TIME(s)     PID    COMM             T FILE
0.097416    3481   gsd-color        R etc/localtime
0.097488    3481   gsd-color        R localtime
0.097515    3481   gsd-color        R usr/share/zoneinfo/Asia/Tokyo
# 省略
0.097779    23215  dcsnoop          R usr/lib/python2.7/encodings/ascii
0.097786    23215  dcsnoop          R lib/python2.7/encodings/ascii
0.097809    23215  dcsnoop          R python2.7/encodings/ascii
# 省略
0.753587    1175   gmain            R extrausers
0.753599    1211   gmain            R etc/NetworkManager/VPN
0.753622    1211   gmain            R NetworkManager/VPN
0.753634    1211   gmain            R VPN
# 省略
4.666200    23163  ThreadPoolForeg  M .com.google.Chrome.LWOyo3

mountsnoop

mount() および umount() syscallをトレースする

COMM プロセス名
PID プロセスID
TID スレッドID
MNT_NS マウントしているnamespaceのinode number
CALL syscall、引数、戻り値
❯ sudo /usr/share/bcc/tools/mountsnoop 
COMM             PID     TID     MNT_NS      CALL
dockerd          1329    2575    4026531840  mount("overlay", "/var/lib/docker/overlay2/f606e18c5811d17fbe31ae16d76af01a3a1c77f6e72c031137d98499c79d3ebb-init/merged", "overlay", MS_NOSUID|MS_NOEXEC|MS_REMOUNT|MS_MANDLOCK|MS_MOVE|MS_REC|MS_SILENT|MS_POSIXACL|MS_UNBINDABLE|MS_PRIVATE|MS_LAZYTIME|MS_NOUSER|0x564510000200, "") = 0
dockerd          1329    1714    4026531840  mount("overlay", "/var/lib/docker/overlay2/b9dc1b32c519d1567f91049d638141703d05795dedd49d371628d8a6c3d4ed30-init/merged", "overlay", MS_NOSUID|MS_NOEXEC|MS_REMOUNT|MS_MANDLOCK|MS_MOVE|MS_REC|MS_SILENT|MS_POSIXACL|MS_UNBINDABLE|MS_PRIVATE|MS_LAZYTIME|MS_NOUSER|0x564510000200, "") = 0
dockerd          1329    1673    4026531840  mount("overlay", "/var/lib/docker/overlay2/accc5ace809c7b6f253c0ba6aabea824b16555b78b482687a3fc4bd95fd8c1f8-init/merged", "overlay", MS_NOSUID|MS_NOEXEC|MS_REMOUNT|MS_MANDLOCK|MS_MOVE|MS_REC|MS_SILENT|MS_POSIXACL|MS_UNBINDABLE|MS_PRIVATE|MS_LAZYTIME|MS_NOUSER|0x564510000200, "") = 0
dockerd          1329    1563    4026531840  mount("overlay", "/var/lib/docker/overlay2/5c2f7a8d49bfc977691083b40801307c929632baa9de64acbeb1acc26d0016b7-init/merged", "overlay", MS_NOSUID|MS_NOEXEC|MS_REMOUNT|MS_MANDLOCK|MS_MOVE|MS_REC|MS_SILENT|MS_POSIXACL|MS_UNBINDABLE|MS_PRIVATE|MS_LAZYTIME|MS_NOUSER|0x564510000200, "") = 0
dockerd          1329    1563    4026531840  umount("/var/lib/docker/overlay2/5c2f7a8d49bfc977691083b40801307c929632baa9de64acbeb1acc26d0016b7-init/merged", MNT_DETACH) = 0
dockerd          1329    2575    4026531840  umount("/var/lib/docker/overlay2/f606e18c5811d17fbe31ae16d76af01a3a1c77f6e72c031137d98499c79d3ebb-init/merged", MNT_DETACH) = 0
dockerd          1329    1673    4026531840  umount("/var/lib/docker/overlay2/accc5ace809c7b6f253c0ba6aabea824b16555b78b482687a3fc4bd95fd8c1f8-init/merged", MNT_DETACH) = 0
dockerd          1329    1714    4026531840  umount("/var/lib/docker/overlay2/b9dc1b32c519d1567f91049d638141703d05795dedd49d371628d8a6c3d4ed30-init/merged", MNT_DETACH) = 0
dockerd          1329    2575    4026531840  mount("overlay", "/var/lib/docker/overlay2/f606e18c5811d17fbe31ae16d76af01a3a1c77f6e72c031137d98499c79d3ebb/merged", "overlay", MS_NOSUID|MS_NOEXEC|MS_REMOUNT|MS_MANDLOCK|MS_MOVE|MS_REC|MS_SILENT|MS_POSIXACL|MS_UNBINDABLE|MS_PRIVATE|MS_LAZYTIME|MS_NOUSER|0x564510000200, "") = 0

ext4dist

ext4操作のレイテンシを要約する

フィールド

usecs マイクロ秒の範囲
count 範囲内のオペレーションの回数
distribution カウントの分布
❯ sudo /usr/share/bcc/tools/ext4dist
Tracing ext4 operation latency... Hit Ctrl-C to end.

operation = read
     usecs               : count     distribution
         0 -> 1          : 290      |****************************************|
         2 -> 3          : 11       |*                                       |
         4 -> 7          : 3        |                                        |
         8 -> 15         : 4        |                                        |
        16 -> 31         : 1        |                                        |

operation = write
     usecs               : count     distribution
         0 -> 1          : 1        |****************************************|
         2 -> 3          : 0        |                                        |
         4 -> 7          : 0        |                                        |
         8 -> 15         : 1        |****************************************|

operation = open
     usecs               : count     distribution
         0 -> 1          : 175      |****************************************|
         2 -> 3          : 5        |*                                       |
         4 -> 7          : 0        |                                        |
         8 -> 15         : 1        |                                        |