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

Add segment sorter for data streams #75195

Merged

Conversation

mayya-sharipova
Copy link
Contributor

@mayya-sharipova mayya-sharipova commented Jul 9, 2021

It is beneficial to sort segments within a datastream's index
by desc order of their max timestamp field, so
that the most recent (in terms of timestamp) segments
will be first.

This allows to speed up sort query on @timestamp desc field,
which is the most common type of query for datastreams,
as we are mostly concerned with the recent data.
This patch addressed this for writable indices.

Segments' sorter is different from index sorting.
An index sorter by itself is only concerned about the order of docs
within an individual segment (and not how the segments are organized),
while the segment sorter is only used during search and allows
to start docs collection with the "right" segment,
so we can terminate the collection faster.

TODO:

  • Should we also do this for frozen or readonly indices?
    Or they always supposed to have 1 segment?

@mayya-sharipova mayya-sharipova added the :Search/Search Search-related issues that do not fall into other categories label Jul 9, 2021
@elasticmachine elasticmachine added the Team:Search Meta label for search team label Jul 9, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search (Team:Search)

@mayya-sharipova
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-1

@mayya-sharipova mayya-sharipova force-pushed the datastreams-leaf-sorter branch from 4661286 to 3b25eed Compare July 14, 2021 15:57
It is beneficial to add leaf sorter for data streams
by desc order of their max timestamp field, so
that the most recent (in terms of timestamp) segments
will be first.
This allows to speed up sort query on @timestamp desc field,
which is the most common type of query for datastreams,
as we are mostly concerned with the recent data.
This patch addressed for writable indices.

This path also adds a new flag isDataStreamIndex
to IndexMetadata that shows if this index is a
part of datastream or not.

TODO:
- Should we also to this for frozen or readonly indices?
@mayya-sharipova mayya-sharipova force-pushed the datastreams-leaf-sorter branch from 3b25eed to 5360987 Compare July 14, 2021 18:11
@dakrone
Copy link
Member

dakrone commented Jul 15, 2021

@mayya-sharipova I have a question because I am unfamiliar with this part of the code :) Is this leaf sorter the same as regular index sorting, or is this something that only takes effect on query or merging? Does this affect the indexing throughput the way the index-time sorting can?

@mayya-sharipova mayya-sharipova changed the title Add default leaf sorter for data streams Add segment sorter for data streams Jul 16, 2021
@mayya-sharipova
Copy link
Contributor Author

mayya-sharipova commented Jul 16, 2021

@dakrone Thank you for taking a look. Answering your questions:

Is this leaf sorter the same as regular index sorting, or is this something that only takes effect on query or merging?

Segments' sorter is different from index sorting, and is only used during querying. An index sorter by itself is only concerned about the order of docs within an individual segment (and not how the segments are organized), while the segment sorter is used during querying to start docs collection with the "right" segment, so we can terminate the collection faster once we collected to the top docs (for data streams, these would be the most recent docs).

Does this affect the indexing throughput the way the index-time sorting can?

No, it doesn't. Segment's sorter is only used during querying.

I've also clarified the PR comment with this information.

@hendrikmuhs
Copy link

Does sorting get always applied?

In the case of rollup and transform a composite agg is used and both read data in ascending order (date histogram), in addition both can not benefit from an early exit, but actually disable this explicitly.

That's why I am concerned about this change if it changes the behavior for all cases.

Copy link
Contributor

@jimczi jimczi left a comment

Choose a reason for hiding this comment

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

I left a comment regarding the index metadata change. It should be possible to detect if an index is part of a datastream dynamically.

@@ -387,6 +389,7 @@ public static APIBlock readFrom(StreamInput input) throws IOException {
private final ActiveShardCount waitForActiveShards;
private final ImmutableOpenMap<String, RolloverInfo> rolloverInfos;
private final boolean isSystem;
private final boolean isDataStreamIndex;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should change the index metadata for this information. That would only work on data streams created after 7.15 unless I missed something ?
Checking if a concrete index is a data stream can be done dynamically when the IndexShard or IndexService is created ? You can access the index abstraction lookup with clusterService.state().metadata().getIndicesLookup().

Copy link
Contributor

@danhermann danhermann Jul 21, 2021

Choose a reason for hiding this comment

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

+1 to what @jimczi said here. Individual indices can be detached from and added to data streams in a variety of scenarios including snapshot restores and the relatively new Migrate to Data Stream API. If such a flag were included in index metadata, code would need to be added in all such places to correct the index metadata and we'd prefer to avoid that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jimczi Thank you for comment. I've started with a dynamic lookup clusterService.state().metadata().getIndicesLookup() like you suggested but it is not allowed to to access a cluster state while modifying cluster state (e.g. during index creation). There is a function ClusterApplierService::assertNotCalledFromClusterStateApplier that checks for it, and returns an error: "the applied cluster state is not yet available". I can investigate if it is possible to do this check somewhere earlier.

@danhermann Thanks for checking, and highlighting Migrate Data Stream API. I would think that this API would be quite rare to use, and most datastream indices would be created in a usual way. But indeed if used, we would need to update index metadata.

I will see if it is possible to do this check dynamically, but as we build more code around datastreams it would be nice to have an easy way to check if a shard is a part of datastream, with APIs like: IndexMetadata::isDataStreamIndex or IndexShard::isDataStreamIndex.

@mayya-sharipova
Copy link
Contributor Author

mayya-sharipova commented Jul 21, 2021

@hendrikmuhs Thanks for looking and raising your concerns. Answering your questions:

Does sorting get always applied?

In the case of rollup and transform a composite agg is used and both read data in ascending order (date histogram), in addition both can not benefit from an early exit, but actually disable this explicitly.

Yes, it will be always applied to datastream indices. But this PR is about sorting of segments, in terms of which segment is better to start when doing document collection. It adds a tiny overhead, and for aggregations that collect all documents from all segments, it doesn't really matter from what segment to start, and I don't think there will be any impact on the performance of date histogram or other aggs (but I will make sure to benchmark for this).

I think a bigger concern for your use case could be #71186, which proposes to add sort on @timestamp by default to all searches on datastream indices. Please raise your very valid concerns on that issue.

This reverts commit 5360987.
As we want to dynamically specify in an index belongs to data stream.
@hendrikmuhs
Copy link

@mayya-sharipova

Thanks for the response. It would be good to benchmark it. If you need help to set this up let me know. It seems tricky to benchmark, I might be wrong, but a lot of benchmarks force-merge to 1 segment before testing, we obviously don't want that behavior in this case.

I have a non-PR'd yet transform track which might be useful, however we don't need transform for this. The aggregation tracks might work as well.

It is beneficial to sort segments within a datastream's index
by desc order of their max timestamp field, so
that the most recent (in terms of timestamp) segments
will be first.

This allows to speed up sort query on @timestamp desc field,
which is the most common type of query for datastreams,
as we are mostly concerned with the recent data.
This patch addressed this for writable indices.

Segments' sorter is different from index sorting.
An index sorter by itself is only concerned about the order of docs
within an individual segment (and not how the segments are organized),
while the segment sorter is only used during search and allows
to start docs collection with the "right" segment,
so we can terminate the collection faster.

This PR adds a property to IndexShard `isDataStreamIndex` that
shows if a shard is a part of datastream.
@mayya-sharipova
Copy link
Contributor Author

mayya-sharipova commented Jul 26, 2021

@jimczi Thanks for your review so far. In a9d44d9, I've added a data-stream check as you suggested; the check is done in IndicesClusterStateService::createShard, and now it will a property of IndexShard object instead of being a part of stored metadata.

There is an unresolved issue with migrate with data stream API, as there is no closing and reopening of shard during migration, a migration to data stream on already existing migrated indices will not be reflected. We have two options to address it:

  1. Decide that it doesn't matter. Migration happens rarely, this only affects speedups in search and on new indices it will be reflected anyway.
  2. @dnhatn suggested to apply leaf sorter not only on data stream indices, but on all indices that have @timestamp field. For this, we can check MapperService in a similar way as it is done in TimestampFieldMapperService.

@jimczi WDYT?

@jpountz
Copy link
Contributor

jpountz commented Jul 27, 2021

@hendrikmuhs Do I understand you correctly that benchmarking date histograms on @timestamp should be a good enough proxy to make sure that transforms are unaffected by this change? Mayya and I just discussed about doing this before merging this change.

@jimczi
Copy link
Contributor

jimczi commented Jul 27, 2021

@dnhatn suggested to apply leaf sorter not only on data stream indices, but on all indices that have @timestamp field. For this, we can check MapperService in a similar way as it is done in TimestampFieldMapperService.

I like the idea. That'll probably require to move the timestamp metadata field in core but that makes sense to me.

@hendrikmuhs
Copy link

@hendrikmuhs Do I understand you correctly that benchmarking date histograms on @timestamp should be a good enough proxy to make sure that transforms are unaffected by this change? Mayya and I just discussed about doing this before merging this change.

Yes, that sound like a good plan to me. Thanks for looking into it!

@dimitris-athanasiou
Copy link
Contributor

Another use case that might be affected is scrolling through all docs in ascending order of a date field. This is what ML anomaly detection does when aggregations can't be used (which is many use cases). It might be worth also benchmarking if segment sorting slows this use case down significantly.

@mayya-sharipova
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-1

@mayya-sharipova
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-2

@mayya-sharipova
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/bwc

@mayya-sharipova mayya-sharipova merged commit f18b9d5 into elastic:master Sep 3, 2021
@mayya-sharipova mayya-sharipova deleted the datastreams-leaf-sorter branch September 3, 2021 13:43
mayya-sharipova added a commit to mayya-sharipova/elasticsearch that referenced this pull request Sep 3, 2021
It is beneficial to sort segments within a datastream's index
by desc order of their max timestamp field, so
that the most recent (in terms of timestamp) segments
will be first.

This allows to speed up sort query on @timestamp desc field,
which is the most common type of query for datastreams,
as we are mostly concerned with the recent data.
This patch addressed this for writable indices.

Segments' sorter is different from index sorting.
An index sorter by itself is  concerned about the order of docs
within an individual segment (and not how the segments are organized),
while the segment sorter is only used during search and allows
to start docs collection with the "right" segment,
so we can terminate the collection faster.

This PR adds a property to IndexShard `isDataStreamIndex` that
shows if a shard is a part of datastream.
mayya-sharipova added a commit that referenced this pull request Sep 3, 2021
It is beneficial to sort segments within a datastream's index
by desc order of their max timestamp field, so
that the most recent (in terms of timestamp) segments
will be first.

This allows to speed up sort query on @timestamp desc field,
which is the most common type of query for datastreams,
as we are mostly concerned with the recent data.
This patch addressed this for writable indices.

Segments' sorter is different from index sorting.
An index sorter by itself is  concerned about the order of docs
within an individual segment (and not how the segments are organized),
while the segment sorter is only used during search and allows
to start docs collection with the "right" segment,
so we can terminate the collection faster.

This PR adds a property to IndexShard `isDataStreamIndex` that
shows if a shard is a part of datastream.

Backport for #75195
wjp719 added a commit to wjp719/elasticsearch that referenced this pull request Sep 4, 2021
* master: (128 commits)
  Mute DieWithDignityIT (elastic#77283)
  Fix randomization in MlNodeShutdownIT (elastic#77281)
  Add target_node_name for REPLACE shutdown type (elastic#77151)
  [DOCS] Adds information about version compatibility headers (elastic#77096)
  Fix template equals when mappings are wrapped (elastic#77008)
  Fix TextFieldMapper Retaining a Reference to its Builder (elastic#77251)
  Move die with dignity to be a test module (elastic#77136)
  Update task names for rest compatiblity (elastic#75267)
  [ML] adjusting bwc serialization for elastic#77256 (elastic#77257)
  Move `index.hidden` from Static to Dynamic settings (elastic#77218)
  Handle cgroups v2 in `OsProbe` (elastic#77128)
  Choose postings format from FieldMapper instead of MappedFieldType (elastic#77234)
  Add segment sorter for data streams (elastic#75195)
  Update skip after backport (elastic#77212)
  [ML] adding new defer_definition_decompression parameter to put trained model API (elastic#77189)
  [ML] Fix bug in inference stats persister for when feature reset is called
  Only check replicas in cancelling existing recoveries. (elastic#60564)
  Format `AbstractFilteringTestCase` (elastic#77217)
  [DOCS] Fixes line breaks. (elastic#77248)
  Convert 'routing' values in REST API tests to strings
  ...

# Conflicts:
#	server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java
mayya-sharipova added a commit to mayya-sharipova/elasticsearch that referenced this pull request Oct 4, 2021
PR elastic#75195 added segment sorter on @timestamp desc for datastream indices.
This PR applies segment sorter to all indices that have @timestamp
field.

The presence of @timestamp field can serve as a strong
indication that we are dealing with timeseries indices. The most
common type of query for timeseries indices is to get the latest data,
that is data sorted by @timestamp desc. This PR sorts segments
by @timestamp desc which allows to speed up this kind of queries.

Relates to elastic#75195
mayya-sharipova added a commit that referenced this pull request Oct 5, 2021
PR #75195 added segment sorter on @timestamp desc for datastream indices.
This PR applies segment sorter to all indices that have @timestamp
field.

The presence of @timestamp field can serve as a strong
indication that we are dealing with timeseries indices. The most
common type of query for timeseries indices is to get the latest data,
that is data sorted by @timestamp desc. This PR sorts segments
by @timestamp desc which allows to speed up this kind of queries.

Relates to #75195
mayya-sharipova added a commit to mayya-sharipova/elasticsearch that referenced this pull request Oct 5, 2021
PR elastic#75195 added segment sorter on @timestamp desc for datastream indices.
This PR applies segment sorter to all indices that have @timestamp
field.

The presence of @timestamp field can serve as a strong
indication that we are dealing with timeseries indices. The most
common type of query for timeseries indices is to get the latest data,
that is data sorted by @timestamp desc. This PR sorts segments
by @timestamp desc which allows to speed up this kind of queries.

Backport for elastic#78639
Relates to elastic#75195
mayya-sharipova added a commit that referenced this pull request Oct 5, 2021
PR #75195 added segment sorter on @timestamp desc for datastream indices.
This PR applies segment sorter to all indices that have @timestamp
field.

The presence of @timestamp field can serve as a strong
indication that we are dealing with timeseries indices. The most
common type of query for timeseries indices is to get the latest data,
that is data sorted by @timestamp desc. This PR sorts segments
by @timestamp desc which allows to speed up this kind of queries.

Backport for #78639
Relates to #75195
javanna added a commit to javanna/elasticsearch that referenced this pull request Feb 7, 2023
Ordinary indices support sorting their segments on the timestamp when they have such a field defined
in their mappings (see elastic#75195). This was not initially supported as a directory reader could not be created provding
a leaf sorter, which is now possible in Lucene and we can make use of.
javanna added a commit that referenced this pull request Feb 8, 2023
Ordinary indices support sorting their segments on the timestamp when they have such a field defined
in their mappings (see #75195). This was not initially supported as a directory reader could not be created provding
a leaf sorter, which is now possible in Lucene and we can make use of.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement release highlight :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team v7.16.0 v8.0.0-alpha2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants