IOデバイスとレイテンシ
(planetscale.com)- 不揮発性ストレージはテープからHDD、SSD、クラウドのネットワークストレージへと進化してきたが、データの位置と配置は依然としてIOレイテンシを左右する
- テープストレージは順次読み書きに強い一方、離れた場所にあるデータを読むには数十秒かかることもあり、高トラフィックのトランザクションデータベースには向かない
- HDDはテープよりレイテンシを大幅に下げたが、回転するプラッタとヘッド移動のためランダム読み取りは通常 1〜3ms 程度で、リクエスト順序による性能差が大きい
- SSDは機械部品なしでNAND flashにより動作し、ランダム読み取りは 16μs まで高速化できるが、並列性の活用とgarbage collectionのためデータ配置は引き続き重要である
- クラウドでのストレージとコンピュートの分離はスケーラビリティと障害対応を容易にする一方で、ネットワーク往復とIOPS制限を追加し、PlanetScale Metalは直結の NVMe SSD とレプリケーションによってこのコストの削減を目指している
ストレージのレイテンシを左右する基本要素
- 不揮発性ストレージは電源が切れてもデータを保持し、写真、メール、銀行残高、医療記録のようなデータを保存する基盤である
- CPUレジスタ、CPUキャッシュ、RAMのような 揮発性ストレージ はより高速だが、継続的な電力供給を必要とする
- ストレージ性能は容量だけの問題ではなく、データに到達する方法、読み書きの単位、キューイング、並列性、ネットワーク往復の有無によって変わる
- PlanetScaleは PlanetScale Metal の公開に合わせて、Metalがネットワーク接続ストレージではなくローカルNVMeドライブでクラウドデータベースを実行すると明らかにした
テープストレージ: 順次アクセスには強いがランダムアクセスには弱い
- コンピュータは1950年代から テープドライブ を不揮発性デジタルストレージとして使ってきた
- テープカートリッジは複数のトラックと多数のセルで構成され、各セルの磁気分極状態がバイナリデータを表現する
- カートリッジをリーダーに入れてモーターで巻き取ると、IO head が通過するデータを読む
- 読み書き位置がヘッドに近ければ速いが、遠ければレイテンシが大きくなる
- 現代のテープシステムでも、離れたデータを読むには数百メートル分を巻かなければならないことがある
- この場合、読み取りに 数十秒 かかることがある
- 同じ数の読み書きでも、データが散在していれば順次配置よりはるかに時間がかかる
- 記事の例では、散在した読み書きが同じ作業量で約 7倍 長くかかる状況を示している
- テープはランダム読み書きのレイテンシは悪いが、長い順次読み書きには依然として適している
- SSDやHDDよりGBあたりコストが低く、保管寿命が長い
- CERNは 400PB以上 のデータをテープストレージのデータウェアハウスで管理している
- AWSもテープアーカイブサービスを提供している
- 高トラフィックの トランザクションデータベース にはテープは適していない
HDD: 回転ディスクとコマンドキューイングの折衷
- HDD はテープの代わりに、円形の金属ディスクであるプラッタにデータを保存する
- プラッタは筐体内で高速回転し、例として 7200 RPM が一般的な速度として挙げられている
- HDDのトラックは円形で、1枚のディスクに 100,000本以上 のトラックがあることもある
- 各トラックは数十万のページを含み、各ページはおよそ 4KB のデータを格納する
- HDDはヘッド移動とプラッタ回転によって読み書き位置を合わせる
- テープと異なり、表面全体のビットに常時アクセスできる
- 目的のデータが現れるまでテープを巻く必要はない
- 一般的なランダム読み取りは 1〜3ms で実行できる
- リクエスト順序は性能に大きな影響を与える
- 順次性の高い読み書きは速く終わる
- 同じ6回の読み書きでも、順序が入り混じるとプラッタが正しい位置に来るまでの待ち時間が増える
- 磁気ディスクは古くから コマンドキューイング をサポートしている
- SCSIは1980年代から、SATAは2000年代から関連機能を提供している
- OSは複数のコマンドを並列、または順序を変えて実行できるよう送ることができる
- ディスクコントローラは作業キューを使って、ディスク構造に合わせて読み書きをスケジューリングできる
- HDDはテープより改善されたが、特に ランダム読み書き では依然として遅い場合がある
SSD: 機械部品が消えても残る性能変数
- SSD またはflashストレージは1980年代に発明されたが、コンシューマ向けストレージとして主流になったのは2000年代である
- SSDはデータ読み取りのために機械部品に依存しない
- NAND flashという不揮発性トランジスタを使う
- 1と0は物理部品の移動なしに電気信号で読み取り、書き込み、消去される
- SSDは1つ以上の target で構成され、各targetは複数のblockを含み、blockは複数のpageを含む
- SSDはpage単位で読み書きする
- 一部のデータだけが必要でも、ドライブへのリクエスト単位はpageである
- 例の構成ではpageが4096ビット、blockが16K page、targetが16K block、デバイスが8 targetなら、合計は
4k * 16k * 16k * 8 = 8,796,093,022,208ビット、すなわち 8TB になる - SSDのランダム読み取りはモデルによって異なるが、16μs まで高速になりうる
- 機械部品がなくてもデータ配置は重要である
- SSDの性能要因には 並列性 と garbage collection が含まれる
SSDの並列性: target分散がスループットを変える
- 一般に各 target には、制御ユニットにつながる専用のlineがある
- 各lineは読み書きを処理するが、一度に転送できるpageは1つだけである
- page転送は非常に高速だが、それでもわずかな時間を要する
- 8個のwriteが4個のtargetに分散されていれば、4本のlineを並列に使って2回の時間スライスで書き込める
- 8個のwriteがすべて同じtargetに集中すると、1本のlineしか使われず、残りのlineは遊んでしまう
- 読み書きの順序とデータ配置はSSDでも性能に影響する
- MySQLのようなソフトウェアを設計する際は、データがどのような構造で保存され、ディスク上にどう配置されるかに注意すべきである
SSDのgarbage collection: 書き込み前の消去コスト
- SSDのpageは何度でも読めるが、一度書き込まれたpageは既存データを明示的に消去するまで新しいデータで上書きできない
- 個別のpageは消去できず、block全体 を消去しなければならない
- SSDにはempty、in-use、dirty pageを管理する内部アルゴリズムが必要である
- dirty page は、書き込まれたがもはやデータが不要で、消去準備ができたpageである
- 新しいwriteを受けるためにデータを再配置しなければならない場合があり、これを管理するアルゴリズムが garbage collector である
- 十分なunused pageがあれば、新しいデータをすぐに書き込める
- unused pageが不足し、dirty pageが多い場合は、まずgarbage collectionを実行しなければならない
- 例では、新たに5 pageを書き込むためにnon-dirty page 2個を別の場所へ移動する
- その後、そのtargetのpageをすべてdirty状態にして消去できるようにする
- こうした追加段階がwrite性能を大きく低下させる
- 読み取り、書き込み、削除が多い多忙なSSDでは、garbage collectionのために他の作業が遅くなることがある
クラウドがもたらした変化: ストレージとコンピュートの分離
- テープからHDD、SSDへの変化は、耐久的なIO性能を大きく向上させた
- クラウドへの移行は、IO性能にさらなる変化をもたらした
- AWSは2006年の公開以来、クラウド移行を大きく広めたサービスとして挙げられている
- クラウド環境では、ユーザーは大規模データセンター内の任意のハードウェア上で仮想化されたサーバーを借りる
- サーバーはハードウェア故障、交換、ネットワーク断などさまざまな理由でいつでも停止しうる
- リースしたクラウドインフラ上でシステムを構築する場合は、より頻繁な障害に耐えられなければならない
- こうした条件と、動的に拡張可能なストレージボリュームへの要求が storageとcomputeの分離 につながった
ネットワーク接続ストレージの利点とコスト
- 従来、サーバー、デスクトップ、ノートPC、携帯電話は不揮発性ストレージを直接接続してきた
- SATAケーブル、PCIeインターフェース、または同一SoC内蔵の形が使われる
- 直接接続ストレージは高速だが、2つの制約がある
- サーバーが停止するとデータも一緒に利用できなくなる
- ストレージ容量が固定される
- アプリケーションサーバーは通常、一時的な(ephemeral)環境と相性がよく、多くの作業がメモリ上で行われるため、この問題は大きくない
- データベースはサーバーが停止してもデータを失ってはならず、データサイズが急速に増えてストレージ限界に達することがある
- 多くのクラウドプロバイダは、コンピュートインスタンスに別途構成可能なネットワーク接続ストレージを取り付けられるようにしている
- EC2の基本構成は通常、EBS のネットワークストレージボリュームを接続する方式である
- Amazon RDS、Amazon Aurora、Google Cloud SQL、PlanetScaleのようなデータベースサービスも、computeとstorageがネットワークで分離されたシステムに依存している
- この方式により、データ増減に応じてストレージボリュームを動的に調整できる
- サーバーが停止してもデータは安全に残り、別のサーバーに再接続できる
- その代わり、ネットワーク往復とIOPS制限という性能コストが生じる
ローカルNVMeとネットワークストレージのレイテンシ差
- 直接接続された NVMe SSD は、不揮発性メモリホストコントローラインターフェース仕様を使い、高速なIO速度と帯域幅を提供するSSDである
- CPUからRAMまでの往復は約 100ns とされる
- CPUからローカル接続NVMe SSDまでの往復は約 50,000ns、つまり 50μs である
- ネットワーク接続ストレージボリュームでは、データセンター内部の短いネットワーク往復が必要になる
- EBSのようなネットワーク接続ストレージは、往復時間が約 250,000ns、つまり 250μs または 0.25ms とされる
- 同じ最新SSDを使っていても、ネットワーク接続では個々の読み書きリクエスト処理時間が一桁長くなる
- 大量の順次IOでは悪影響を和らげられるが、取り除くことはできない
- ネットワーク接続ストレージは、ストレージシステムにアクセスするたびに 追加レイテンシ を生む
IOPS制限と直接接続ストレージの違い
- AWSやGoogle Cloudを含む多くのクラウドプロバイダは、ネットワーク接続ストレージモデルにおいてwire経由で送れるIO操作数を制限している
- AmazonのGP3 EBSインスタンスは、基本で毎秒 3000 IOPS を許可する
- より高く設定することもできるが、追加コストがかかる
- 以前のGP2 EBSボリュームは、ときどきburstを許容するためにIOPS poolを蓄積する方式で動作していた
- ストレージをコンピュートインスタンスに直接接続すれば、人為的なIO操作制限はない
- 直接接続では、ハードウェアが許す限り読み書きできる
耐久性と拡張性を維持する方法
- 直接接続SSDにおける問題1の データ耐久性 は、レプリケーションで解決できる
- 一般的な方式は、1台のサーバーをprimaryとしてすべてのwriteリクエストを受け取り、2台以上の追加サーバーがデータを複製する構成である
- データが3か所にあれば、データ損失の可能性は小さくなる
- 例の数値として月間サーバー障害確率を1%と仮定すると:
- 単一サーバーでは毎月のデータ損失確率は 1% である
- 3台のサーバーでは
1% × 1% × 1% = 0.0001%、つまり 100万分の1 の確率まで下がる
- PlanetScaleは失敗したノードを自動検知して置き換え、データベースデータを頻繁かつ安全にバックアップする
- 問題2の ドライブ拡張性 には、より多くの手動介入が必要となる
- ディスクが容量上限に近づいたときの監視とアラートが必要である
- 必要なときに容量を簡単に増やせるツールが必要である
PlanetScale Metalのアプローチ
- Metal は、直接接続NVMe SSDを使用するデータベースクラスタを提供する
- 各データベースインスタンスは direct-attached NVMe SSD で実行される
- Metalクラスタは基本的にprimary 1台とreplica 2台で構成される
- 対応するデータベースクラスタは Vitess または Postgres である
- ストレージ上限に達したら、数回のクリックでより大きなドライブを備えたサーバーへスケール調整できる
- 内部では新しいノードを立ち上げ、既存インスタンスから新しいインスタンスへデータを移行し、このプロセスは zero downtime で処理される
- Metalデータベースには人為的なIOPS capがない
- ユーザーは低レイテンシでIO操作を実行でき、クラウドプロバイダの高価なIOPSクラス料金やthrottleなしに、ハードウェアが許す限り利用できる
1件のコメント
Hacker News のコメント
ブログの著者です。今回の記事を書く過程は本当に楽しく、これまで作った記事の中でも間違いなく最も複雑でした
インタラクティブな可視化を作るために、文字どおり数千行の JavaScriptを書きました。皆さんに楽しんでもらえればと思います
ただ、耐久性についての「100万分の1」という表現は、新しいサーバーが入って再レプリケーションされるまでの障害時間が短いことを考えると悲観的すぎる気がします
例えば復旧に10分かかるとして、3台のサーバーが月に1回必ず故障するとしても、それらが重なってすべて故障する確率はすでに200万分の1くらいだと思いますし、月間故障確率が1%なら、3つの障害が重なる可能性は極めて低くなります
顧客が100万人いるなら100万分の1はそれほど良い数値ではないので、補足してみました
キーボードを叩いていた時間と、頭の中で考えていた時間がかなり違うことは分かっています
このテーマには非常に馴染みがあるので内容自体に付け加えることはなく、ざっと見ても良さそうです。ただ、自分のブログ用のアニメーションを考えているところで、最近試したライブラリのいくつかが気に入りませんでした
しばらく SQLite+NVMe の組み合わせを推していました。個人的には、普段よりずっと先まで進める新しいパターンに見え、場合によっては水平スケーリングなしでも最後まで持ちこたえられます
性能ではレイテンシが王様で、特に項目を直列に処理しなければならない場合はなおさらです。NVMe 上で SQLite を動かすと、ほかのプロバイダーでは得られないレイテンシ上の利点が生まれます
現実的なユースケースの大半では、メモリ実行が NVMe の永続ストレージより大きく優れているとも思いません
単一ホストでは少し速いかもしれませんが、Web サーバーが1台から2台になり、その両方がデータベースに書き込む必要が出た瞬間に、自分で物事を難しくしているように思えます
レイテンシが重要だという言い方も誤解を招きます。一貫性がなければ性能には意味がなく、Web サーバーが複数台になった瞬間に、その一貫性を自分で解決しなければなりません
さらに、データベースのレイテンシは通常インターネットの往復レイテンシよりずっと小さく、そのインターネットのレイテンシも、画像やコードライブラリのようなページアセットの読み込みを待つ「遅延」に比べれば小さいものです
そもそも直列のデータベースクエリはできるだけ避けるべきで、可能なら JOIN を使い、不可能な場合でもできるだけ非同期に同時にクエリを投げて並列実行されるようにすべきです
並列書き込みの問題を避けるには、特定の不格好な動作モードを設定する以外に、アプリケーション側で書き込み専用の単一スレッドを使うという小技があります
そうすると、すでに複雑な並列コードがたいてい少しだけさらに複雑になります。書き込みスレッドが1つなら、SQLite は本当に見事に動きます
fsync()してみると、NVMe ディスクでも依然として1〜2ms のレイテンシが測定されますより新しいシステムでは約800µs程度でした
情報量がとても良かったので、製品プロモーションだという事実を完全に忘れて読んでいました。可視化とインタラクションが素晴らしいです
ディスク I/O のアニメーションを見て Melvin Kaye を思い出しました
Mel は、遅い Flexowriter が出力文字の間に遅延を必要とするときでさえ、時間遅延ループを使いませんでした
代わりにドラム上の命令の位置を調整して、次の命令が必要になるたびに読み取りヘッドがちょうど通り過ぎた状態になるようにし、ドラムは次の命令を探すためにもう1回転しなければなりませんでした
https://pages.cs.wisc.edu/~markhill/cs354/Fall2008/notes/The...
Metal は本当に格好よく見えますが、以前の職場で GCP のインスタンスローカル SSDを使ったときは、デバイスブロックがデータを失うなど深刻な信頼性の問題がありました
今は状況が変わったのか、どのマシンタイプを使っているのか気になります
当時の回避策はこれでした: https://discord.com/blog/how-discord-supercharges-network-di...
ただし私たちは、MySQL の準同期レプリケーションによって、すべての書き込みがクライアントに承認される前に、異なるアベイラビリティゾーンの2台のマシンへ永続化される冗長システムを運用しています
Kubernetes オペレーターと Vitess の
vtorcプロセスが連携して、失敗した、または疑わしいレプリカまで積極的に検出して置き換えますGCP では n2d-highmem マシンで最も良い結果が得られ、AWS ではインスタンスストレージを持つ最新世代タイプをほぼ全般的に使っています
良い記事。一般にクラウドストレージがひときわ遅いという問題もある。
ほかでもすでに取り上げられているが、この記事は問題をうまく要約している: http://databasearchitects.blogspot.com/2024/02/ssds-have-bec...
最近 https://github.com/feldera/feldera で増分インデックスを S3/オブジェクトストレージに保存するサポートが追加されたが、NVMe は前の記事で述べられている明白な性能上の利点のため、もっと以前からサポートされていた。
誰かがより良い提供方法でこの領域を揺さぶってくれるといい。
この記事では分散ストレージについて十分に評価されていない部分がある。
第一に、システムによってはレプリケーションを標準で提供していない。Cassandra クラスタや MySQL はマスター・スレーブレプリケーションが可能だが、多くのシステムはそうではない。
第二に、クラウドで NVMe ストレージを使うと、メンテナンス期間やクラウド側が開始するドレインを気にする必要があり、運用がはるかに難しくなる。
そうしたシステムと連携してデータを別ノードへ退避しないと、データが消えてしまう。
ストレージとコンピュートを分離すれば、クラウド運用者は必要に応じてコンピュートを空にして移動でき、データはコンピュートから独立しており、クラウド運用者がそのデータシステムとドレインも管理するため、顧客の介入なしにワークロードの配置を調整できる。
「ローカル」ファイルシステム API のように見えるレプリケートされたネットワーク接続ストレージは、私たちが持っているもののように組み込みレプリケーションを持たないシステムに耐久性を与える強力な方法だ。
本当に素晴らしく、PlanetScale Metal もかなり堅牢に見える。リリースでレイテンシが大きく下がるのを見るのが特に好きだ: https://planetscale.com/blog/upgrading-query-insights-to-met...
何年もの間、レプリケートされたデータベースがなぜいつも EBS にしがみつき、そのレイテンシを受け入れるのか理解できなかった。すでにレプリケーションがあるのに、なぜ思い切ってローカルディスクを使わないのか疑問だった。
以前の組織で Elasticsearch を一時的なログ/メトリクス保存先として運用していたとき、信頼性要件も大きくなかったのでそうしようと提案したが、説得できず、結局もっと悪い AWS Elasticsearch を使うことになった。
ローカルディスク容量が有限なのは分かるが、コア/メモリ/ディスクの比率はほとんどのユースケースに十分なのではないかと思う。比率の異なるローカルディスクインスタンスも多いので、適切なバランスを見つけられる。
20TB 以上のローカルハードディスクインスタンスでホット/コールドストレージを実装することもできる。
PlanetScale チームはついに筋の通ったことをしているので、大いに称賛したい。AWS でさえ Elasticsearch をローカルディスクで動かしていないというのだから、ClickHouse や Cassandra のようなものをすべてローカルディスクで動かすと考えればよい。
主要な問題は、停止・起動イベント後にディスクが消去される点だった。クラスタの残りが正常で利用可能なレプリカがあっても、SQL Server はこれを自動処理できない。
初期化されたノードを自動復旧しないため、それを回避するためのスクリプト作成とテストは、最も大胆で有能な組織でなければ本番環境では耐えられない。
私たちはこのモデルで数百の ClickHouse クラスタを運用している。障害よりも性能問題を解決するためにサイズ変更することのほうがはるかに多い。
たとえば米国時間の日曜朝にテナントの性能問題が発生した場合、最も単純な解決策は週末の間だけより大きな VM に上げ、月曜朝にコアチームが根本原因を見るようにすることだ。
追加コストは小さく、はるかに高くつく従業員の燃え尽きを避けられる。
本当に素晴らしい記事で、ランダム書き込みの可視化がとてもよくできている。
ネットワーク接続ストレージの IOPS 制限について、いくつか、もしかすると馬鹿げた質問が浮かぶ。
第一に、「IOPS」制限は特定種類のネットワークトラフィック、つまり EBS ボリュームとの間のトラフィックに対する速度制限なのかが気になる。結局「IOPS」が「EBS ボリュームのネットワークトラフィック」を意味するのかを尋ねたい。
第二に、この方式がコストを節約してくれるのかも気になる。そうだとすれば、奇妙な AWS の価格裁定によるものなのか、それとも EBS ネットワーキングを減らすことで生じる効率上の利得なのかが気になる。
ストレージとコンピュートを同じマシンに置くことが、レイテンシの面で構造的に 1 ホップ減らす利点であることは明らかに見えるが、ドルあたりの処理量の面でも利点があるのか知りたい。
私はこれを別のモデルとして捉えている。EBS ボリュームは PCIe バスに接続された物理基板の一部ではなく、多数の物理ドライブで構成される大規模分散システムの持ち分であり、コンピュートとの間に専用のネットワーク容量を持つ SAN に近い。
コストは節約できるかもしれないが、結局は複数のトレードオフの束だ。