RAM を超えたキャッシング:NVMe の事例 - Dormando (2018年6月12日)
スタックのあらゆる層におけるキャッシングアーキテクチャは、パフォーマンスとコストの間で暗黙のトレードオフを具現化しています。しかし、これらのトレードオフは常に変化しています。新しい変曲点は、ストレージ技術の進歩、ワークロードパターンの変化、またはハードウェアの需給変動に伴って出現する可能性があります。
この記事では、キャッシングシステムにおけるRAMのコスト増加が設計に与える影響を探ります。 RAMは常に高価でしたが、DRAMの価格は2017年に50%以上上昇しており、高密度のRAMは、電力と全体的なコストを膨張させるマルチソケットNUMAマシンを必要とします。同時に、フラッシュやOptaneなどの代替ストレージ技術は改善を続けています。それらは、専用のハードウェアインターフェース、安定したパフォーマンス、高密度、比較的低コストを備えています。RAMからNVMeまたはNVMデバイスへのキャッシングのオフロードを検討する経済的なインセンティブが増加していますが、パフォーマンスへの影響はまだ広く理解されていません。
分散型でシンプルなキャッシュに特化したキー/バリューストアであるMemcachedのコンテキストで、これらの設計への影響を探ります。概要については、概要ページまたはチュートリアルをご覧ください。
- Memcachedは、RAMをバックアップとするキー/バリューキャッシュです。これは、LRUによってデータの寿命が管理された、大規模な分散ハッシュテーブルとして機能します。最も古い未使用のデータは、新しいデータのために追い出されます。
- 非常に低いレイテンシ(ミリ秒未満)と高いスループットが重要です。ページは、memcachedに複数回データを要求することがあり、これにより時間がすぐに積み重なる可能性があります。
- Memcachedは、フラッシュ/ディスクドライブを備えたデータベースや、テンプレートやレンダリングなどのCPUバウンドのコードへのクエリを削減することで、大幅なコスト削減を実現します。
Memcachedには、extstoreと呼ばれるストレージシステムがあり、RAMを解放して、「最近使用されていない」キーのデータの一部をディスクに保持できます。その仕組みの詳細については、リンクを参照してください。簡単に言えば、キーはRAMに残り、値はディスクに分割できます。最近アクセスした頻繁にアクセスされるキーの値は、RAMに残ります。
このテストは、ハードウェアとガイダンスを提供してくれたAccelerate with Optaneの協力のもとで行われました。また、素晴らしいフィードバックを提供してくれたextstoreを採用したNetflixにも感謝します。
キャッシュRAMの内訳
たとえば、1TBのデータベースでは、特定の期間(4時間など)に「アクティブ」なデータはわずか20%である可能性があります。アクティブなデータをすべてキャッシュしたい場合、200GBのRAMが必要になる可能性があります。その200GBのRAMのうち、高度に利用されているのはわずか20%である可能性があります。
使用されるキャッシュメモリのうち、キャッシュへのすべてのヒットの90%はRAMのわずか10%によって実現されます。残りの90%のRAMは、10%しか占めていません。
ただし、RAM使用量の90%を削減すると、ミス率が少なくとも2倍になり、DBへの負荷が2倍になります。バックエンドシステムのパフォーマンスによっては、RAMの一部を失うと、バックエンドコストが
2倍になる可能性があります。
メモリ内のアイテムを分解すると、大部分(上記のケースでは97.2%)がRAMのわずか30%以内に存在することがわかります。少数の大きいが、それでも
重要なアイテムが他の70%を占めます。
さらに大きなアイテムは、RAMを非常に早く消費する可能性があります。
これらの大きなアイテムは、ネットワーク使用率の大きな割合を占める可能性があることに注意してください。1つの8kリクエストは、80個以上の小さいリクエストと同じ帯域幅を使用します。
extstoreはどのように役立ちますか? 大きく、最近使用されていないアイテムの値をキーから分割してディスクにポインタで示すことで、使用頻度の低いRAMの大部分を節約できます。ユースケースに応じて、次のことが可能です。
- 全体のRAMを削減する:大きなアイテムがたくさんある場合は、100GBから30GB以下に削減します。
- 同じRAMでヒット率を上げる:大きなアイテムをディスクに移動し、小さいアイテムの長いテールをキャッシュし、ヒット率を上げてバックエンドコストを削減します。
- サーバー数を減らす:ネットワークに余裕があり(破損したサーバーの損失に対応できる場合!)、キャッシュフリートのサイズを削減できます。
- 全体的なキャッシュを増やす:サーバーごとに数百ギガバイトのキャッシュ容量を簡単に追加します。
- 以前は高価すぎたオブジェクトをキャッシュする:ビッグデータストア、機械学習トレーニングデータなどから事前に計算されたデータをキャッシュして、大きなオブジェクトを含む新しいプールを作成します。
他のワークロードの変動は問題ないですか? 上記の例では、キャッシュヒットは均等に分散しています。この理論上のシステムには400,000のIO制限があり、これはハイエンドSSDまたはOptaneドライブと同等であるはずです。この場合、RAMにネットワークを飽和させることを依存することはできません。
400,000 IOPSでは、10G NICを飽和させるには、平均でわずか3072バイトが必要です。25Gの場合は8192。適切に設計されたクラスターでは、プール内の成長、使用量の急増、または障害に備えて、追加のマージンが必要です。つまり、平均1024バイトまでのアイテムサイズが可能になる可能性がありますが、1024bでは(キーあたり100バイトのオーバーヘッドを想定)、extstoreはRAMに収まる量の10倍しかディスクに保存できません。
慎重なキャパシティプランニングが必要です。
- 何台の故障したマシンを許容できますか? 故障したマシンごとに、キャッシュの割合が失われます。
- 必要なネットワーク帯域幅はどれくらいですか? サーバー数を減らすと、ネットワーク密度が高くなります。
- 必要なIOPSはどれくらいですか? アクセスのほとんどは最近のデータに対するものであり、ディスクへの依存が少なくなります。
- 必要なレイテンシ保証は何ですか? キャッシュベースのディスクルックアップがバックエンドよりもまだはるかに高速な場合。
- アイテムの有効期間はどれくらいですか? SSDは、焼き切れる前に一定量の書き込みしか許容しません。
誰もが外部ストレージと互換性のあるワークロードを持っているわけではありません。キャッシュプールでRAMがどのように使用されているかを慎重に評価してから、キャッシュにディスクを使用してください。小さなアイテムのみ、短いTTL、または高い書き込み率がある場合は、RAMの方がまだ安価です。この計算は、「1日のドライブ書き込み量」に対するSSDの許容度を監視することによって行われます。1TBのデバイスが1日に2TBの書き込みで5年間動作できる場合、許容度は2 DWPDです。Optaneの許容度は30DWPDと高く、ハイエンドフラッシュドライブは3〜6DWPDです。
テストセットアップ
テストは、32コア、192GBのRAM、4TB SSD、および3つのOptane 750GBドライブを搭載したIntel Xeonマシンで実行されました。テスト中に使用されたOptaneドライブは1つだけです。この記事の執筆時点では、extstoreは1つのドライブでのみ機能し、この構成がほとんどのユーザーを反映しています。
- テストの実行には、mc-crusherが使用されました。具体的には、test-optaneスクリプトを含む3番目のタグです。
- mc-crusherは、可能な限り高速に実行するように設計されています。応答を解析せず、syscallごとにできるだけ多くのクエリをスタックし、時間を計測しようとしません。このテストでは、localhostに対して実行されましたが、CPUの単一コアしか使用しませんでした。
-
test-optaneスクリプトは、テストで使用される構成を具体的に記述しています。Memcachedは、32個のワーカースレッドを使用するように構成されました(マシンにはハイパースレッドを備えた64個のコアがあります)。
- mc-crusherの「balloon」プログラムを使用して125GBのRAMを占有し、1億個のキーをmemcachedにロードして、extstoreが単にバッファプールを使用するのを防ぎました。
各テスト実行中、mc-crusherクライアントの数とサーバー内のextstore IOスレッドの数が変更されました。IOスレッドが少なすぎるとデバイスが飽和せず、多すぎると過負荷になり、キューが発生する可能性があります。
各テストは、ウォームアップ後1分間実行されます。
レイテンシとスループットの測定
mc-crusherは結果を計測しないため、結果データを生成するために2つのスクリプトが使用されました。
- bench-sample:memcachedに対して「stats」コマンドを定期的に実行し、そのカウンターを使用して平均スループットを判断します。データは数秒ごとにサンプリングされ、有意な標準偏差がないか検査されました。
- latency-sample:ブロックするmemcachedクライアントのふりをして、bench-sampleが実行されているのと同時に、時間経過とともにリクエストを「サンプリング」するスクリプト。これは、「95パーセンタイル」のようなトラップを回避するために使用され、外れ値またはグループ化を削除し、誤解を招く結果を引き起こします。
すべてのテストについて、レイテンシサンプルの完全な内訳が提供されます。サンプリングは、1ミリ秒あたり最大1回のレートで実行されました。
注:イベントループは使用されていません。これは、同時にイベントのスタックが発生した場合、処理されるのを待つ時間として経過時間を判断する必要がないようにするためです。
テスト
3つの一般的なテストが実行されました。
- ASCIIマルチゲット:このモードでは、extstoreは応答を生成するために使用するパケットを最小限に抑え、内部でリクエストを大量にパイプライン化できます。レイテンシの低いデバイスは、このテストでより簡単に高いスループットを達成できます。
- パイプライン化された取得:多くの取得リクエストが同じパケットにスタックされますが、extstoreは各リクエストを個別に処理する必要があります。これらのテストでは、extstoreはOSのバッファリングされたIOを提供する能力(kswapdカーネルスレッドが最大化されました)を簡単に飽和させることができましたが、レイテンシーグラフでは、Optaneはフラッシュドライブの1/10のレイテンシーを維持できることが示されています。
- クライアント負荷が高い場合、パイプライン化された取得は奇妙に見える場合があります。これにはさらに調査が必要ですが、おそらく内部のキューが原因です。mc-crusherは非常にアグレッシブであるため、Optaneドライブは、はるかに少ないIOスレッドとクラッシャークライアントでシステムを飽和させることができます。本番環境のワークロードでは、Optaneははるかに安定した低レイテンシーサービスを提供します。
- マルチゲット+パイプライン化された設定:前の2つのワークロードは読み取り専用でした。このテストでは、memcachedに対して設定も、約1/3〜1/5のレートで実行されます。extstoreは、読み取りが行われているのと同じタイミングでドライブにフラッシュしています。ここでも、Optaneが強力な結果を出しています。
結果
残念ながら、グラフには多少の変動があります。これは、テスト中にRAMの空きが少なすぎるために発生します。Optaneのパフォーマンスは安定していましたが、OSは追いつくのに苦労しました。
参考までに:memcachedのこの正確な構成(32スレッドなど)に対する純粋なRAMマルチゲットロードテストでは、1秒あたり1,800万個のキーになります。さらに作為的なベンチマークでは、多くのコアを備えたサーバーで1秒あたり5,000万個のキーを超えるようになりました。
extstore IOスレッド数が少ない場合、OptaneドライブはIO制限にかなり近い飽和状態に達することができます。4スレッド、4クライアントの場合、Optaneは230k IOPS、SSDは40k IOPSを達成します。レイテンシの内訳を見ると、SSDは通常、待ち時間が1桁高く、Optaneは10usの範囲に留まるのに対し、SSDは100usとなり、1msに達することもあります。
extstore IOスレッド数が多い場合、基盤となるOSが飽和状態になり、Optaneのグラフに変動やキューイングが発生します。一方、SSDはフラッシュからのレイテンシを克服するために、より多くのスレッドリソースの恩恵を受け続けます。
多くのワークロードにおいて、SSDとOptaneの両方が完全に実行可能です。読み取りの大部分がRAMから来ており、extstoreは大きなオブジェクトのテール部分のみを処理するために使用される場合、両方ともリクエストを1ms以内の応答時間で維持できます。
extstoreの限界を押し広げたい場合、Optaneのようなドライブが非常に役立ちます。
- 高い書き込み耐性はキャッシュワークロードに適しています。
- 非常に低いレイテンシは、ディスクからキャッシュデータを要求することのトレードオフを滑らかにするのに役立ちます。
- 現在のところ、小型であることは有利です。extstoreはディスク上のすべての値に対してRAMを必要とするからです。375Gから1TBのディスクは、特定のマシンで必要なRAMが大幅に少なく、2TB以上は安全なフェイルオーバーを許可したり、NICの飽和を避けたりするにはおそらく密度が高すぎるでしょう。
テストタイプ
SSD IOスレッド数
Optane IOスレッド数
学習事項
- extstoreのフラッシャーは、LRUを管理するコードと組み合わされたバックグラウンドスレッドです。ベンチマーク中、セットは常にサーバーに送信されるため、extstoreのフラッシュが枯渇する可能性があります。本番環境では、memcachedへの挿入レートは、ミリ秒単位であっても波のように発生する傾向があるため、追いつくことができます。これは、独自のスレッドとしてより一貫したパフォーマンスを発揮します。
- レイテンシのサンプリングは難しいです。現在のスクリプトは役立つデータを提供しますが、より良いプログラムは、サーバーが一時停止しているのか、それとも一部のリクエストが単に遅いのかを判断できるように、ミリ秒ごとに1つのリクエストをブロッキングスレッドのプールに送信します。すべてのサンプルの完全なタイミングを保存してグラフ化することもできます。これにより、基盤となるOSまたはドライブから発生する可能性のある応答のクラスタリングを視覚化できます。
- バッファ付きI/Oには制限があります。これは事前に認識されていました。ほとんどのワークロードは1秒あたり数十万回以下の操作であり、そのほとんどはextstoreではなくRAMに対して行われます。当面は安定性に重点を置いていますが、最終的にはダイレクトIOと非同期IOによって、高負荷時のデバイスをより有効に活用できるようになります。
- extstoreのバケット化により、従来のフラッシュと並行してOptaneを使用するという非常に興味深い組み合わせが可能になる可能性があります。内部では、extstoreはデータをディスクスペースの「ページ」(通常64M)に整理します。新しいアイテムは特定のページにクラスタ化されます。TTLの短いアイテムは一緒にクラスタ化できます。ページ圧縮を生き残ったアイテムもクラスタ化されるため、時間の経過に伴う圧縮の必要性が減ります。すべての新しいアイテムやTTLの短いアイテムは、375GのOptaneドライブに配置し、圧縮されたアイテムは1TBのフラッシュドライブに配置することで、さらにコストを削減できます。
結論
コストのために現在不可能だったワークロードが可能になりました。混合データサイズと大規模なプールを含むほとんどのワークロードは、大幅なコスト削減を実現できます。
extstoreはディスク上のアイテムごとにRAMを必要とします。このグラフは、アイテムあたり100バイトのオーバーヘッド(キー+メタデータ)を想定して、アイテムサイズが大きくなるにつれてRAMのオーバーヘッドがどのように低下するかを視覚化しています。
DRAMのコストは、ドライブによって異なりますが、Optaneの3〜4倍、SSDの4〜8倍です。
キャッシュがRAMからOptane(またはフラッシュ)に移行すると、RAMのみに費やされるお金は1/3にまで減少する可能性があります。
RAMを削減すると、非常に高密度のRAMを実現するためにマルチソケットサーバーへの依存度が低下します。NUMA対応のマシンがしばしば必要になります。これらには、複数のソケット、複数のCPUがあり、RAMの半分が各CPUに接続されています。memcachedは非常に効率的であるため、RAMを削減できるだけでなく、RAMを削減すると、マザーボード/CPUの半分、さらには電力コストも削減できます。特定のワークロードでは最大80%のコスト削減が妥当です。
高速で低レイテンシのSSDは、データベースとキャッシュ設計の新しい時代を切り開きます。コスト削減とキャッシュ使用量の拡大の両方において、幅広いユースケースで高いパフォーマンス数値を示します。