ストレージのメモリー使用量ベンチマーク
etcdのストレージでは、2つの構成要素が物理メモリーを消費します。etcdプロセスは、キーの検索を高速化するためにインメモリーインデックスを割り当てます。また、オペレーティングシステムが管理するプロセスのページキャッシュには、最近ディスクから読み込んだデータが保存され、すばやく再利用できます。
インメモリーインデックスは、ディスク上のデータ(値)へのポインターとともに、すべてのキーをB木 のデータ構造で保持します。B木の各キーには、値の異なるバージョンを指す複数のポインターが含まれる場合があります。そのため、インメモリーインデックスの理論上のメモリー消費量は、次の式で近似できます。
N * (c1 + avg_key_size) + N * (avg_versions_of_key) * (c2 + size_of_pointer)
ここで、c1はキーのメタデータのオーバーヘッド、c2はバージョンのメタデータのオーバーヘッドです。
次の図は、インメモリーインデックスのB木の詳細な構造を示します。
ページキャッシュのメモリー はオペレーティングシステムが管理するため、このドキュメントでは詳しく扱いません。
テスト環境
etcdのバージョン
GCEのn1-standard-2マシンタイプ
- メモリー:7.5 GB
- CPU:2基
インメモリーインデックスのメモリー使用量
このテストでは、インメモリーインデックスのメモリー使用量のみを測定します。目的は、前述のc1とc2を求め、ストレージのメモリー消費量の厳密な限界を把握することです。
Goのruntime.ReadMemStatsを使い、インデックス作成前後の総割り当てバイト数の差から、メモリー消費量を算出します。インメモリーインデックス自体の使用量を完全に反映するわけではありませんが、おおよその消費傾向を把握できます。
| N | バージョン数 | キーサイズ | メモリー使用量 |
|---|---|---|---|
| 100K | 1 | 64bytes | 22MB |
| 100K | 5 | 64bytes | 39MB |
| 1M | 1 | 64bytes | 218MB |
| 1M | 5 | 64bytes | 432MB |
| 100K | 1 | 256bytes | 41MB |
| 100K | 5 | 256bytes | 65MB |
| 1M | 1 | 256bytes | 409MB |
| 1M | 5 | 256bytes | 506MB |
結果から、c1=120bytes、c2=30bytesと計算できます。式の未知数はこの2つだけなので、c1とc2の算出には2組のデータだけが必要です。c1=120bytesとc2=30bytesは、計算した4組のc1とc2の平均値です。小さなキー・バリューペアに対しては、キーのメタデータのオーバーヘッドは依然として無視できない大きさ(50%)です。しかし、少なくとも1000%のオーバーヘッドがあった旧ストアからは大幅に改善しています。
全体のメモリー使用量
全体のメモリー使用量は、ストレージを含めたetcdのRSS消費量を測定したものです。値はディスクに保存し、頻繁に使う値だけをOSのページキャッシュで管理するメモリーに保持するため、値のサイズがetcd全体のメモリー使用量に与える影響はごく小さいはずです。
| N | バージョン数 | キーサイズ | 値のサイズ | メモリー使用量 |
|---|---|---|---|---|
| 100K | 1 | 64bytes | 256bytes | 40MB |
| 100K | 5 | 64bytes | 256bytes | 89MB |
| 1M | 1 | 64bytes | 256bytes | 470MB |
| 1M | 5 | 64bytes | 256bytes | 880MB |
| 100K | 1 | 64bytes | 1KB | 102MB |
| 100K | 5 | 64bytes | 1KB | 164MB |
| 1M | 1 | 64bytes | 1KB | 587MB |
| 1M | 5 | 64bytes | 1KB | 836MB |
結果から、値のサイズはメモリー消費量に大きな影響を与えないことがわかります。OSのページキャッシュに保持されるデータが増えるため、わずかな増加は見られます。