|
@@ -68,6 +68,7 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
private final IngestService ingestService;
|
|
|
private final IngestActionForwarder ingestForwarder;
|
|
|
protected final LongSupplier relativeTimeNanosProvider;
|
|
|
+ protected final Executor coordinationExecutor;
|
|
|
protected final Executor writeExecutor;
|
|
|
protected final Executor systemWriteExecutor;
|
|
|
private final ActionType<BulkResponse> bulkAction;
|
|
@@ -92,6 +93,7 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
this.indexingPressure = indexingPressure;
|
|
|
this.systemIndices = systemIndices;
|
|
|
this.projectResolver = projectResolver;
|
|
|
+ this.coordinationExecutor = threadPool.executor(ThreadPool.Names.WRITE_COORDINATION);
|
|
|
this.writeExecutor = threadPool.executor(ThreadPool.Names.WRITE);
|
|
|
this.systemWriteExecutor = threadPool.executor(ThreadPool.Names.SYSTEM_WRITE);
|
|
|
this.ingestForwarder = new IngestActionForwarder(transportService);
|
|
@@ -106,8 +108,8 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
* This is called on the Transport thread so we can check the indexing
|
|
|
* memory pressure *quickly* but we don't want to keep the transport
|
|
|
* thread busy. Then, as soon as we have the indexing pressure in we fork
|
|
|
- * to one of the write thread pools. We do this because juggling the
|
|
|
- * bulk request can get expensive for a few reasons:
|
|
|
+ * to the coordinator thread pool for coordination tasks. We do this because
|
|
|
+ * juggling the bulk request can get expensive for a few reasons:
|
|
|
* 1. Figuring out which shard should receive a bulk request might require
|
|
|
* parsing the _source.
|
|
|
* 2. When dispatching the sub-requests to shards we may have to compress
|
|
@@ -131,14 +133,15 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
releasable = indexingPressure.markCoordinatingOperationStarted(indexingOps, indexingBytes, isOnlySystem);
|
|
|
}
|
|
|
final ActionListener<BulkResponse> releasingListener = ActionListener.runBefore(listener, releasable::close);
|
|
|
- final Executor executor = isOnlySystem ? systemWriteExecutor : writeExecutor;
|
|
|
- ensureClusterStateThenForkAndExecute(task, bulkRequest, executor, releasingListener);
|
|
|
+ // Use coordinationExecutor for dispatching coordination tasks
|
|
|
+ ensureClusterStateThenForkAndExecute(task, bulkRequest, coordinationExecutor, isOnlySystem, releasingListener);
|
|
|
}
|
|
|
|
|
|
private void ensureClusterStateThenForkAndExecute(
|
|
|
Task task,
|
|
|
BulkRequest bulkRequest,
|
|
|
Executor executor,
|
|
|
+ boolean isOnlySystem,
|
|
|
ActionListener<BulkResponse> releasingListener
|
|
|
) {
|
|
|
final ClusterState initialState = clusterService.state();
|
|
@@ -160,7 +163,7 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
clusterStateObserver.waitForNextChange(new ClusterStateObserver.Listener() {
|
|
|
@Override
|
|
|
public void onNewClusterState(ClusterState state) {
|
|
|
- forkAndExecute(task, bulkRequest, executor, releasingListener);
|
|
|
+ forkAndExecute(task, bulkRequest, executor, isOnlySystem, releasingListener);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -174,21 +177,32 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
}
|
|
|
}, newState -> false == newState.blocks().hasGlobalBlockWithLevel(projectId, ClusterBlockLevel.WRITE));
|
|
|
} else {
|
|
|
- forkAndExecute(task, bulkRequest, executor, releasingListener);
|
|
|
+ forkAndExecute(task, bulkRequest, executor, isOnlySystem, releasingListener);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void forkAndExecute(Task task, BulkRequest bulkRequest, Executor executor, ActionListener<BulkResponse> releasingListener) {
|
|
|
+ private void forkAndExecute(
|
|
|
+ Task task,
|
|
|
+ BulkRequest bulkRequest,
|
|
|
+ Executor executor,
|
|
|
+ boolean isOnlySystem,
|
|
|
+ ActionListener<BulkResponse> releasingListener
|
|
|
+ ) {
|
|
|
executor.execute(new ActionRunnable<>(releasingListener) {
|
|
|
@Override
|
|
|
protected void doRun() throws IOException {
|
|
|
- applyPipelinesAndDoInternalExecute(task, bulkRequest, executor, releasingListener);
|
|
|
+ applyPipelinesAndDoInternalExecute(task, bulkRequest, executor, isOnlySystem, releasingListener);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- private boolean applyPipelines(Task task, BulkRequest bulkRequest, Executor executor, ActionListener<BulkResponse> listener)
|
|
|
- throws IOException {
|
|
|
+ private boolean applyPipelines(
|
|
|
+ Task task,
|
|
|
+ BulkRequest bulkRequest,
|
|
|
+ Executor executor,
|
|
|
+ boolean isOnlySystem,
|
|
|
+ ActionListener<BulkResponse> listener
|
|
|
+ ) throws IOException {
|
|
|
boolean hasIndexRequestsWithPipelines = false;
|
|
|
ClusterState state = clusterService.state();
|
|
|
ProjectId projectId = projectResolver.getProjectId();
|
|
@@ -277,7 +291,7 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
assert arePipelinesResolved : bulkRequest;
|
|
|
}
|
|
|
if (clusterService.localNode().isIngestNode()) {
|
|
|
- processBulkIndexIngestRequest(task, bulkRequest, executor, project, l);
|
|
|
+ processBulkIndexIngestRequest(task, bulkRequest, executor, isOnlySystem, project, l);
|
|
|
} else {
|
|
|
ingestForwarder.forwardIngestRequest(bulkAction, bulkRequest, l);
|
|
|
}
|
|
@@ -291,6 +305,7 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
Task task,
|
|
|
BulkRequest original,
|
|
|
Executor executor,
|
|
|
+ boolean isOnlySystem,
|
|
|
ProjectMetadata metadata,
|
|
|
ActionListener<BulkResponse> listener
|
|
|
) {
|
|
@@ -324,12 +339,12 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
ActionRunnable<BulkResponse> runnable = new ActionRunnable<>(actionListener) {
|
|
|
@Override
|
|
|
protected void doRun() throws IOException {
|
|
|
- applyPipelinesAndDoInternalExecute(task, bulkRequest, executor, actionListener);
|
|
|
+ applyPipelinesAndDoInternalExecute(task, bulkRequest, executor, isOnlySystem, actionListener);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean isForceExecution() {
|
|
|
- // If we fork back to a write thread we **not** should fail, because tp queue is full.
|
|
|
+ // If we fork back to a coordination thread we **not** should fail, because tp queue is full.
|
|
|
// (Otherwise the work done during ingest will be lost)
|
|
|
// It is okay to force execution here. Throttling of write requests happens prior to
|
|
|
// ingest when a node receives a bulk request.
|
|
@@ -337,7 +352,8 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
}
|
|
|
};
|
|
|
// If a processor went async and returned a response on a different thread then
|
|
|
- // before we continue the bulk request we should fork back on a write thread:
|
|
|
+ // before we continue the bulk request we should fork back on a coordination thread. Otherwise it is fine to perform
|
|
|
+ // coordination steps on the write thread
|
|
|
if (originalThread == Thread.currentThread()) {
|
|
|
runnable.run();
|
|
|
} else {
|
|
@@ -346,7 +362,8 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- executor
|
|
|
+ // Use the appropriate write executor for actual ingest processing
|
|
|
+ isOnlySystem ? systemWriteExecutor : writeExecutor
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -402,10 +419,11 @@ public abstract class TransportAbstractBulkAction extends HandledTransportAction
|
|
|
Task task,
|
|
|
BulkRequest bulkRequest,
|
|
|
Executor executor,
|
|
|
+ boolean isOnlySystem,
|
|
|
ActionListener<BulkResponse> listener
|
|
|
) throws IOException {
|
|
|
final long relativeStartTimeNanos = relativeTimeNanos();
|
|
|
- if (applyPipelines(task, bulkRequest, executor, listener) == false) {
|
|
|
+ if (applyPipelines(task, bulkRequest, executor, isOnlySystem, listener) == false) {
|
|
|
doInternalExecute(task, bulkRequest, executor, listener, relativeStartTimeNanos);
|
|
|
}
|
|
|
}
|