NVMeとSSDを意識したストレージエンジン設計
ストレージエンジンの書き込み性能と寿命は、SSDの内部動作を無視すると頭打ちになります。FTL・書き込み増幅・GC・並列キューの原理から、ページサイズ・コンパクション・zoned配置の勘所が掴めます。
- 1.SSDはFTLが論理ブロックを物理ページに対応づけ、上書き不可・消去はブロック単位という制約をGCで隠す。DBの書き込み増幅にSSD内部の増幅が掛け算で乗るため、追記中心の設計が効く。
- 2.NVMeは多数の深いキューで並列I/Oを捌けるため、同期1本の小さなランダム書き込みより、複数スレッドからまとまったページを非同期に投げる設計が帯域を引き出す。
- 3.Zoned Storage(ZNS)はGCをホスト側に開放し、シーケンシャル書き込みゾーンをLSMのSSTableに対応づけることで、デバイス内GCを実質ゼロにして書き込み増幅と寿命を改善できる。
なぜストレージエンジンがSSDの内部を知るべきか
ストレージエンジンは長らく回転ディスク(HDD)を前提に設計されてきました。シーク時間が支配的なHDDでは、シーケンシャルアクセスを最大化しランダムI/Oを避けることが正義で、B+Treeの内部もこの前提の上にあります。SSD/NVMeはシークが消えた一方で、フラッシュメモリ固有の制約を内部に抱えています。この制約を知らずに「ランダムI/Oも速いから何でも良い」と扱うと、書き込み性能が頭打ちになり、デバイス寿命も縮みます。本記事は、FTL・書き込み増幅・GC・並列キューというSSDの原理から、ストレージエンジン側の設計判断を導きます。
フラッシュの三制約とFTL
NANDフラッシュには、ソフトウェア設計を縛る三つの物理制約があります。
- 読み書きはページ単位、消去はブロック単位。ページ(典型的に4KB〜16KB)が読み書きの最小単位だが、消去はそれを束ねたブロック(数百ページ〜)単位でしか行えない。
- 上書き不可(erase-before-write)。一度書いたページを書き換えるには、まず属するブロック全体を消去する必要がある。論理的な「上書き」は、別の空きページへ書いて旧ページを無効化する形で実現される。
- 消去回数に上限(摩耗)。各ブロックの消去(P/Eサイクル)には有限の寿命があり、偏って消すと一部ブロックだけ先に死ぬ。
これらを上位から隠すのが FTL(Flash Translation Layer) です。FTLはホストが見る論理ブロックアドレス(LBA)を、フラッシュ上の物理ページへ動的に対応づけるマッピング表を持ちます。LBAへの「上書き」は、新しい空きページへ書いてマッピングを張り替え、旧ページを「無効(stale)」と印付けるだけ。物理的な消去は後でまとめて行います。摩耗を均す ウェアレベリング も、このマッピングの張り替えで実現します。
FTLが「上書きを別ページへの追記+マッピング更新」で実現するのは、ログ構造化ストレージそのものです。つまりSSDの中には、ホスト側のLSM-Treeと同じ追記&後始末の構造がもう一段隠れています。設計の妙は、この二段のログ構造を喧嘩させずに重ねることにあります。
ガベージコレクションと書き込み増幅
無効ページがブロック内に増えると、有効ページと無効ページが混在します。空き領域を回収するため、FTLは GC(ガベージコレクション) を走らせます。手順は、対象ブロックの有効ページだけを別の空きブロックへコピー(退避)し、元ブロックを丸ごと消去して空きに戻す、というものです。
ここで 書き込み増幅(Write Amplification, WA) が生まれます。GCが有効ページを退避するたび、ホストが要求していない書き込みがフラッシュ内部で追加発生するからです。WAは次のように定義されます。
WA = フラッシュへの実書き込み量 / ホストが要求した書き込み量
WAが大きいほど、同じ論理書き込みに対しフラッシュセルへの実書き込みが増え、帯域を食い、P/Eサイクルを早く消費して寿命を縮めます。決定的なのは、ホスト(DB)側の書き込み増幅とデバイス側のWAが掛け算で乗る点です。LSMのコンパクションでホスト側WAが10倍、その書き込みをSSDが捌く際のデバイスWAが3倍なら、フラッシュには論理量の約30倍が書き込まれます。
4KB未満や非整列の小さなランダム上書きを多発させると、GCが退避すべき有効ページが各ブロックに散らばり、デバイスWAが急増します。逆に、消去ブロックサイズに近い大きな塊をシーケンシャルに書くと、無効化がブロック単位でまとまり、GCはほぼ消去だけで済んでWAが1に近づきます。DBの書き込みパターンが、見えないデバイスWAを左右します。
並列キュー:NVMeで帯域を引き出す
SATA時代のAHCIはコマンドキューが1本・深さ32でしたが、NVMeは最大65535個のキューを各深さ65536まで持てます。フラッシュは内部で複数のチャネル・ダイ・プレーンに分かれ並列動作するため、十分な数の未完了I/O(高いキュー深度)を与えて初めて全帯域が出ます。同期的に1本のI/Oを投げて完了を待つ使い方では、内部並列性の大半が遊びます。
ストレージエンジン側の含意は明確です。
- 非同期・バッチでI/Oを投げる。複数のページ書き込みをまとめ、完了を待たずに次々投入する。ダイレクトI/Oとio_uringはこの非同期投入とキュー深度の確保に直結します。
- 書き込みをまとめてシーケンシャル化する。LSMのMemTableフラッシュやWALの追記は本質的にシーケンシャルで、NVMeのスループットを素直に引き出します。
- fsyncの粒度を粗くする。コミットごとに同期するとキュー深度が稼げません。グループコミットとfsyncで複数トランザクションのフラッシュを束ねると、同期点が減り並列性が上がります。
ページサイズ・コンパクション・zoned配置の設計
以上の原理から、ストレージエンジンの三つの設計軸が導けます。
第一に ページ/ブロックサイズの整列。エンジンのI/O単位を、デバイスの物理ページや消去ブロックの境界に整列・倍数化すると、書き戻しがブロック内で完結し、Read-Modify-Write(読んで一部だけ書き換える際にデバイスが内部で起こす再書き込み)を避けられます。整列を外すとトーンページ対策のダブルライトと相まって、書き込み量がさらに膨らみます。
第二に コンパクションの調整。LSMのコンパクション戦略はホスト側WAを直接決め、それがデバイスWAに乗算されます。SSDではコンパクションのI/Oを大きなシーケンシャル単位にまとめ、SSTableのファイルサイズを消去ブロックの整数倍に寄せると、ファイル削除がそのままブロック無効化に対応し、デバイスGCが軽くなります。
第三に zoned配置(ZNS)。Zoned Namespace SSD(ZNS)は、デバイスを多数の ゾーン に分け、各ゾーンは 追記のみ・リセットで一括消去 という制約をホストに見せます。これはフラッシュ消去ブロックの制約をそのまま露出させる代わりに、デバイス内GCをなくし制御をホストへ渡す設計です。
LSMのSSTableは「一度シーケンシャルに書いたら不変、不要になったら丸ごと削除」という性質を持ちます。これはZNSのゾーン(追記のみ・リセットで消去)と一対一で噛み合います。1ゾーン=数個のSSTableと対応づければ、ファイル削除がゾーンリセットになり、デバイス側GCが実質ゼロになります。RocksDBのZenFSはこの発想でZNS上にLSMを配置します。
三方式の対比
| 観点 | 従来SSD(FTL任せ) | 整列+大粒度コンパクション | ZNS(zoned配置) |
|---|---|---|---|
| GCの主体 | デバイス内FTL(不可視) | デバイス内FTL(軽め) | ホスト(DBが制御) |
| デバイスWA | 中〜大(パターン依存) | 小(ブロック整列で抑制) | ほぼ1(退避なし) |
| オーバープロビジョニング | 必要(GC用の予備領域) | 必要だが軽減 | ほぼ不要 |
| 実装負担 | 小(透過的) | 中(整列・粒度設計) | 大(追記専用・配置をDBが管理) |
| 代表例 | 一般的なNVMe SSD | RocksDB等の調整運用 | ZNS+RocksDB/ZenFS |
SSDが上書き不可・消去はブロック単位であること、その制約をFTLがマッピング張り替えで隠し、無効ページ回収のためにGCが有効ページを退避することで書き込み増幅が生じること、そしてホスト側WAとデバイスWAが乗算される関係が頻出です。NVMeで性能が出る条件は高いキュー深度=非同期で多数のI/Oを未完了状態にすること、ZNSの利点はデバイス内GCをなくしホストが配置を制御することでWAを1に近づけること、と即答できると強いです。
まとめ
SSD/NVMeを意識したストレージ設計の核心は、フラッシュの「上書き不可・消去はブロック単位」という制約と、それを隠すFTL・GCが生むデバイス書き込み増幅を、ホスト側の書き込みパターンで抑え込むことです。ランダム小書き込みを避けて追記・シーケンシャルに寄せ、ページとファイルを消去ブロックに整列させ、NVMeの並列キューを非同期バッチで埋め、究極にはZNSでGCをホスト側に引き取る——これらはすべて、二段に重なるログ構造(DBのLSMとSSDのFTL)を噛み合わせる試みです。増幅の三角形はRUM予想で、SSTableの内部構造はSSTableのブロックフォーマットで、より広い文脈はストレージエンジンの系譜で押さえると体系が掴めます。
データベース Article
NVMeとSSDを意識したストレージエンジン設計を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
SSD
比較で見る軸
難易度: advanced / カテゴリ: データベース / タグ数: 5
導入後に効く点
NVMeは多数の深いキューで並列I/Oを捌けるため、同期1本の小さなランダム書き込みより、複数スレッドからまとまったページを非同期に投げる設計が帯域を引き出す。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- データベース
- タグ数
- 5
判断チェックリスト
- 自社の用途が「SSD / NVMe」に近いか確認する。
- 強みである「SSDはFTLが論理ブロックを物理ページに対応づけ、上書き不可・消去はブロック単位という制約をGCで隠す。DBの書き込み増幅にSSD内部の増幅が掛け算で乗るため、追記中心の設計が効く。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。