# Тестирование использования памяти хранилищем

> Показатели производительности хранилища etcd (индекс в памяти и страничный кеш)

---

Индекс LLMS: [llms.txt](/ru/llms.txt)

---

<!---todo: link storage to storage design doc-->
Физическую память потребляют два компонента хранилища etcd. Для ускорения поиска ключей процесс etcd выделяет *индекс в памяти*. Управляемый операционной системой *страничный кеш* процесса хранит недавно прочитанные с диска данные для быстрого повторного использования.

Индекс в памяти хранит все ключи в структуре данных [B-tree][btree] вместе с указателями на данные на диске — значения. Каждый ключ в B-tree может содержать несколько указателей на разные версии значения. Поэтому теоретическое потребление памяти индексом можно приблизительно оценить формулой:

`N * (c1 + avg_key_size) + N * (avg_versions_of_key) * (c2 + size_of_pointer)`

где `c1` — накладные расходы метаданных ключа, а `c2` — накладные расходы метаданных версии.

На схеме показана подробная структура B-tree индекса в памяти.

```


                                In mem index

                               +------------+
                               | key || ... |
  +--------------+             |     ||     |
  |              |             +------------+
  |              |             | v1  || ... |
  |   disk    <----------------|     ||     | Tree Node
  |              |             +------------+
  |              |             | v2  || ... |
  |           <----------------+     ||     |
  |              |             +------------+
  +--------------+       +-----+    |   |   |
                         |     |    |   |   |
                         |     +------------+
                         |
                         |
                         ^
                      ------+
                      | ... |
                      |     |
                      +-----+
                      | ... | Tree Node
                      |     |
                      +-----+
                      | ... |
                      |     |
                      ------+
```

[Память страничного кеша][pagecache] управляется операционной системой и подробно в этом документе не рассматривается.

## Среда тестирования {#testing-environment}

Версия etcd

- git head https://github.com/etcd-io/etcd/commit/776e9fb7be7eee5e6b58ab977c8887b4fe4d48db

Тип машины GCE n1-standard-2

- 7.5 GB памяти
- 2x CPU

## Использование памяти индексом в памяти {#in-memory-index-memory-usage}

В этом тесте измеряется только потребление памяти индексом. Цель — найти упомянутые выше `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`. Для этого достаточно двух наборов данных, поскольку `c1` и `c2` — единственные неизвестные переменные в формуле. Значения `c1=120bytes` и `c2=30bytes` являются средними по 4 вычисленным наборам `c1` и `c2`. Для небольших пар «ключ — значение» накладные расходы метаданных ключа всё ещё заметны (50%). Тем не менее это значительно лучше старого хранилища, где накладные расходы составляли не менее 1000%.

## Общее использование памяти {#overall-memory-usage}

Общее использование памяти показывает, сколько RSS потребляет etcd вместе с хранилищем. Размер значения почти не должен влиять на общее потребление памяти 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        |

Результаты показывают, что размер значения не оказывает существенного влияния на потребление памяти. Небольшой рост связан с увеличением объёма данных в страничном кеше ОС.

[btree]: https://en.wikipedia.org/wiki/B-tree
[pagecache]: https://en.wikipedia.org/wiki/Page_cache
