Skip to content

Commit 6e6f8d4

Browse files
committed
Changes
1 parent b00fc11 commit 6e6f8d4

File tree

5 files changed

+122
-67
lines changed

5 files changed

+122
-67
lines changed

server/src/main/java/org/elasticsearch/action/bulk/IncrementalBulkService.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static class Handler implements Releasable {
9797

9898
private final ArrayList<Releasable> releasables = new ArrayList<>(4);
9999
private final ArrayList<BulkResponse> responses = new ArrayList<>(2);
100-
private final IndexingPressure.Coordinating coordinatingOperation;
100+
private final IndexingPressure.Incremental incrementalOperation;
101101
private boolean closed = false;
102102
private boolean globalFailure = false;
103103
private boolean incrementalRequestSubmitted = false;
@@ -116,10 +116,14 @@ protected Handler(
116116
this.waitForActiveShards = waitForActiveShards != null ? ActiveShardCount.parseString(waitForActiveShards) : null;
117117
this.timeout = timeout;
118118
this.refresh = refresh;
119-
this.coordinatingOperation = indexingPressure.markCoordinatingOperationStarted(0, 0, false);
119+
this.incrementalOperation = indexingPressure.startIncrementalCoordinating(0, 0, false);
120120
createNewBulkRequest(EMPTY_STATE);
121121
}
122122

123+
public IndexingPressure.Incremental getIncrementalOperation() {
124+
return incrementalOperation;
125+
}
126+
123127
public void addItems(List<DocWriteRequest<?>> items, Releasable releasable, Runnable nextItems) {
124128
assert closed == false;
125129
assert bulkInProgress == false;
@@ -129,7 +133,8 @@ public void addItems(List<DocWriteRequest<?>> items, Releasable releasable, Runn
129133
} else {
130134
assert bulkRequest != null;
131135
if (internalAddItems(items, releasable)) {
132-
if (coordinatingOperation.shouldSplit()) {
136+
if (incrementalOperation.shouldSplit()) {
137+
IndexingPressure.Coordinating coordinating = incrementalOperation.split();
133138
final boolean isFirstRequest = incrementalRequestSubmitted == false;
134139
incrementalRequestSubmitted = true;
135140
final ArrayList<Releasable> toRelease = new ArrayList<>(releasables);
@@ -151,7 +156,7 @@ public void onFailure(Exception e) {
151156
}
152157
}, () -> {
153158
bulkInProgress = false;
154-
coordinatingOperation.releaseCurrent();
159+
coordinating.close();
155160
toRelease.forEach(Releasable::close);
156161
nextItems.run();
157162
}));
@@ -172,6 +177,7 @@ public void lastItems(List<DocWriteRequest<?>> items, Releasable releasable, Act
172177
} else {
173178
assert bulkRequest != null;
174179
if (internalAddItems(items, releasable)) {
180+
IndexingPressure.Coordinating coordinating = incrementalOperation.split();
175181
final ArrayList<Releasable> toRelease = new ArrayList<>(releasables);
176182
releasables.clear();
177183
// We do not need to set this back to false as this will be the last request.
@@ -192,7 +198,7 @@ public void onFailure(Exception e) {
192198
errorResponse(listener);
193199
}
194200
}, () -> {
195-
coordinatingOperation.releaseCurrent();
201+
coordinating.close();
196202
toRelease.forEach(Releasable::close);
197203
}));
198204
} else {
@@ -205,15 +211,15 @@ public void onFailure(Exception e) {
205211
public void close() {
206212
if (closed == false) {
207213
closed = true;
208-
coordinatingOperation.close();
214+
incrementalOperation.close();
209215
releasables.forEach(Releasable::close);
210216
releasables.clear();
211217
}
212218
}
213219

214220
private void shortCircuitDueToTopLevelFailure(List<DocWriteRequest<?>> items, Releasable releasable) {
215221
assert releasables.isEmpty();
216-
assert coordinatingOperation.currentSize() == 0;
222+
assert incrementalOperation.currentOperationsSize() == 0;
217223
assert bulkRequest == null;
218224
if (globalFailure == false) {
219225
addItemLevelFailures(items);
@@ -258,11 +264,11 @@ private boolean internalAddItems(List<DocWriteRequest<?>> items, Releasable rele
258264
bulkRequest.add(items);
259265
releasables.add(releasable);
260266
long size = items.stream().mapToLong(Accountable::ramBytesUsed).sum();
261-
coordinatingOperation.increment(items.size(), size);
267+
incrementalOperation.increment(items.size(), size);
262268
return true;
263269
} catch (EsRejectedExecutionException e) {
264270
handleBulkFailure(incrementalRequestSubmitted == false, e);
265-
coordinatingOperation.releaseCurrent();
271+
incrementalOperation.split().close();
266272
releasables.forEach(Releasable::close);
267273
releasables.clear();
268274
return false;

server/src/main/java/org/elasticsearch/index/IndexingPressure.java

Lines changed: 98 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -138,24 +138,111 @@ private static Releasable wrapReleasable(Releasable releasable) {
138138
};
139139
}
140140

141+
public Incremental startIncrementalCoordinating(int operations, long bytes, boolean forceExecution) {
142+
Incremental coordinating = new Incremental(forceExecution);
143+
coordinating.coordinating.increment(operations, bytes);
144+
return coordinating;
145+
}
146+
141147
public Coordinating markCoordinatingOperationStarted(int operations, long bytes, boolean forceExecution) {
142148
Coordinating coordinating = new Coordinating(forceExecution);
143149
coordinating.increment(operations, bytes);
144150
return coordinating;
145151
}
146152

153+
public class Incremental implements Releasable {
154+
155+
private final AtomicBoolean closed = new AtomicBoolean();
156+
private final boolean forceExecution;
157+
private long currentUnparsedSize = 0;
158+
private long totalParsedBytes = 0;
159+
private Coordinating coordinating;
160+
161+
public Incremental(boolean forceExecution) {
162+
this.forceExecution = forceExecution;
163+
this.coordinating = new Coordinating(forceExecution);
164+
}
165+
166+
public long totalParsedBytes() {
167+
return totalParsedBytes;
168+
}
169+
170+
public void incrementUnparsedBytes(long bytes) {
171+
assert closed.get() == false;
172+
// TODO: Implement integration with IndexingPressure for unparsed bytes
173+
currentUnparsedSize += bytes;
174+
}
175+
176+
public void transferUnparsedBytesToParsed(long bytes) {
177+
assert closed.get() == false;
178+
assert currentUnparsedSize >= bytes;
179+
currentUnparsedSize -= bytes;
180+
totalParsedBytes += bytes;
181+
}
182+
183+
public void increment(int operations, long bytes) {
184+
// TODO: Eventually most of the memory will already be accounted for in unparsed.
185+
coordinating.increment(operations, bytes);
186+
}
187+
188+
public long currentOperationsSize() {
189+
return coordinating.currentOperationsSize;
190+
}
191+
192+
public boolean shouldSplit() {
193+
long currentUsage = (currentCombinedCoordinatingAndPrimaryBytes.get() + currentReplicaBytes.get());
194+
long currentOperationsSize = coordinating.currentOperationsSize;
195+
if (currentUsage >= highWatermark && currentOperationsSize >= highWatermarkSize) {
196+
highWaterMarkSplits.getAndIncrement();
197+
logger.trace(
198+
() -> Strings.format(
199+
"Split bulk due to high watermark: current bytes [%d] and size [%d]",
200+
currentUsage,
201+
currentOperationsSize
202+
)
203+
);
204+
return true;
205+
}
206+
if (currentUsage >= lowWatermark && currentOperationsSize >= lowWatermarkSize) {
207+
lowWaterMarkSplits.getAndIncrement();
208+
logger.trace(
209+
() -> Strings.format(
210+
"Split bulk due to low watermark: current bytes [%d] and size [%d]",
211+
currentUsage,
212+
currentOperationsSize
213+
)
214+
);
215+
return true;
216+
}
217+
return false;
218+
}
219+
220+
public Coordinating split() {
221+
Coordinating toReturn = coordinating;
222+
coordinating = new Coordinating(forceExecution);
223+
return toReturn;
224+
}
225+
226+
@Override
227+
public void close() {
228+
coordinating.close();
229+
}
230+
}
231+
232+
// TODO: Maybe this should be re-named and used for primary operations too. Eventually we will need to account for: ingest pipeline
233+
// expansions, reading updates, etc. This could just be a generic OP that could be expanded as appropriate
147234
public class Coordinating implements Releasable {
148235

149236
private final AtomicBoolean closed = new AtomicBoolean();
150237
private final boolean forceExecution;
151238
private int currentOperations = 0;
152-
private long currentSize = 0;
239+
private long currentOperationsSize = 0;
153240

154241
public Coordinating(boolean forceExecution) {
155242
this.forceExecution = forceExecution;
156243
}
157244

158-
public void increment(int operations, long bytes) {
245+
private void increment(int operations, long bytes) {
159246
assert closed.get() == false;
160247
long combinedBytes = currentCombinedCoordinatingAndPrimaryBytes.addAndGet(bytes);
161248
long replicaWriteBytes = currentReplicaBytes.get();
@@ -186,7 +273,7 @@ public void increment(int operations, long bytes) {
186273
);
187274
}
188275
currentOperations += operations;
189-
currentSize += bytes;
276+
currentOperationsSize += bytes;
190277
logger.trace(() -> Strings.format("adding [%d] coordinating operations and [%d] bytes", operations, bytes));
191278
currentCoordinatingBytes.getAndAdd(bytes);
192279
currentCoordinatingOps.getAndAdd(operations);
@@ -196,43 +283,17 @@ public void increment(int operations, long bytes) {
196283
totalCoordinatingRequests.getAndIncrement();
197284
}
198285

199-
public long currentSize() {
200-
return currentSize;
201-
}
202-
203-
public void releaseCurrent() {
204-
currentCombinedCoordinatingAndPrimaryBytes.getAndAdd(-currentSize);
205-
currentCoordinatingBytes.getAndAdd(-currentSize);
206-
currentCoordinatingOps.getAndAdd(-currentOperations);
207-
currentSize = 0;
208-
currentOperations = 0;
209-
}
210-
211-
public boolean shouldSplit() {
212-
long currentUsage = (currentCombinedCoordinatingAndPrimaryBytes.get() + currentReplicaBytes.get());
213-
if (currentUsage >= highWatermark && currentSize >= highWatermarkSize) {
214-
highWaterMarkSplits.getAndIncrement();
215-
logger.trace(
216-
() -> Strings.format("Split bulk due to high watermark: current bytes [%d] and size [%d]", currentUsage, currentSize)
217-
);
218-
return true;
219-
}
220-
if (currentUsage >= lowWatermark && currentSize >= lowWatermarkSize) {
221-
lowWaterMarkSplits.getAndIncrement();
222-
logger.trace(
223-
() -> Strings.format("Split bulk due to low watermark: current bytes [%d] and size [%d]", currentUsage, currentSize)
224-
);
225-
return true;
226-
}
227-
return false;
228-
229-
}
230-
231286
@Override
232287
public void close() {
233288
if (closed.compareAndSet(false, true)) {
234-
logger.trace(() -> Strings.format("removing [%d] coordinating operations and [%d] bytes", currentOperations, currentSize));
235-
releaseCurrent();
289+
logger.trace(
290+
() -> Strings.format("removing [%d] coordinating operations and [%d] bytes", currentOperations, currentOperationsSize)
291+
);
292+
currentCombinedCoordinatingAndPrimaryBytes.getAndAdd(-currentOperationsSize);
293+
currentCoordinatingBytes.getAndAdd(-currentOperationsSize);
294+
currentCoordinatingOps.getAndAdd(-currentOperations);
295+
currentOperationsSize = 0;
296+
currentOperations = 0;
236297
} else {
237298
logger.error("IndexingPressure memory is adjusted twice", new IllegalStateException("Releasable is called twice"));
238299
assert false : "IndexingPressure is adjusted twice";

server/src/main/java/org/elasticsearch/rest/action/document/RestBulkAction.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ static class ChunkHandler implements BaseRestHandler.RequestBodyChunkConsumer {
155155

156156
private volatile RestChannel restChannel;
157157
private boolean shortCircuited;
158-
private int bytesParsed = 0;
159158
private final ArrayDeque<ReleasableBytesReference> unParsedChunks = new ArrayDeque<>(4);
160159
private final ArrayList<DocWriteRequest<?>> items = new ArrayList<>(4);
161160

@@ -202,6 +201,7 @@ public void handleChunk(RestChannel channel, ReleasableBytesReference chunk, boo
202201
bytesConsumed = 0;
203202
} else {
204203
try {
204+
handler.getIncrementalOperation().incrementUnparsedBytes(chunk.length());
205205
unParsedChunks.add(chunk);
206206

207207
if (unParsedChunks.size() > 1) {
@@ -210,10 +210,8 @@ public void handleChunk(RestChannel channel, ReleasableBytesReference chunk, boo
210210
data = chunk;
211211
}
212212

213-
// TODO: Check that the behavior here vs. globalRouting, globalPipeline, globalRequireAlias, globalRequireDatsStream in
214-
// BulkRequest#add is fine
215213
bytesConsumed = parser.parse(data, isLast);
216-
bytesParsed += bytesConsumed;
214+
handler.getIncrementalOperation().transferUnparsedBytesToParsed(bytesConsumed);
217215

218216
} catch (Exception e) {
219217
shortCircuit();
@@ -225,7 +223,7 @@ public void handleChunk(RestChannel channel, ReleasableBytesReference chunk, boo
225223
final ArrayList<Releasable> releasables = accountParsing(bytesConsumed);
226224
if (isLast) {
227225
assert unParsedChunks.isEmpty();
228-
if (bytesParsed == 0) {
226+
if (handler.getIncrementalOperation().totalParsedBytes() == 0) {
229227
shortCircuit();
230228
new RestToXContentListener<>(channel).onFailure(new ElasticsearchParseException("request body is required"));
231229
} else {

server/src/test/java/org/elasticsearch/index/IndexingPressureTests.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,18 @@ public void testHighAndLowWatermarkSplits() {
4141
IndexingPressure indexingPressure = new IndexingPressure(settings);
4242

4343
try (
44-
IndexingPressure.Coordinating coordinating1 = indexingPressure.markCoordinatingOperationStarted(
45-
10,
46-
randomIntBetween(1, 127),
47-
false
48-
);
49-
IndexingPressure.Coordinating coordinating2 = indexingPressure.markCoordinatingOperationStarted(
44+
IndexingPressure.Incremental coordinating1 = indexingPressure.startIncrementalCoordinating(10, randomIntBetween(1, 127), false);
45+
IndexingPressure.Incremental coordinating2 = indexingPressure.startIncrementalCoordinating(
5046
10,
5147
randomIntBetween(128, 1023),
5248
false
5349
);
54-
IndexingPressure.Coordinating coordinating3 = indexingPressure.markCoordinatingOperationStarted(
50+
IndexingPressure.Incremental coordinating3 = indexingPressure.startIncrementalCoordinating(
5551
10,
5652
randomIntBetween(1024, 6000),
5753
false
5854
);
59-
Releasable ignored1 = indexingPressure.markCoordinatingOperationStarted(
55+
Releasable ignored1 = indexingPressure.startIncrementalCoordinating(
6056
10,
6157
1 + (8 * 1024) - indexingPressure.stats().getCurrentCoordinatingBytes(),
6258
false

server/src/test/java/org/elasticsearch/rest/action/document/RestBulkActionTests.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.client.internal.Client;
2121
import org.elasticsearch.common.bytes.BytesArray;
2222
import org.elasticsearch.common.bytes.ReleasableBytesReference;
23+
import org.elasticsearch.common.settings.Settings;
2324
import org.elasticsearch.core.Releasable;
2425
import org.elasticsearch.http.HttpBody;
2526
import org.elasticsearch.index.IndexVersion;
@@ -42,11 +43,7 @@
4243
import static org.hamcrest.Matchers.empty;
4344
import static org.hamcrest.Matchers.equalTo;
4445
import static org.hamcrest.Matchers.hasSize;
45-
import static org.mockito.ArgumentMatchers.anyBoolean;
46-
import static org.mockito.ArgumentMatchers.anyInt;
47-
import static org.mockito.ArgumentMatchers.anyLong;
4846
import static org.mockito.Mockito.mock;
49-
import static org.mockito.Mockito.when;
5047

5148
/**
5249
* Tests for {@link RestBulkAction}.
@@ -228,10 +225,7 @@ public void next() {
228225
.build();
229226
FakeRestChannel channel = new FakeRestChannel(request, randomBoolean(), 1);
230227

231-
IndexingPressure indexingPressure = mock(IndexingPressure.class);
232-
when(indexingPressure.markCoordinatingOperationStarted(anyInt(), anyLong(), anyBoolean())).thenReturn(
233-
mock(IndexingPressure.Coordinating.class)
234-
);
228+
IndexingPressure indexingPressure = new IndexingPressure(Settings.EMPTY);
235229
RestBulkAction.ChunkHandler chunkHandler = new RestBulkAction.ChunkHandler(true, request, () -> {
236230
return new IncrementalBulkService.Handler(null, indexingPressure, null, null, null) {
237231

0 commit comments

Comments
 (0)