Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iteratively execute synchronous ingest processors #84250

Merged
merged 25 commits into from
Apr 12, 2022

Conversation

danhermann
Copy link
Contributor

@danhermann danhermann commented Feb 22, 2022

Iteratively executes ingest processors that are not asynchronous. This resolves the issue of stack overflows that could occur in large ingest pipelines. As a secondary effect, it dramatically reduces the depth of the stack during ingest pipeline execution which reduces the performance cost of gathering a stack trace for any exceptions instantiated during pipeline execution. The aggregate performance effect of these changes has been observed to be a 10-15% improvement in some larger pipelines.

The primary changes required were adding iterative execution loops to CompoundProcessor and ForEachProcessor. Most of the other changes were consequences of changing those two processors.

Fixes #84274.

@danhermann danhermann added >enhancement :Data Management/Ingest Node Execution or management of Ingest Pipelines including GeoIP v8.2.0 labels Feb 22, 2022
@elasticsearchmachine
Copy link
Collaborator

Hi @danhermann, I've created a changelog YAML for you.

@danhermann danhermann marked this pull request as ready for review February 24, 2022 16:50
@elasticmachine elasticmachine added the Team:Data Management Meta label for data/management team label Feb 24, 2022
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-data-management (Team:Data Management)

@danhermann danhermann marked this pull request as draft February 24, 2022 16:51
@danhermann danhermann marked this pull request as ready for review March 4, 2022 15:09
@danhermann danhermann marked this pull request as draft March 4, 2022 15:10
@danhermann danhermann changed the title Ingest pipeline performance improvements Iteratively execute synchronous ingest processors Mar 5, 2022
@elasticsearchmachine
Copy link
Collaborator

Hi @danhermann, I've updated the changelog YAML for you.

@danhermann danhermann marked this pull request as ready for review March 5, 2022 18:40
@elastic elastic deleted a comment from elasticmachine Mar 7, 2022
@danhermann
Copy link
Contributor Author

@elasticmachine update branch

@masseyke
Copy link
Member

Adding a brief description of how CompoundProcessor works since I was initially thrown off:
It iterates through all non-async processors, executing them until it comes across an async processor. It then asynchronously executes that one and recurses a stack frame, where it again iterates through all non-async processors, executing them until it comes across an async processor. And so on. So we still have recursion, but only one level per async processor. The synchronous processors won't all run at the same level in the same for loop, but we're at least no longer going additional levels for each synchronous processor.

@masseyke
Copy link
Member

@elasticmachine update branch

@martijnvg
Copy link
Member

@elasticmachine update branch

@masseyke
Copy link
Member

@elasticmachine run elasticsearch-ci/bwc

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@masseyke
Copy link
Member

I ran a couple of rally tests to make sure that we don't see a performance regression with this. For all tests I used a one-node Elasticsearch cluster and a separate node running rally.
First I ran the ingest_pipeline:baseline track that comes with rally. This doesn't have many processors, but it was a good check that we hadn't accidentally messed up performance:

esrally race --pipeline=benchmark-only --target-hosts="http://10.10.26.75:9200/" --track="http_logs" --challenge="append-index-only-with-ingest-pipeline" --track-params="ingest_pipeline:baseline" --client-options=~/cluster2-client-options.json --on-error=abort --track-params="bulk_indexing_clients:16,number_of_shards:1"

The median throughput improved by about 4.5%.
Next I ran the solutions/logs track in rally-internal-tracks, after configuring it to use apache access logs for 100% of the data.

esrally race --pipeline=benchmark-only --target-hosts="http://10.10.26.75:9200"  --track="solutions/logs" --client-options=~/cluster2-client-options.json --on-error=abort  --track-repository=rally-internal-tracks --track-params="bulk_indexing_clients:16,number_of_shards:1" --kill-running-processes

I ran that multiple times (since the first run on a fresh ES was always slowest), and on the non-first runs I'm consistently seeing the Total Ingest Pipeline time before the change around 190s, and after the change around 170s, so an ~11% improvement.

@masseyke masseyke merged commit cce3d92 into elastic:master Apr 12, 2022
weizijun added a commit to weizijun/elasticsearch that referenced this pull request Apr 13, 2022
* upstream/master: (40 commits)
  Fix BuildTests serialization (elastic#85827)
  Use urgent priority for node shutdown cluster state update (elastic#85838)
  Remove Task classes from HLRC (elastic#85835)
  Remove unused migration classes (elastic#85834)
  Remove uses of Charset name parsing (elastic#85795)
  Remove legacy versioned logic for DefaultSystemMemoryInfo (elastic#85761)
  Expose proxy settings for GCS repositories (elastic#85785)
  Remove SLM classes from HLRC (elastic#85825)
  TSDB: fix the time_series in order collect priority (elastic#85526)
  Remove ILM classes from HLRC (elastic#85822)
  FastVectorHighlighter should use ValueFetchers to load source data (elastic#85815)
  Iteratively execute synchronous ingest processors (elastic#84250)
  Remove TransformClient from HLRC  (elastic#85787)
  Mute XPackRestIT deprecation/10_basic/Test Deprecations (elastic#85807)
  Unmute Lintian packaging test (elastic#85778)
  Add a highlighter unit test base class (elastic#85719)
  Remove NIO Transport Plugin (elastic#82085)
  [TEST] Remove token methods from HLRC SecurityClient (elastic#85515)
  [Test] Use thread-safe hashSet for result collection (elastic#85653)
  [TEST] Mute BuildTests.testSerialization (elastic#85801)
  ...

# Conflicts:
#	server/src/test/java/org/elasticsearch/search/aggregations/timeseries/TimeSeriesIndexSearcherTests.java
@DJRickyB
Copy link
Contributor

Thanks @masseyke for pushing this across the finish line. It had a positive impact on the notoriously hard-to-pin-down conditional processor as well as script and geoip in our nightly benchmarks. I have annotated the charts: https://elasticsearch-benchmarks.elastic.co/#tracks/logging/nightly/default/30d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Data Management/Ingest Node Execution or management of Ingest Pipelines including GeoIP >enhancement release highlight Team:Data Management Meta label for data/management team v8.3.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use of recursion rather than iteration in CompoundProcessor limits ingest pipeline length
8 participants