go.etcd.io/etcd@v3.3.27+incompatible/Documentation/rfc/_index.md (about) 1 --- 2 title: etcd v3 API 3 --- 4 5 The etcd v3 API is designed to give users a more efficient and cleaner abstraction compared to etcd v2. There are a number of semantic and protocol changes in this new API. For an overview [see Xiang Li's video](https://youtu.be/J5AioGtEPeQ?t=211). 6 7 To prove out the design of the v3 API the team has also built [a number of example recipes](https://github.com/coreos/etcd/tree/master/contrib/recipes), there is a [video discussing these recipes too](https://www.youtube.com/watch?v=fj-2RY-3yVU&feature=youtu.be&t=590). 8 9 # Design 10 11 1. Flatten binary key-value space 12 13 2. Keep the event history until compaction 14 - access to old version of keys 15 - user controlled history compaction 16 17 3. Support range query 18 - Pagination support with limit argument 19 - Support consistency guarantee across multiple range queries 20 21 4. Replace TTL key with Lease 22 - more efficient/ low cost keep alive 23 - a logical group of TTL keys 24 25 5. Replace CAS/CAD with multi-object Txn 26 - MUCH MORE powerful and flexible 27 28 6. Support efficient watching with multiple ranges 29 30 7. RPC API supports the completed set of APIs. 31 - more efficient than JSON/HTTP 32 - additional txn/lease support 33 34 8. HTTP API supports a subset of APIs. 35 - easy for people to try out etcd 36 - easy for people to write simple etcd application 37 38 39 ## Notes 40 41 ### Request Size Limitation 42 43 The max request size is around 1MB. Since etcd replicates requests in a streaming fashion, a very large 44 request might block other requests for a long time. The use case for etcd is to store small configuration 45 values, so we prevent user from submitting large requests. This also applies to Txn requests. We might loosen 46 the size in the future a little bit or make it configurable. 47 48 ## Protobuf Defined API 49 50 [api protobuf][api-protobuf] 51 52 [kv protobuf][kv-protobuf] 53 54 ## Examples 55 56 ### Put a key (foo=bar) 57 58 ``` 59 // A put is always successful 60 Put( PutRequest { key = foo, value = bar } ) 61 62 PutResponse { 63 cluster_id = 0x1000, 64 member_id = 0x1, 65 revision = 1, 66 raft_term = 0x1, 67 } 68 ``` 69 70 ### Get a key (assume we have foo=bar) 71 ``` 72 Get ( RangeRequest { key = foo } ) 73 74 RangeResponse { 75 cluster_id = 0x1000, 76 member_id = 0x1, 77 revision = 1, 78 raft_term = 0x1, 79 kvs = { 80 { 81 key = foo, 82 value = bar, 83 create_revision = 1, 84 mod_revision = 1, 85 version = 1; 86 }, 87 }, 88 } 89 ``` 90 91 ### Range over a key space (assume we have foo0=bar0… foo100=bar100) 92 ``` 93 Range ( RangeRequest { key = foo, end_key = foo80, limit = 30 } ) 94 95 RangeResponse { 96 cluster_id = 0x1000, 97 member_id = 0x1, 98 revision = 100, 99 raft_term = 0x1, 100 kvs = { 101 { 102 key = foo0, 103 value = bar0, 104 create_revision = 1, 105 mod_revision = 1, 106 version = 1; 107 }, 108 ..., 109 { 110 key = foo30, 111 value = bar30, 112 create_revision = 30, 113 mod_revision = 30, 114 version = 1; 115 }, 116 }, 117 } 118 ``` 119 120 ### Finish a txn (assume we have foo0=bar0, foo1=bar1) 121 ``` 122 Txn(TxnRequest { 123 // mod_revision of foo0 is equal to 1, mod_revision of foo1 is greater than 1 124 compare = { 125 {compareType = equal, key = foo0, mod_revision = 1}, 126 {compareType = greater, key = foo1, mod_revision = 1}} 127 }, 128 // if the comparison succeeds, put foo2 = bar2 129 success = {PutRequest { key = foo2, value = success }}, 130 // if the comparison fails, put foo2=fail 131 failure = {PutRequest { key = foo2, value = failure }}, 132 ) 133 134 TxnResponse { 135 cluster_id = 0x1000, 136 member_id = 0x1, 137 revision = 3, 138 raft_term = 0x1, 139 succeeded = true, 140 responses = { 141 // response of PUT foo2=success 142 { 143 cluster_id = 0x1000, 144 member_id = 0x1, 145 revision = 3, 146 raft_term = 0x1, 147 } 148 } 149 } 150 ``` 151 152 ### Watch on a key/range 153 154 ``` 155 Watch( WatchRequest{ 156 key = foo, 157 end_key = fop, // prefix foo 158 start_revision = 20, 159 end_revision = 10000, 160 // server decided notification frequency 161 progress_notification = true, 162 } 163 … // this can be a watch request stream 164 ) 165 166 // put (foo0=bar0) event at 3 167 WatchResponse { 168 cluster_id = 0x1000, 169 member_id = 0x1, 170 revision = 3, 171 raft_term = 0x1, 172 event_type = put, 173 kv = { 174 key = foo0, 175 value = bar0, 176 create_revision = 1, 177 mod_revision = 1, 178 version = 1; 179 }, 180 } 181 … 182 183 // a notification at 2000 184 WatchResponse { 185 cluster_id = 0x1000, 186 member_id = 0x1, 187 revision = 2000, 188 raft_term = 0x1, 189 // nil event as notification 190 } 191 192 … 193 194 // put (foo0=bar3000) event at 3000 195 WatchResponse { 196 cluster_id = 0x1000, 197 member_id = 0x1, 198 revision = 3000, 199 raft_term = 0x1, 200 event_type = put, 201 kv = { 202 key = foo0, 203 value = bar3000, 204 create_revision = 1, 205 mod_revision = 3000, 206 version = 2; 207 }, 208 } 209 … 210 211 ``` 212 213 [api-protobuf]: https://github.com/etcd-io/etcd/blob/master/etcdserver/etcdserverpb/rpc.proto 214 [kv-protobuf]: https://github.com/etcd-io/etcd/blob/master/mvcc/mvccpb/kv.proto