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

Enhance memory accounting for document expansion and introduce max document size limit #123543

Merged
merged 14 commits into from
Mar 6, 2025

Conversation

fcofdez
Copy link
Contributor

@fcofdez fcofdez commented Feb 26, 2025

This commit improves memory accounting by incorporating document
expansion during shard bulk execution. Additionally, it introduces a new
limit on the maximum document size, which defaults to 5% of the
available heap.

This limit can be configured using the new setting:

  • indexing_pressure.memory.max_operation_size

These changes help prevent excessive memory consumption and
improve indexing stability.

Closes ES-10777

@fcofdez fcofdez added >enhancement :Distributed Indexing/CRUD A catch all label for issues around indexing, updating and getting a doc by id. Not search. Team:Distributed Indexing Meta label for Distributed Indexing team v9.1.0 labels Feb 26, 2025
@fcofdez fcofdez requested a review from Tim-Brooks February 26, 2025 19:48
@fcofdez fcofdez requested a review from a team as a code owner February 26, 2025 19:48
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed-indexing (Team:Distributed Indexing)

@elasticsearchmachine
Copy link
Collaborator

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

@@ -108,13 +114,17 @@ public class IndexingPressure {
private final AtomicLong lowWaterMarkSplits = new AtomicLong(0);
private final AtomicLong highWaterMarkSplits = new AtomicLong(0);

private final AtomicLong largeOpsRejections = new AtomicLong(0);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

My idea is to use this specific metrics related to large documents / expansion issues in autoscaling, that way we could have an idea of the extra memory that the nodes would need to cope with the load.

Copy link
Contributor

Choose a reason for hiding this comment

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

++

Copy link
Contributor

Warning

It looks like this PR modifies one or more .asciidoc files. These files are being migrated to Markdown, and any changes merged now will be lost. See the migration guide for details.

Copy link
Contributor

Warning

It looks like this PR modifies one or more .asciidoc files. These files are being migrated to Markdown, and any changes merged now will be lost. See the migration guide for details.

@@ -79,6 +79,12 @@ public class IndexingPressure {
Setting.Property.NodeScope
);

public static final Setting<ByteSizeValue> MAX_OPERATION_SIZE = Setting.memorySizeSetting(
"indexing_pressure.memory.max_operation_size",
"5%",
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems slightly breaking for small heaps, like 1GB heap now only allow 50MB docs. While this may be a good default, it could break some users too. Should we make it 10% here in the core code base for now?

Copy link
Contributor

@Tim-Brooks Tim-Brooks left a comment

Choose a reason for hiding this comment

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

This mostly looks good. I do have a question about accounting operation counts twice.

@@ -41,6 +41,8 @@ public class IndexingPressureStats implements Writeable, ToXContentFragment {
*/
private final long lowWaterMarkSplits;
private final long highWaterMarkSplits;
private final long largeOpsRejections;
private final long totalLargeRejectedOpsBytes;
Copy link
Contributor

Choose a reason for hiding this comment

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

We haven't tracked the number of byte rejected in the past. I'm guessing that maybe we think this could be useful for autoscaling?

Like divide bytes rejected / ops to get an idea of what we need to scale to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's the idea. But it's a bit tricky because we should make that value sticky somehow.

@@ -193,7 +204,49 @@ public Releasable markPrimaryOperationLocalToCoordinatingNodeStarted(int operati
});
}

public Releasable markPrimaryOperationStarted(int operations, long bytes, boolean forceExecution) {
public void checkLargestPrimaryOperationIsWithinLimits(
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason this should not be called from within markPrimaryOperationLocalToCoordinatingNodeStarted similar to validateAndMarkPrimaryOperationStarted?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, I added that method in f8b8814

) {
var listener = ActionListener.releaseBefore(
indexingPressure.trackPrimaryOperationExpansion(
primaryOperationCount(request),
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't think incrementing primary operations count a second time? I think we just want to do expansion memory here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have to pass the number of operations to increment the number of rejected operations if the expansion is beyond the current limit. (there's an if to only increment the rejections in the method)

@@ -108,13 +114,17 @@ public class IndexingPressure {
private final AtomicLong lowWaterMarkSplits = new AtomicLong(0);
private final AtomicLong highWaterMarkSplits = new AtomicLong(0);

private final AtomicLong largeOpsRejections = new AtomicLong(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

++

@@ -203,6 +256,10 @@ public Releasable markPrimaryOperationStarted(int operations, long bytes, boolea
this.currentCombinedCoordinatingAndPrimaryBytes.getAndAdd(-bytes);
this.primaryRejections.getAndIncrement();
this.primaryDocumentRejections.addAndGet(operations);
if (operationExpansionTracking) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. Does this make sense? We've already pass the "large document" check. And this just means we passed the primary limit when attempting to do the expansion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wasn't sure if we wanted to track expansions for autoscaling too, if you think that we shouldn't I can remove this.

Copy link
Contributor

Choose a reason for hiding this comment

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

I kind of feel like if we get to this point and it is not a "large document" this should count as a primary rejection only as it might be just a normal sized document.

However, I'm open to changing this if there is a logical reason from an autoscaling perspective why we want to treat this.

Copy link
Contributor

@Tim-Brooks Tim-Brooks left a comment

Choose a reason for hiding this comment

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

This looks good to me.

I made a comment about the large document vs. primary rejection. Although, I'm okay with either approach.

@fcofdez fcofdez merged commit 387eef0 into elastic:main Mar 6, 2025
17 checks passed
georgewallace pushed a commit to georgewallace/elasticsearch that referenced this pull request Mar 11, 2025
…cument size limit (elastic#123543)

This commit improves memory accounting by incorporating document
expansion during shard bulk execution. Additionally, it introduces a new
limit on the maximum document size, which defaults to 5% of the
available heap.

This limit can be configured using the new setting:

indexing_pressure.memory.max_operation_size
These changes help prevent excessive memory consumption and
improve indexing stability.

Closes ES-10777
costin pushed a commit to costin/elasticsearch that referenced this pull request Mar 15, 2025
…cument size limit (elastic#123543)

This commit improves memory accounting by incorporating document
expansion during shard bulk execution. Additionally, it introduces a new
limit on the maximum document size, which defaults to 5% of the
available heap.

This limit can be configured using the new setting:

indexing_pressure.memory.max_operation_size
These changes help prevent excessive memory consumption and
improve indexing stability.

Closes ES-10777
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed Indexing/CRUD A catch all label for issues around indexing, updating and getting a doc by id. Not search. >enhancement Team:Distributed Indexing Meta label for Distributed Indexing team v9.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants