# 監視のメモリー使用量ベンチマーク

> etcdのウォッチャーの性能測定

---

LLMSインデックス: [llms.txt](/ja/llms.txt)

---

> [!NOTE]
> 監視機能は活発に開発されているため、開発が進むにつれてメモリー使用量が変わる可能性があります。ただし、以下の数値を大幅に超えて増えることは想定していません。

etcdの主な目標の1つは、非常に多くのウォッチャーが膨大な数の監視を行えるようにすることです。etcdは、O(10k)のクライアント、O(100K)の監視ストリーム（クライアントあたりO(10)ストリーム）、合計O(10M)の監視（ストリームあたりO(100)の監視）への対応を目指しています。個々の監視が消費するメモリーは、etcd全体の使用量の中で最も大きな割合を占めるため、現在および今後の最適化の重点となっています。


etcdの監視では、関連する3つの構成要素、すなわち各`grpc.Conn`、各監視ストリーム、各監視インスタンスが物理メモリーを消費します。`grpc.Conn`は実際のTCP接続とその他のgRPC接続状態を保持します。各`grpc.Conn`はO(10kb)のメモリーを消費し、複数の監視ストリームが接続されることがあります。

各監視ストリームは独立したHTTP2接続で、さらにO(10kb)のメモリーを消費します。
複数の監視で1つの監視ストリームを共有できます。

監視インスタンスは、キー・バリューストアの変更を追跡する実際の構造体です。各監視のメモリー消費量はO(1kb)未満に収まるはずです。

```
                                          +-------+
                                          | watch |
                              +---------> | foo   |
                              |           +-------+
                       +------+-----+
                       |   stream   |
      +--------------> |            |
      |                +------+-----+     +-------+
      |                       |           | watch |
      |                       +---------> | bar   |
+-----+------+                            +-------+
|            |         +------------+
|   conn     +-------> |   stream   |
|            |         |            |
+-----+------+         +------------+
      |
      |
      |
      |                +------------+
      +--------------> |   stream   |
                       |            |
                       +------------+
```

監視の理論上のメモリー消費量は、次の式で近似できます。
`memory = c1 * number_of_conn + c2 * avg_number_of_stream_per_conn + c3 * avg_number_of_watch_stream`

## テスト環境 {#testing-environment}

etcdのバージョン
- git head https://github.com/etcd-io/etcd/commit/185097ffaa627b909007e772c175e8fefac17af3

GCEのn1-standard-2マシンタイプ
- メモリー：7.5 GB
- CPU：2基

## 全体のメモリー使用量 {#overall-memory-usage}

全体のメモリー使用量は、クライアントのウォッチャーを接続したetcdが消費する[RSS][rss]を測定したものです。結果には最大10%程度のばらつきがありますが、おおよそのメモリー使用量と割り当ての傾向を把握するという目的には意味があります。

ベンチマーク結果から、おおよそ`c1 = 17kb`、`c2 = 18kb`、`c3 = 350bytes`と計算できます。つまり、クライアント接続を1つ追加すると17kb、ストリームを1つ追加すると18kbのメモリーを消費しますが、監視を1つ追加したときの消費量はわずか350bytesです。通常、1台のetcdサーバーで、数GBのメモリーを使って数百万の監視を維持できます。


| クライアント数 | クライアントあたりのストリーム数 | ストリームあたりの監視数 | 監視の総数 | メモリー使用量 |
|---------|---------|-----------|----------------|--------------|
| 1k |  1 |   1 |   1k |   50MB |
| 2k |  1 |   1 |   2k |   90MB |
| 5k |  1 |   1 |   5k |  200MB |
| 1k | 10 |   1 |  10k |  217MB |
| 2k | 10 |   1 |  20k |  417MB |
| 5k | 10 |   1 |  50k |  980MB |
| 1k | 50 |   1 |  50k | 1001MB |
| 2k | 50 |   1 | 100k | 1960MB |
| 5k | 50 |   1 | 250k | 4700MB |
| 1k | 50 |  10 | 500k | 1171MB |
| 2k | 50 |  10 |   1M | 2371MB |
| 5k | 50 |  10 | 2.5M | 5710MB |
| 1k | 50 | 100 |   5M | 2380MB |
| 2k | 50 | 100 |  10M | 4672MB |
| 5k | 50 | 100 |  25M |  *OOM* |

[rss]: https://en.wikipedia.org/wiki/Resident_set_size
