# Гарантии API etcd

> Гарантии API, предоставляемые etcd

---

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

---

etcd — согласованное и долговечное хранилище ключей и значений.
Доступ к нему предоставляют [службы gRPC][gRPC Services].
etcd обеспечивает наиболее строгие гарантии согласованности и долговечности
для распределённой системы. В этой спецификации перечислены гарантии API etcd.

### Рассматриваемые API {#apis-to-consider}

* KV APIs
  * [Range](/ru/docs/etcd/learning/api/#range)
  * [RangeStream](/ru/docs/etcd/learning/api/#rangestream)
  * [Put](/ru/docs/etcd/learning/api/#put)
  * [Delete](/ru/docs/etcd/learning/api/#delete-range)
  * [Transaction](/ru/docs/etcd/learning/api/#transaction)
* API наблюдения
  * [Watch](/ru/docs/etcd/learning/api/#watch-api)
* API аренды
  * [Grant](/ru/docs/etcd/learning/api/#obtaining-leases)
  * [Отзыв][Revoke]
  * [Keep alive](/ru/docs/etcd/learning/api/#keep-alives)

API KV позволяет напрямую читать и изменять хранилище ключей и значений.
API наблюдения позволяет подписываться на изменения хранилища.
API аренды позволяет назначать ключу время существования.

API KV и наблюдения предоставляют доступ не только к последним версиям ключей,
но и к предыдущим версиям в непрерывном окне истории, ограниченном операцией
компактизации.

Вызов API KV действует немедленно, тогда как API наблюдения возвращает события
с неограниченной задержкой. В исправном кластере etcd события наблюдения обычно
появляются через 10ms после возникновения. Однако верхней границы нет, и в
неисправном кластере события могут не поступить вовсе.

## API KV {#kv-apis}

etcd гарантирует долговечность и строгую сериализуемость всех вызовов API KV.
Это самые строгие гарантии изоляции распределённых транзакционных баз данных.

### Долговечность {#durability}

Любая завершённая операция долговечна. Все доступные данные также долговечны.
Чтение никогда не вернёт данные, которые не были сохранены долговечно.

### Строгая сериализуемость {#strict-serializability}

Операции службы KV атомарны и выполняются в полном порядке, согласованном с их
порядком в реальном времени. Полный порядок задаётся [ревизией][revision].
Подробнее см. [строгая сериализуемость][strict serializability].

В транзакциях без вложенных TXN порядок выполнения операций гарантированно
совпадает с порядком в списке, что обеспечивает стабильные ответы GET внутри
транзакции. Для транзакций с вложенными TXN порядок выполнения не определён.

Строгая сериализуемость подразумевает другие, более слабые и понятные гарантии:

#### Атомарность {#atomicity}

Все запросы API атомарны: операция либо завершается полностью, либо не выполняется
совсем. Для запросов наблюдения все события одной операции входят в один ответ.
Наблюдение никогда не видит частичные события отдельной операции.

#### Линеаризуемость {#linearizability}

С точки зрения клиента линеаризуемость предоставляет полезные свойства,
упрощающие рассуждения. В [оригинальной статье][linearizability] дано ясное
описание: `Linearizability provides the illusion
that each operation applied by concurrent processes takes effect instantaneously
at some point between its invocation and its response.`

Например, клиент завершает запись в момент 1 (*t1*). Клиент, начавший чтение в
*t2* (где *t2* > *t1*), должен получить значение не старее предыдущей записи,
завершённой в *t1*. Однако само чтение может завершиться только в *t3*.
Линеаризуемость гарантирует возврат самого актуального значения. Без неё
значение, актуальное в *t2* при начале чтения, может устареть к *t3*, поскольку
между *t2* и *t3* могла произойти параллельная запись.

По умолчанию etcd обеспечивает линеаризуемость всех остальных операций. За это
приходится платить: линеаризуемые запросы должны проходить через консенсус Raft.
Чтобы снизить задержку и повысить пропускную способность чтения, клиент может
выбрать для запроса режим согласованности `serializable`. Он допускает чтение
устаревших относительно кворума данных, но устраняет затраты на живой консенсус,
необходимый линеаризуемому доступу.

## API наблюдения {#watch-apis}

Наблюдения предоставляют следующие гарантии событий:
* Упорядоченность — события упорядочены по ревизии.
  В наблюдении не появится событие, которое по времени предшествует уже
  опубликованному. Для транзакций без вложенных TXN порядок создаваемых событий
  гарантированно совпадает с порядком операций в списке. Для транзакций с
  вложенными TXN порядок не определён.
* Уникальность — событие не появится в одном наблюдении дважды.
* Надёжность — последовательность не пропустит подпоследовательность событий в
  доступном окне истории. Если события упорядочены как a < b < c и наблюдение
  получает a и c, оно гарантированно получит b, пока b находится в доступном окне.
* Атомарность — список событий гарантированно охватывает полные ревизии.
  Обновления нескольких ключей в одной ревизии не разделяются между списками.
* Возобновляемость — прерванное наблюдение можно возобновить, создав новое после
  последней ревизии, полученной до разрыва, пока она находится в окне истории.
* Возможность закладки — события уведомления о ходе гарантируют, что все события
  до указанной ревизии уже доставлены.

etcd не гарантирует линеаризуемость операций наблюдения. Для правильного порядка
относительно других операций пользователи должны проверять ревизию событий.

## API аренды {#lease-apis}

etcd предоставляет [механизм аренды][lease]. Основной сценарий — реализация
распределённой координации, например распределённых блокировок. Механизм прост:
аренда создаётся API grant, привязывается к ключу API put, отзывается API revoke
и истекает по времени существования (TTL) настенных часов. Однако для правильной
распределённой координации необходимо учитывать [важные свойства API и их
использования][why].

## Определения, специфичные для etcd {#etcd-specific-definitions}

### Завершённая операция {#operation-completed}

Операция etcd считается завершённой, когда она зафиксирована через консенсус и,
следовательно, «выполнена» — навсегда сохранена — движком хранения etcd. Клиент
узнаёт о завершении, получив ответ сервера etcd. Если истёк тайм-аут или между
клиентом и участником etcd нарушилась сеть, статус операции может остаться
неопределённым для клиента. etcd также может прерывать операции во время выборов
лидера. В этом случае etcd не отправляет ответы `abort` на ожидающие запросы клиентов.

### Ревизия {#revision}

Операции etcd, изменяющей хранилище ключей и значений, назначается одна
возрастающая ревизия. Транзакция может изменить хранилище несколько раз, но
получает только одну ревизию. Атрибут ревизии изменённой пары «ключ — значение»
равен ревизии операции. Ревизию можно использовать как логические часы
хранилища. Пара с большей ревизией изменена после пары с меньшей. Две пары с
одинаковой ревизией изменены одной операцией «одновременно».

[grpc Services]: /ru/docs/etcd/learning/api/#grpc-services
[lease]: https://web.stanford.edu/class/cs240/readings/leases.pdf
[linearizability]: https://cs.brown.edu/~mph/HerlihyW90/p463-herlihy.pdf
[serializable_isolation]: https://en.wikipedia.org/wiki/Isolation_(database_systems)#Serializable
[strict serializability]: http://jepsen.io/consistency/models/strict-serializable
[txn]: /ru/docs/etcd/learning/api/#transaction
[why]: /ru/docs/etcd/learning/why/#notes-on-the-usage-of-lock-and-lease
[revision]: #revision
