LeavaTailの日記

LeavaTailの日記

Linuxエンジニアを目指した技術者の備忘録

ファイルシステムの違いによるストレージへの書き込み特性を比較する

注意

本記事は、特定の環境下における特定の書き込みパターンを測定した結果であり、ファイルシステムの優劣を決めるものではない。

概要

本記事では、eBPF と fio を用いて、次のようなストレージへの書き込み特性について確認した。

  • IO要求の発行回数
  • 書き込み総量
  • 書き込み頻度とオフセット

Linuxファイルシステム (ext4, xfs, nilfs2, f2fs, exfat, btrfs, jfs) 毎にどのような特性があるかをまとめた。

はじめに

フラッシュメモリは、ハードディスクといったストレージデバイスと比較して、アクセス速度や省電力が優れている。 そのため近年、SDメモリカードSSDといったフラッシュメモリを搭載したストレージデバイスが広く普及している。

一方で、フラッシュメモリはその仕組みにより、ハードディスクと比較して「データ書き込み回数」に限りがあるといった課題がある。

ストレージデバイス搭載コントローラが直寿命化するような工夫が施されていたりするが、アプリケーション側でも工夫することでその効果はさらに高めることができる。

ここでは、OSの機能の一機能 "ファイルシステム"に注目して、それぞれの書き込みの違いを確認する。

目的

ファイルシステムの違いによって、次のような書き込み特性がどのように変化するかを調査する。

  • IO要求の発行回数
  • 書き込み総量
  • 書き込み頻度とオフセット

実行環境

Raspberry Pi 4 Model B (Raspberry Pi 4) は microSDカード経由でRaspberry Pi OSを起動させる。 また、Raspbery Pi 4 の USB3.0ポートにポータブルSSDを接続する。

計測環境の概要

ここで使用するRaspberry Pi 4のスペックについて、必要な情報だけ抜粋したものを下記に示す。

項目 概要
Board Raspberry Pi 4
CPU Cortex-A72 (ARM v8) 1.5GHz
メモリ 4GB LPDDR4-3200
OS Raspberry Pi OS (64 bit) (Feb 21st 2023)
kernel v5.15.92
I/O Scheduler mq-deadline
BCC Utilities bpfcc-tools version 0.18.0+ds-2
ext4 Utilities E2fsprogs version 1.46.2
xfs Utilities xfsprogs version 5.10.0-4
nilfs2 Utilities nilfs-tools version 2.2.8-1
f2fs Utilities f2fs-tools version 1.14.0-2
exfat Utilities exfatprogs version : 1.1.0-1
btrfs Utilities btrfs-progs version 5.10.1-2
jfs Utilities jfsutils version 1.1.15-5
fio fio-3.25-2
OS格納先ストレージ microSDHC 16GB Class10 UHS-1
計測用ストレージ SL-MG5

この実験では、 ポータブル SSD (SL-MG5) に対する書き込みを計測する。

計測方法

BPF Compiler Collection (BCC) を利用することで、ユーザプログラムから IO要求発行に任意の処理を追加し、IO要求の内容を確認する。

今回の計測では、BCCのサンプルスクリプトとして提供されている biosnoop を利用する

biosnoop は、IO要求発行(blk_mq_start_request)と IO完了(blk_account_io_done) における BIO のステータスを確認することができる。

このスクリプトを実行することで得られる書き込み先デバイス (DISK) と アクセス方向 (T) でフィルターをかける。
ここから、タイムスタンプ (TIME), オフセット (SECTOR)とサイズ (SIZE)を抽出する。

また、ストレージへの書き込みをする負荷プログラムとして fio を実行する

fioでは、合計 32GB となるように 以下の2パターンからデータを書き込みをする。

  1. 並列度1 でシーケンシャルな書き込みをする

     fio -directory=/mnt/fio-test -direct=0 -rw=write -bs=256k -size=32G -numjob=1 -invalidate=1 -fsync_on_close=1 -group_reporting
    
  2. 並列度8 でランダムな書き込みをする

     fio -directory=/mnt/fio-test -direct=0 -rw=randwrite -bs=256k -size=4G -numjob=8 -invalidate=1 -randseed=1 -fsync_on_close=1 -group_reporting
    

この実験では、これらのツールを活用して異なるファイルシステムに実行する。

毎計測時、デフォルトパラメータでmkfsコマンドの実行と、 echo 3 > /proc/sys/vm/drop_cachesによるキャッシュ解放を実施する。
biosnoopによる計測は、ファイルシステムをマウント(mount)してからアンマウント(umount)までとする。

その区間に負荷プログラム(fio)を実行し、そのときのIO要求のデータを使用する。

計測のタイムライン

準備

Linuxカーネルの再構築

BCCは、特定のカーネルコンフィグに依存しているが、Raspberry pi OS のデフォルトで無効となっている。

そこで、公式手順に基に、独自にカーネルのビルド・インストールを実施する。
カーネルコンフィグは、デフォルトのカーネルコンフィグから次のように修正する。

user@hostname:~/linux$ ./scripts/diffconfig .config.old .config
IKHEADERS n -> y

必要なパッケージのインストール

今回の計測するにあたって、Raspberry Pi OS にプリインストールされているパッケージのみでは不足している。

そこで、計測用にdebianパッケージを追加でインストールする。

pi@raspberrypi:~$ sudo apt install bpfcc-tools
pi@raspberrypi:~$ sudo apt install nilfs-tools exfatprogs xfsprogs jfsutils reiserfsprogs f2fs-tools btrfs-progs

BPFスクリプトの修正

debian (bullseye) が提供する bpfcc-toolsパッケージは、upstreamより古いバージョンとなっている。

今回使用しているバージョンには、BYTESの値で不適切となる不具合があったため、次のコミットをcherry-pickした。

github.com

また、今回の計測では短時間に多くのBIO情報が出力されるため、リングバッファ (page_cnt) のサイズも拡張しておく。

実験結果

IO要求の発行回数

biosnoop によって得られた結果から BYTES を抽出し、IO要求の発行回数をサイズごとに抽出した。

シーケンシャルな書き込み (並列度1) の場合は、次のような結果となった。

並列度1 で 32GBのデータを書き込みしたときのIO要求発行回数

この場合、それぞれのファイルシステムで大きな差は見られなかった。
また、それぞれのファイルシステムでは、fioによる書き込みサイズ 256K より大きいサイズで発行されていることも分かった。

一方で、ランダムな書き込み (並列度8) の場合は、次のような結果となった。

並列度8 で 32GBのデータを書き込みしたときのIO要求発行回数

この場合、先ほどのシーケンシャルな書き込みと比較していくつかの特徴がみられた。

  • f2fs と nilfs2 ファイルシステムは、シーケンシャルな書き込み(並列度1) とランダムな書き込み (並列度8) で似た傾向となった
  • ext4、xfs と btrfs ファイルシステムは、ランダムな書き込み (並列度8) では アプリケーションからの書き込みサイズ(256K) のIOが増えたため、IO総数も増えた
  • exfat と jfs ファイルシステムは、ランダムな書き込み (並列度8) では小さいIOに分割されて発行されたため、IO総数が増大した。

メタデータ書き込み総量

biosnoop によって得られた結果から BYTES を抽出し、その合計値を計算することでストレージへの書き込み総量を計算する。
さらに、ファイルの実データ (32GB) を減算することで、メタデータの書き込み総量を算出した。

  • Pattern 1: シーケンシャルな書き込み (並列度1)
  • Pattern 2: ランダムな書き込み (並列度8)

上記2パターンで計測したときのメタデータの書き込み総量は、次のようになった。 (単位は MB)

ext4 xfs nilfs2 f2fs exfat btrfs jfs
1 70.54 2.11 572.77 130.05 0.21 56.00 488.95
2 440.60 4.88 2296.04 414.20 32743.73 376.04 1148.64

ここから、メタデータによる書き込み総量の増加率を計算した結果、次のようになった。

ext4 xfs nilfs2 f2fs exfat btrfs jfs
1 +0.22% +0.01% +1.75% +0.40% +0.00% +0.17% +1.49%
2 +1.34% +0.01% +7.01% +1.26% +99.93% +1.15% +3.51%

この結果から、次のような特徴がみられた。

  • exfatを除いたファイルシステムは、並列度1から8にしたときにメタデータ書き込み総量は増加している。
    • 書き込み先ファイルが 1 から 8 に増えたため、メタデータの総量が増えるのは妥当であると思える。
  • exfatファイルシステムは、並列度1 ではメタデータ書き込み総量が最も少なかったが、並列度8になると膨大となった。
    • 並列度1の場合、exfatは連続したクラスタ確保 (NoFatChain属性) では、メタデータの書き込みを一部スキップできるのが要因と推測する。
    • 並列度8の場合、exfatの書き込み総量が急激に増加するのは、sparse fileに対応していないために、ランダムな書き込みで実データの書き込み回数が増えているのではないかと推測する。

書き込み頻度とオフセット

biosnoop によって得られた結果からTIME,SECTOR,BYTES を抽出することで、「いつ」「どこに」書き込みを実施したかを図示する。

シーケンシャルな書き込み(並列度1)を青色、ランダムな書き込み (並列度8) を水色で同時に図示している。

ext4ファイルシステムの書き込み先オフセット

ext4ファイルシステムは、次のようなストレージアクセスが見られた。

シーケンシャルな書き込み (並列度1)の場合、ジャーナルファイルとターゲットファイルの2つの直線が見られる。
その一方で、ランダムな書き込み(並列度8)の場合、書き込みが分散されているように見える。

xfsファイルシステムの書き込み先オフセット

xfsファイルシステムは、同じジャーナリングファイルシステムであるext4と傾向は似ている。

nilfs2ファイルシステムの書き込み先オフセット

nilfs2ファイルシステムは、ログ構造化ファイルシステムであるため、どちらのパターンにおいても直線となっている。

f2fsファイルシステムの書き込み先オフセット

f2fsファイルシステムも、ログ構造化ファイルシステムであるため、nilfs2と傾向は似ている。

exfatファイルシステムの書き込み先オフセット

exfatファイルシステムは、一定のところまで書いた後に断片化した書き込みが長時間続いている。

btrfsファイルシステムの書き込み先オフセット

btrfsファイルシステムでは、並列度に応じて書き込みが分散しているように見える。

jfsファイルシステムの書き込み先オフセット

jfsファイルシステムでは、ストレージデバイス全体を一定間隔に書き込みをしている。

パフォーマンス

memo

今回の実験では、Trim命令を明示的に発行していない。また、測定用にバックグラウンドプロセスがいくつか動いている。そのため、これらの値は参考値として算出した。

fio によって得られた結果にあるbwを抽出した。

  • Pattern 1: シーケンシャルな書き込み (並列度1)
  • Pattern 2: ランダムな書き込み (並列度8)

上記2パターンで計測したときの書き込み性能は、次のようになった。

fioによるパフォーマンス比較

ここでは、 f2fs と exfat ファイルシステムの特性について特筆する。

  • f2fs ファイルシステムは、並列かつランダムな書き込みであっても一定のパフォーマンスを出すことができる。
  • exfat ファイルシステムでは、並列かつランダムな書き込みが苦手であり、シーケンシャルな書き込みに比べて 20% ほどしかパフォーマンスが出ていない。

おわりに

本記事では、ファイルシステムの違いによるストレージへの書き込みについて以下の3点に着目して計測した。

  • IO要求の発行回数
  • メタデータ書き込み総量
  • 書き込み頻度とオフセット

計測の結果、アプリケーションの書き込みパターンがこれらに大きく影響するような結果となった。

また、今回は対象外としたが、ファイルシステムによってはデータ完全性を保障したり、ユーザビリティを向上させるような機能がある。
さらに、今回はデフォルトのパラメータで計測したが、ファイルシステムによってはmkfsのオプションやmountのオプションでデバイスに最適化した書き込みができるようになる。

そのため、今回のデータのみではファイルシステムの優劣をつけることはできず、それぞれのユースケースに沿ってファイルシステムを選定することが必要となってくる

変更履歴

  • 2023/3/22: 記事公開

参考