# etcd APIの保証

> etcd APIが提供する保証

---

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

---

etcdは、一貫性と耐久性を備えたキー・バリューストアです。
キー・バリューストアは[gRPCサービス][gRPC Services]を通じて公開されます。
etcdは、分散システムで最も強い一貫性と耐久性の保証を提供します。
この仕様では、etcd APIが提供する保証を列挙します。

### 対象のAPI {#apis-to-consider}

* KV API
  * [Range](/ja/docs/etcd/learning/api/#range)
  * [RangeStream](/ja/docs/etcd/learning/api/#rangestream)
  * [Put](/ja/docs/etcd/learning/api/#put)
  * [Delete](/ja/docs/etcd/learning/api/#delete-range)
  * [トランザクション](/ja/docs/etcd/learning/api/#transaction)
* Watch API
  * [Watch](/ja/docs/etcd/learning/api/#watch-api)
* Lease API
  * [Grant](/ja/docs/etcd/learning/api/#obtaining-leases)
  * [Revoke]
  * [キープアライブ](/ja/docs/etcd/learning/api/#keep-alives)

KV APIは、キー・バリューストアの直接の読み取りと操作を提供します。
Watch APIは、キー・バリューストアの変更の購読を提供します。
Lease APIは、キーへの生存時間の割り当てを提供します。

KV APIとWatch APIのどちらでも、キーの最新バージョンだけでなく、
コンパクション操作によって制限される連続した履歴の範囲内で、
過去のバージョンにもアクセスできます。

KV APIの呼び出しは直ちに反映されますが、Watch APIの応答には上限のない遅延が生じます。
正常に動作するetcdクラスターでは、イベント発生から10ms程度の遅延で監視イベントが届くことを期待できます。
ただし、遅延に上限はなく、健全でないクラスターではイベントが届かないこともあります。

## KV API {#kv-apis}

etcdは、すべてのKV API呼び出しに対し、耐久性と厳密な直列化可能性を保証します。
これは、分散トランザクションデータベースシステムにおける最も強い分離保証です。

### 耐久性 {#durability}

完了した操作にはすべて耐久性があります。アクセス可能なデータも、すべて永続化済みのデータです。
読み取りが、まだ永続化されていないデータを返すことはありません。

### 厳密な直列化可能性 {#strict-serializability}

KVサービスの操作はアトミックであり、操作の実時間の順序と整合する全順序で実行されます。
この全順序は[リビジョン][revision]によって表されます。
詳細は[厳密な直列化可能性][strict serializability]を参照してください。

入れ子のTXNを含まないトランザクションでは、操作の実行順序は
操作リストの順序と一致することが保証されるため、トランザクション内の
GETレスポンスは安定しています。
入れ子のTXNを含むトランザクションでは、実行順序は規定されていません。

厳密な直列化可能性は、より理解しやすい、次の弱い保証も満たします。

#### 原子性 {#atomicity}

すべてのAPIリクエストはアトミックです。操作は全体が完了するか、まったく実行されないかのいずれかです。
監視リクエストでは、1つの操作が生成するすべてのイベントが1つの監視レスポンスに含まれます。
監視が、単一の操作のイベントの一部だけを観測することはありません。

#### 線形化可能性 {#linearizability}

クライアントの観点では、線形化可能性は動作を考えやすくする有用な性質を提供します。
[元の論文][linearizability]から、明快な説明を引用します。
`線形化可能性は、並行するプロセスが適用する各操作が、
その呼び出しから応答までの間のある時点で、
瞬時に有効になるかのように見せます。`

たとえば、クライアントが時点1（*t1*）で書き込みを完了したとします。
*t2*（*t2* > *t1*）で読み取りを発行したクライアントは、少なくとも
*t1*で完了した書き込みと同じか、それより新しい値を受け取るはずです。ただし、
読み取りが実際に完了するのは*t3*になる場合があります。線形化可能性は、
読み取りの開始時点*t2*から完了時点*t3*までの間のある時点で最新だった値を
返すことを保証します。読み取りの開始前に完了した書き込みはすべて反映されます。
*t2*と*t3*の間に発生した並行する書き込みは、反映される場合も、されない場合もあります。
返却値が、読み取りの完了時点で最新の値である必要はありません。

etcdは、その他のすべての操作について、デフォルトで線形化可能性を保証します。
ただし、線形化されたリクエストはRaftコンセンサス処理を経由する必要があるため、
線形化可能性にはコストが伴います。読み取りリクエストのレイテンシーを下げ、
スループットを高めるために、クライアントはリクエストの一貫性モードを
`serializable`に設定できます。このモードでは、クォーラムに対して古いデータに
アクセスする可能性がありますが、線形化されたアクセスがその都度のコンセンサスに
依存することによる性能上の負担をなくせます。

## Watch API {#watch-apis}

監視は、イベントについて次のことを保証します。
* 順序性：イベントはリビジョン順に並びます。
  すでに送信されたイベントより時間的に前のイベントが、後から監視に現れることはありません。
  入れ子のTXNを含まないトランザクションでは、生成されるイベントの順序は
  操作リストの順序と一致することが保証されます。
  入れ子のTXNを含むトランザクションでは、生成されるイベントの順序は
  規定されていません。
* 一意性：同じイベントが監視に2回現れることはありません。
* 信頼性：利用可能な履歴の範囲内で、イベント列の一部が欠落することはありません。
  イベントが時間順にa < b < cと並んでいる場合、
  監視がイベントaとcを受信したなら、bが利用可能な履歴の範囲内にある限り、
  bも受信することが保証されます。
* 原子性：イベントのリストは、完全なリビジョンを含むことが保証されます。
  同じリビジョンで行われた複数のキーの更新が、複数のイベントリストに
  分割されることはありません。
* 再開可能性：切断前に監視イベントで最後に受信したリビジョンが履歴の範囲内にある限り、
  そのリビジョンの次から新しい監視を開始することで、
  切断された監視を再開できます。
* ブックマーク可能性：進捗通知イベントは、あるリビジョンまでのすべてのイベントが
  すでに配信済みであることを保証します。

etcdは、監視操作の線形化可能性を保証しません。他の操作との正しい順序を確保するため、
ユーザーは監視イベントのリビジョンを確認する必要があります。

## Lease API {#lease-apis}

etcdは[リースの仕組み][lease]を提供します。リースの主な用途は、
分散ロックなどの分散協調の仕組みを実装することです。
リース自体の仕組みは単純です。grant APIで作成し、put APIでキーに関連付け、
revoke APIで取り消すことができ、実時間の生存時間（TTL）が過ぎると期限切れになります。
ただし、正しい分散協調の仕組みを実装するには、
[APIとその使用上の重要な性質][why]を理解しておく必要があります。

## etcd固有の定義 {#etcd-specific-definitions}

### 操作の完了 {#operation-completed}

etcdの操作は、コンセンサスを通じてコミットされ、etcdのストレージエンジンによって
「実行」、つまり永続的に保存された時点で完了と見なされます。
クライアントはetcdサーバーからレスポンスを受信することで、操作の完了を認識します。
タイムアウトした場合や、クライアントとetcdメンバーの間でネットワークが途絶した場合、
クライアントには操作の状態を判断できないことがあります。また、etcdはリーダー選挙が
発生すると操作を中止する場合があります。このとき、クライアントの未完了のリクエストに対して、
etcdは`abort`レスポンスを送信しません。

### リビジョン {#revision}

キー・バリューストアを変更するetcdの操作には、増加するリビジョンが1つ割り当てられます。
トランザクション操作はキー・バリューストアを複数回変更することがありますが、
割り当てられるリビジョンは1つだけです。操作によって変更されたキー・バリューペアの
リビジョン属性は、その操作のリビジョンと同じ値を持ちます。
リビジョンは、キー・バリューストアの論理時計として使用できます。
リビジョンが大きいキー・バリューペアは、リビジョンが小さいキー・バリューペアより後に
変更されています。同じリビジョンを持つ2つのキー・バリューペアは、
1つの操作によって「同時に」変更されています。

[grpc Services]: /ja/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]: /ja/docs/etcd/learning/api/#transaction
[why]: /ja/docs/etcd/learning/why/#notes-on-the-usage-of-lock-and-lease
[revision]: #revision
