You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/api-reference/automatic-compaction-api.md
+62-2Lines changed: 62 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,6 +37,14 @@ Instead of the automatic compaction API, you can use the supervisor API to submi
37
37
38
38
In this topic, `http://ROUTER_IP:ROUTER_PORT` is a placeholder for your Router service address and port. Replace it with the information for your deployment. For example, use `http://localhost:8888` for quickstart deployments.
39
39
40
+
## Concurrency control with ETag and If-Match
41
+
42
+
The automatic compaction write endpoints support optimistic concurrency control using HTTP `ETag` and `If-Match`. `GET /druid/coordinator/v1/config/compaction` returns an `ETag` header whose value is a stable hash of the underlying compaction configuration document (the union of cluster-level config and all per-datasource configs).
43
+
44
+
To guard a write against concurrent updates, pass the most recently observed ETag back in an `If-Match` header on `POST` or `DELETE`. The change only commits if the stored configuration still hashes to that ETag; otherwise the request fails with `409 Conflict`. Re-`GET` to obtain the new value and ETag, re-apply your change, and retry. The `If-Match` header is optional; requests without it preserve the previous last-writer-wins behavior. `If-Match: *` matches any existing configuration.
45
+
46
+
Endpoints with this behavior: `POST /druid/coordinator/v1/config/compaction`, `DELETE /druid/coordinator/v1/config/compaction/{dataSource}`, `POST /druid/coordinator/v1/config/compaction/taskslots`, and the unified `POST /druid/indexer/v1/compaction/config/cluster`. See the equivalent section in the [Dynamic configuration API](./dynamic-configuration-api.md#concurrency-control-with-etag-and-if-match) for the general protocol and a client-flow example. Note that automatic compaction returns `409 Conflict` rather than `412 Precondition Failed` because the underlying error category maps to 409.
47
+
40
48
## Manage automatic compaction
41
49
42
50
### Create or update automatic compaction configuration
@@ -51,6 +59,12 @@ Note that this endpoint returns an HTTP `200 OK` message code even if the dataso
51
59
52
60
`POST``/druid/coordinator/v1/config/compaction`
53
61
62
+
#### Header parameters
63
+
64
+
*`If-Match`
65
+
* Type: String
66
+
* Optional. Quoted ETag previously returned by `GET /druid/coordinator/v1/config/compaction`. When supplied, the update only commits if the stored compaction configuration still matches this ETag. Pass `*` to require only that some value is already stored. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
67
+
54
68
#### Responses
55
69
56
70
<Tabs>
@@ -60,6 +74,12 @@ Note that this endpoint returns an HTTP `200 OK` message code even if the dataso
60
74
61
75
*Successfully submitted auto compaction configuration*
62
76
77
+
</TabItem>
78
+
<TabItemvalue="1b"label="409 CONFLICT">
79
+
80
+
81
+
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
82
+
63
83
</TabItem>
64
84
</Tabs>
65
85
@@ -140,6 +160,12 @@ Removes the automatic compaction configuration for a datasource. This updates th
* Optional. Quoted ETag previously returned by `GET /druid/coordinator/v1/config/compaction`. When supplied, the delete only commits if the stored compaction configuration still matches this ETag. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
168
+
143
169
#### Responses
144
170
145
171
<Tabs>
@@ -155,6 +181,12 @@ Removes the automatic compaction configuration for a datasource. This updates th
155
181
156
182
*Datasource does not have automatic compaction or invalid datasource name*
157
183
184
+
</TabItem>
185
+
<TabItemvalue="5b"label="409 CONFLICT">
186
+
187
+
188
+
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
189
+
158
190
</TabItem>
159
191
</Tabs>
160
192
@@ -215,6 +247,12 @@ To limit the maximum number of compaction tasks, use the optional query paramete
215
247
* Default: 2147483647
216
248
* Limits the maximum number of task slots for compaction tasks.
217
249
250
+
#### Header parameters
251
+
252
+
*`If-Match`
253
+
* Type: String
254
+
* Optional. Quoted ETag previously returned by `GET /druid/coordinator/v1/config/compaction`. When supplied, the update only commits if the stored compaction configuration still matches this ETag. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
255
+
218
256
#### Responses
219
257
220
258
<Tabs>
@@ -230,6 +268,12 @@ To limit the maximum number of compaction tasks, use the optional query paramete
230
268
231
269
*Invalid `max` value*
232
270
271
+
</TabItem>
272
+
<TabItemvalue="9b"label="409 CONFLICT">
273
+
274
+
275
+
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
276
+
233
277
</TabItem>
234
278
</Tabs>
235
279
@@ -270,6 +314,8 @@ Retrieves all automatic compaction configurations. Returns a `compactionConfigs`
270
314
271
315
You can use this endpoint to retrieve `compactionTaskSlotRatio` and `maxCompactionTaskSlots` values for managing resource allocation of compaction tasks.
272
316
317
+
The response includes an `ETag` header that you can pass back in `If-Match` on a subsequent write to detect concurrent updates; see [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
318
+
273
319
#### URL
274
320
275
321
`GET``/druid/coordinator/v1/config/compaction`
@@ -281,7 +327,7 @@ You can use this endpoint to retrieve `compactionTaskSlotRatio` and `maxCompacti
*Successfully retrieved automatic compaction configurations. The `ETag` response header carries an opaque identifier for the returned configuration version.*
285
331
286
332
</TabItem>
287
333
</Tabs>
@@ -926,6 +972,12 @@ This policy specifies the datasources and intervals eligible for compaction and
* Optional. Quoted ETag previously returned by `GET /druid/indexer/v1/compaction/config/cluster` (or `GET /druid/coordinator/v1/config/compaction`, since both reflect the same underlying configuration). When supplied, the update only commits if the stored configuration still matches this ETag. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
980
+
929
981
#### Responses
930
982
931
983
<Tabs>
@@ -941,6 +993,12 @@ This policy specifies the datasources and intervals eligible for compaction and
941
993
942
994
*Invalid `max` value*
943
995
996
+
</TabItem>
997
+
<TabItemvalue="9b"label="409 CONFLICT">
998
+
999
+
1000
+
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
1001
+
944
1002
</TabItem>
945
1003
</Tabs>
946
1004
@@ -1002,6 +1060,8 @@ A successful request returns an HTTP `200 OK` message code and an empty response
1002
1060
Retrieves cluster-level configuration for compaction tasks which applies to all datasources, unless explicitly overridden in the datasource compaction config.
1003
1061
This includes all the fields listed in [Update cluster-level compaction config](#update-cluster-level-compaction-config).
1004
1062
1063
+
The response includes an `ETag` header that you can pass back in `If-Match` on a subsequent write; see [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
*Successfully retrieved cluster compaction configuration. The `ETag` response header carries an opaque identifier for the returned configuration version.*
Copy file name to clipboardExpand all lines: docs/api-reference/dynamic-configuration-api.md
+60-5Lines changed: 60 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,14 +33,40 @@ In this topic, `http://ROUTER_IP:ROUTER_PORT` is a placeholder for your Router s
33
33
Replace it with the information for your deployment.
34
34
For example, use `http://localhost:8888` for quickstart deployments.
35
35
36
+
## Concurrency control with ETag and If-Match
37
+
38
+
Without coordination, two concurrent updates to the same dynamic configuration silently overwrite each other—the last writer wins and the earlier writer has no signal that their change was lost. To prevent this, the dynamic configuration endpoints support an optimistic-concurrency-control protocol modeled on HTTP `ETag` and `If-Match`:
39
+
40
+
* Every `GET` response for a dynamic configuration includes an `ETag` header. The value is a stable hash of the stored configuration bytes—identical bytes always produce the same ETag.
41
+
* On a `POST` (or `DELETE`), supply the ETag you last observed in an `If-Match` header. The server only commits the change if the currently stored configuration still hashes to that ETag.
42
+
* If another writer changed the configuration after your read, your request fails with `412 Precondition Failed` (or `409 Conflict` for automatic compaction endpoints—see [Automatic compaction API](./automatic-compaction-api.md)). Re-`GET` to obtain the new value and ETag, re-apply your change, and retry.
43
+
* The `If-Match` header is **optional**. Requests without it preserve the previous last-writer-wins behavior.
44
+
*`If-Match: *` is supported and matches any existing configuration (it only fails if no value has been stored yet).
curl -X POST "http://ROUTER_IP:ROUTER_PORT/druid/coordinator/v1/config" \
54
+
-H "Content-Type: application/json" \
55
+
-H "If-Match: $ETAG" \
56
+
-d @new-config.json
57
+
# 200 on success, 412 if someone else updated the config in between.
58
+
```
59
+
60
+
Endpoints that support this protocol are noted individually below.
61
+
36
62
## Coordinator dynamic configuration
37
63
38
64
The Coordinator has dynamic configurations to tune certain behavior on the fly, without requiring a service restart.
39
65
For information on the supported properties, see [Coordinator dynamic configuration](../configuration/index.md#dynamic-configuration).
40
66
41
67
### Get dynamic configuration
42
68
43
-
Retrieves the current Coordinator dynamic configuration. Returns a JSON object with the dynamic configuration properties.
69
+
Retrieves the current Coordinator dynamic configuration. Returns a JSON object with the dynamic configuration properties. The response includes an `ETag` header that can be used with `If-Match` on a subsequent update; see [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
44
70
45
71
#### URL
46
72
@@ -53,7 +79,7 @@ Retrieves the current Coordinator dynamic configuration. Returns a JSON object w
53
79
<TabItemvalue="1"label="200 SUCCESS">
54
80
55
81
56
-
*Successfully retrieved dynamic configuration*
82
+
*Successfully retrieved dynamic configuration. The `ETag` response header carries an opaque identifier for the returned configuration version.*
57
83
58
84
</TabItem>
59
85
</Tabs>
@@ -136,6 +162,9 @@ The endpoint supports a set of optional header parameters to populate the `autho
136
162
*`X-Druid-Comment`
137
163
* Type: String
138
164
* Description for the update.
165
+
*`If-Match`
166
+
* Type: String
167
+
* Optional. Quoted ETag previously returned by `GET /druid/coordinator/v1/config`. When supplied, the update only commits if the currently stored configuration still matches this ETag. Pass `*` to require only that some value is already stored. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
139
168
140
169
#### Responses
141
170
@@ -146,6 +175,12 @@ The endpoint supports a set of optional header parameters to populate the `autho
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
183
+
149
184
</TabItem>
150
185
</Tabs>
151
186
@@ -319,7 +354,7 @@ These settings control broker behavior such as query blocking rules and default
319
354
320
355
### Get broker dynamic configuration
321
356
322
-
Retrieves the current Broker dynamic configuration. Returns a JSON object with the dynamic configuration properties.
357
+
Retrieves the current Broker dynamic configuration. Returns a JSON object with the dynamic configuration properties. The response includes an `ETag` header that can be used with `If-Match` on a subsequent update; see [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
323
358
324
359
#### URL
325
360
@@ -332,7 +367,7 @@ Retrieves the current Broker dynamic configuration. Returns a JSON object with t
*Successfully retrieved broker dynamic configuration. The `ETag` response header carries an opaque identifier for the returned configuration version.*
336
371
337
372
</TabItem>
338
373
</Tabs>
@@ -412,6 +447,10 @@ The endpoint supports a set of optional header parameters to populate the audit
412
447
* Type: String
413
448
* Comment describing the change.
414
449
450
+
*`If-Match`
451
+
* Type: String
452
+
* Optional. Quoted ETag previously returned by `GET /druid/coordinator/v1/broker/config`. When supplied, the update only commits if the currently stored configuration still matches this ETag. Pass `*` to require only that some value is already stored. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
453
+
415
454
#### Responses
416
455
417
456
<Tabs>
@@ -421,6 +460,12 @@ The endpoint supports a set of optional header parameters to populate the audit
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
468
+
424
469
</TabItem>
425
470
</Tabs>
426
471
@@ -719,6 +764,7 @@ For information on the supported properties, see [Overlord dynamic configuration
719
764
Retrieves the current Overlord dynamic configuration.
720
765
Returns a JSON object with the dynamic configuration properties.
721
766
Returns an empty response body if there is no current Overlord dynamic configuration.
767
+
When a configuration is present, the response includes an `ETag` header that can be used with `If-Match` on a subsequent update; see [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
722
768
723
769
#### URL
724
770
@@ -731,7 +777,7 @@ Returns an empty response body if there is no current Overlord dynamic configura
731
777
<TabItemvalue="10"label="200 SUCCESS">
732
778
733
779
734
-
*Successfully retrieved dynamic configuration*
780
+
*Successfully retrieved dynamic configuration. When a configuration is stored, the `ETag` response header carries an opaque identifier for the returned configuration version.*
735
781
736
782
</TabItem>
737
783
</Tabs>
@@ -799,6 +845,9 @@ The endpoint supports a set of optional header parameters to populate the `autho
799
845
*`X-Druid-Comment`
800
846
* Type: String
801
847
* Description for the update.
848
+
*`If-Match`
849
+
* Type: String
850
+
* Optional. Quoted ETag previously returned by `GET /druid/indexer/v1/worker`. When supplied, the update only commits if the currently stored configuration still matches this ETag. Pass `*` to require only that some value is already stored. See [Concurrency control with ETag and If-Match](#concurrency-control-with-etag-and-if-match).
802
851
803
852
#### Responses
804
853
@@ -809,6 +858,12 @@ The endpoint supports a set of optional header parameters to populate the `autho
*The `If-Match` header did not match the currently stored configuration, or another writer committed a change between this request's precondition check and write. Re-read the configuration and retry.*
Copy file name to clipboardExpand all lines: extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/execution/KubernetesTaskExecutionConfigResource.java
0 commit comments