ファイルシステム from 詳解システム・パフォーマンス
8章 ファイルシステム
初心者は読み書きのパフォーマンスを考えるときにファイルシステムとディスクをひとまとめで捉えがちだがこれが問題を生む
パフォーマンス面でファイルシステムとディスクを分けて捉えるのがこの節で大事なこと
cgroupへのファイルIOのキャップはバックグラウンドへのフラッシュに適用されないことがある
ファイルシステムへの命令と、実際のディスクへの書き込みはデフォルト非同期だと念頭に置くことが大事
writeはメモリへの書き込みでカーネルから帰ってくる
多分Direct IOはファイルへのIOのキャップが効くはず
ファイルシステムはプリフェッチ、あるいは先読み(readahead)という機能を用意している
前回のファイルIOのオフセットを記憶してファイルIOがシーケンシャルか判定し、そうであれば追加分を先に読みだしておく
明示的にウォームアップするにはreadahead(2)システムコールを呼ぶ
同期書き込みの方法は幾つかある
ファイルオープン時にO_SYNCを指定する
変種のO_DSYNC, O_RSYNCなども
ファイルシステムによってはマウント時に全て同期化するオプションもある
例によってワークロード分析のチェックリスト
基本的なもの
オペレーションの速さとタイプ
ファイルIOのスループット
ファイルIOのサイズ
読み書きの比率
同期書き込みの比率
問題となってるファイルに対してランダムアクセスしているかシーケンシャルアクセスをしているか
応用的なもの
結局これが一番重要に思えている
ファイルシステムキャッシュのヒット率、ミス率
ファイルシステムキャッシュの容量と現在の使用状況
ほかのキャッシュの統計
dentry, inode, buffer
ファイルシステムを使っているユーザとアプリの特定
アクセスされているファイルとディレクトリの特定
作成、削除などのオペレーションの違いも特定できるとよい
エラーが起きているか、それは無効な要求によるものか、ファイルシステムから発行されたものか
ファイルシステムを引き起こしているユーザレベルコールパス
ファイルシステムIOのうち同期的なものの割合
IOのレイテンシの分布
パフォーマンスモニタリング
平均値以外に最悪値や標準偏差がとれるといい
完全な分布が得られたらそれがベストだが負荷が掛かるので次善策として
マイクロベンチマーキング
パフォーマンス特性を把握するために
テストする要素にランダムアクセスが従う分布があるのが面白い
一様分布かパレート分布か
トレーサの使い方
システムコールのレイテンシ
1. 特定のシステムコール(場合によってはその変種も含める)のレイテンシの完全なヒストグラムを取得する
2. 自分の調査したいアプリのIOにいたるまでのスタックトレースを取得する
これであるアプリが同期的にIOしてるならそのレイテンシの影響を受ける
VFSインターフェースをトレーシングすればシステムコールより広い視野で観測できる
キャッシュのフラッシング
Linuxにはファイルシステムキャッシュをフラッシュする手段がある
Documentation/sysctl/vm.txt参照
同じインターフェースでdentry, inodeも消せる
マイクロベンチマーキングはfioがよさげ
この辺のツール群はほとんど古くなってしまっている
練習問題
O_SYNCではなくfsync()を使うメリットを説明しなさい
fsync()ならIOをグルーピングできるので、同期しつつ同時に書き込んでいいものはスループットを上げられる
read()/write()と比較したときのmmap()の利点、欠点を説明せよ
利点
ファイルアクセス時に小さな固定長のバッファを意識しないでプログラムできるので、プログラムを作る側から考えるとコードを書くのが楽。
同じファイルを複数のプロセスから読み出しアクセスする場合、ページが共有されるので効率が良い。
ファイルに長い時間アクセスする必要があり、アクセスパターンがランダムアクセスという場合は性能的な恩恵が受けられる可能性が高い。
欠点
複数プロセス間での共有、長期間に渡る使用、などの条件が重なればパフォーマンスが上がる
ランダムアクセスが多いときはmmapの方が単純に便利だったりする
バッファを意識せずすむのでアプリ開発者としてらくできる
SMP環境などにおいて、CPU間のMMUの同期をとるコストが大きくかかる
特に仮想空間のマッピングを削除するTLB shootdownが問題
論理IOが物理IOになると膨らむのはどういうときかしぼむときはどうか
膨らむとき
ファイルシステムメタデータ
ディスクのレコードサイズに収まらない値を書いて2つに分割されたり、逆に小さすぎて余る場合
レコードサイズという呼び名はあってるのか?
しぼむとき
ファイルキャッシュやtmpfsによるIOリクエスト削減
圧縮やde-duplication
ディスク書き込みをファイルシステムレベルでまとめてシーケンシャル書き込みにする
ファイルシステムのCOWがパフォーマンスを向上させる仕組み
ファイルコピー時に実際にディスクレベルで複製しないので高速
とおもったけどこれを実現するPOSIXシステムコールはないので、独自にやる必要があるらしい
これをファイルシステムでやってるのがDe-duplicationか
WindowsではこれをやるCopyFile()関数がOSから提供されている
データを更新する際にそれの更新後を新しい場所にコピーし、参照を切り替えることで更新する
「ランダムな書き込みをシーケンシャルにすることでパフォーマンスが改善する」と本書にあるが本当か?
これは書き込みがログのようにappend-onlyのアーキテクチャだと正しい言説になる
一方readはランダムのようになってしまうので、遅く成り得る(不定期にデフラグする手法はあり得る)
参照切り替えの前後でファイルシステムの状態がアトミックなのでSnapshotが高速にとれる
ファイルシステムキャッシュをチューニングするためのチェックリストを作成せよ
現在のファイルシステムキャッシュをリストアップし、サイズ、使用状況ヒット率をチェックする方法など
slabtopを使うとdentry, btrfs_inode, inode_cacheのオブジェクト数とアクティブ数(使用量)がとれる
各ファイルシステムのinodeとinode_cacheの違いは?
linuxカーネル内にinodeのキャッシュを扱うインターフェースがあって、その中でもっぱらファイルシステムごとに特殊化されたslabオブジェクトのアロケータが走る。btrfs_inodeなどはそれ。一方procfsなどの特殊化されてないものはinode_cacheが使われる。
inodeのヒット率も同様にしかるべきLinuxのキャッシュの取得関数を監視することでとれるはず...
ファイルシステムオペレーションワークロードの特性把握チェックリストと詳細情報の入手方法をまとめよ
時間が無かったのでまた今度