高速な書き込みは、必ずどこか別の場所で仕事をしている
書き込みの永続性が実際にどこで実現されるのか——ローカルSSD、ネットワークボリューム、オブジェクトストア——そして、最速のベンチマーク数値が実際のコストを隠すことが多い理由を深掘りする。

すべてのストレージエンジンは同じ問いに直面する:書き込みが確認される前に、何が完了していなければならないのか?最も安価な答えは、バイトをメモリにコピーして返すことだ。最も永続性の高い答えは、リモートのストレージサービスやデータベースサーバーのクォーラムを待つことだ。その中間にローカルSSDがあり、プロセスのクラッシュは生き残るが、ホストの障害には耐えられない。
著者のShayonは、明確なフレームワークでトレードオフを説明している:クライアントのPUT(データベースリクエスト)とオブジェクトのPUT(オブジェクトストレージへのHTTPリクエスト)を分離するのだ。これらを分離すれば、レイテンシと永続性がどこでトレードされているかを正確に追跡できる。
ローカルWALの幻想
ホストローカルのNVMe SSDは高速だ——fdatasync()で0.1msから1ms程度——しかし、プロセスやカーネルのクラッシュからのみ保護する。ホストを失えば、書き込みも失われる。S3のようなオブジェクトストアは10倍遅いかもしれない(TursoはS3 Express One Zoneへの4KB PUTの平均6.4msを計測した)が、PUTが成功すれば、ストレージサービスが永続性を所有する。
その差は魅力的だ:50倍の速度差は実際のベンチマーク結果だが、それはすべてのNVMeデバイスとオブジェクトストアの特性ではない。2つの経路は異なる障害を生き残る。
フラッシュのバッチ処理
すべての書き込みの後にfdatasync()を呼ぶと、スループットはデバイスのフラッシュレートに制限される。シリアル化された1msのフラッシュでは、毎秒約1,000回のフラッシュが可能だ。複数の書き込みを1つのフラッシュにまとめる——バイト数、書き込み数、または時間でバッチを閉じる——ことでコストを共有できる。しかし、バッチ処理には独自のトレードオフが伴う:最初のリクエストが最も長く待ち、フラッシュエラーはバッチ全体を失敗させ、タイムアウトしたリクエストが後でディスクに到達するバッチにすでに含まれている可能性がある。
ホストを超えて
ホスト障害を生き残りたいなら、別のコピーが必要だ。永続的なネットワークボリュームはローカルブロックデバイスのように見えるが、すべてのfdatasync()にネットワークレイテンシを追加する。オブジェクトストアは永続性の境界をストレージサービスに移す。レプリケートされたWALは他のデータベースサーバーにコピーを置く。各オプションは、クライアントから見える書き込み経路に仕事を戻す。
著者の重要な洞察:ラベルのないレイテンシチャートは無意味だ。どの操作が速度を支払ったのか、成功後に何が失われる可能性があるのか、システムが許容する未完了のクリーンアップがどれだけあるのかを知る必要がある。
NVMeのレイテンシ数値は、その確認ポイントなしでは不完全だ。タイマーはバイトをメモリにコピーした後に止まったのか、1つのローカルSSDを同期した後か、それともリモートボリュームが書き込みを確認した後か?
| 確認ポイント | 生き残る障害 | レイテンシ | 典型的な用途 |
|---|---|---|---|
| メモリコピー | プロセスクラッシュ | マイクロ秒 | 非永続キャッシュ |
| ローカルSSD fdatasync() | プロセス/カーネルクラッシュ | 0.1–1 ms | WAL、シングルホストDB |
| ネットワークボリューム fdatasync() | ホスト障害、ただしデータセンター障害は不可 | 1–10 ms | アタッチドボリューム、EBS |
| オブジェクトストア PUT | データセンター障害(レプリケーションあり) | 5–50 ms | S3、GCS、Azure Blob |
| レプリケートWAL(クォーラム) | 複数ホスト障害 | 10–100 ms | 分散データベース |
ディスカッション
0 件のコメント
最初のコメントを投稿しましょう。