Skip to content

Coalesce getSortedNumeric calls for ES819 doc values merging #126732

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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

jordan-powers
Copy link
Contributor

When writing the doc values addresses, we currently perform an iteration over all the sorted numeric doc values to calculate the addresses. When merging sorted segments, this iteration is expensive as it requires performing a merge sort.

This patch removes this iteration by instead calculating the addresses while we are writing the values, writing the addresses addresses to a temporary file. Afterwards, they are copied from the temporary file into the merged segment.

Relates to #126111

@jordan-powers jordan-powers added >non-issue auto-backport Automatically create backport pull requests when merged :StorageEngine/Codec v8.19.0 v9.1.0 labels Apr 11, 2025
@jordan-powers jordan-powers self-assigned this Apr 11, 2025
@jordan-powers jordan-powers requested a review from martijnvg April 14, 2025 19:57
@jordan-powers jordan-powers marked this pull request as ready for review April 14, 2025 19:57
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-storage-engine (Team:StorageEngine)

String addressDataOutputName = null;
try (
var addressMetaOutput = new ByteBuffersIndexOutput(addressMetaBuffer, "meta-temp", "meta-temp");
// TODO: which IOContext should be used 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.

This comment was in Martijn's initial implementation, and I didn't know the answer, so I left it. I'd appreciate suggestions

Copy link
Member

@martijnvg martijnvg Apr 15, 2025

Choose a reason for hiding this comment

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

@dnhatn Do you think usage of IOContext.DEFAULT is ok here or is there a better IOContext that can be used here?

Copy link
Member

Choose a reason for hiding this comment

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

I think we need to do something like this: #126499 (comment)

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.

This looks good Jordan.

Would you be able to change the ES819TSDBDocValuesFormatTests#testForceMergeDenseCase() and ES819TSDBDocValuesFormatTests#testForceMergeSparseCase() tests by also indexing multi valued sorted numeric doc values? For example by randomly indexing gauge_2 field with multiple values? (similar to the tags field)

String addressDataOutputName = null;
try (
var addressMetaOutput = new ByteBuffersIndexOutput(addressMetaBuffer, "meta-temp", "meta-temp");
// TODO: which IOContext should be used here?
Copy link
Member

@martijnvg martijnvg Apr 15, 2025

Choose a reason for hiding this comment

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

@dnhatn Do you think usage of IOContext.DEFAULT is ok here or is there a better IOContext that can be used here?

@martijnvg
Copy link
Member

martijnvg commented Apr 15, 2025

I also re-ran the micro benchmark:

Benchmark                                                    (deltaTime)   (nDocs)  (seed)  Mode  Cnt     Score   Error  Units
TSDBDocValuesMergeBenchmark.forceMergeWithOptimizedMerge            1000  20431204      42    ss       4678.076          ms/op
TSDBDocValuesMergeBenchmark.forceMergeWithoutOptimizedMerge         1000  20431204      42    ss       7230.848          ms/op

Which looks better as was reported in #125403.

UPDATE:

Running the same micro benchmark from main branch:

Benchmark                                                    (deltaTime)   (nDocs)  (seed)  Mode  Cnt     Score   Error  Units
TSDBDocValuesMergeBenchmark.forceMergeWithOptimizedMerge            1000  20431204      42    ss       5607.886          ms/op
TSDBDocValuesMergeBenchmark.forceMergeWithoutOptimizedMerge         1000  20431204      42    ss       8397.983          ms/op

which is relatively slightly slower than what was reported above.

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.

Thanks for iterating. I left two more comments.

Comment on lines +589 to +591
} catch (final IOException ignored) {
// ignore exception
}
Copy link
Member

Choose a reason for hiding this comment

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

Can this try-catch be removed? This method signature does allow IOException. If addressDataOutputName is not null, then there should be a temp file, I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do.
I originally added the try-catch because the draft implementation used org.apache.lucene.util.IOUtils.deleteFilesIgnoringExceptions here. That's a forbidden api so I couldn't use it, but it seemed like we were trying to suppress any IOException that happened during that deletion, so I added the try-catch.

Comment on lines +553 to +554
var addressMetaOutput = new ByteBuffersIndexOutput(addressMetaBuffer, "meta-temp", "meta-temp");
var addressDataOutput = dir.createTempOutput(data.getName(), "address-data", ioContext)
Copy link
Member

@martijnvg martijnvg Apr 17, 2025

Choose a reason for hiding this comment

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

Maybe similarly to DISIAccumulator when can encapsulate the accumulation of the addresses in a class that implements Closable and has. a build method that copies data from temp file to actual data file and update metadata?

I think this could make the code a little bit more manageable similar to effect of what DISIAccumulator did.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense to me, I'll add that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants