-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Add Rollup ILM Action #65633
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
Merged
Merged
Add Rollup ILM Action #65633
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
176af36
Add Rollup ILM Action
talevy ca3e695
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 3631adc
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 184c7ca
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 434f49c
respond to review
talevy fe1f124
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 638cbe7
fix for latest master
talevy 91371d9
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy e46d4ec
remove delete option and add to hot before snapshotting
talevy 3e38fd6
enable rollup_v2 flag for ilm tests
talevy 277549b
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 6f7f6f3
put Rollup behind feature flag in ilm hot phase actions
talevy ff38007
fix rollup ilm action test
talevy a5b1bb9
really fix it
talevy c430366
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy d954f55
update rollup ilm to more steps and retryable
talevy 4679677
fix test bugs
talevy 4091a96
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy ffcc4a2
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy d9523a8
simplify and fix tests
talevy d53427e
fix checkstyle
talevy 05de2e1
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 0f8ebcc
re-introduce policy updating by way of a new step
talevy 1905843
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy b622f39
fix merge exceptions
talevy 968e7aa
fix test setup
talevy 1d03113
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy 96a1622
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy c9e31d5
docs and cleanup
talevy 1d1fc31
add docs to ILM Actions page
talevy 49b5802
place ILM Rollup Docs behind unreleased branch conditional
talevy e340f07
Update docs/reference/ilm/actions/ilm-rollup.asciidoc
talevy 7efb1a3
Update docs/reference/ilm/actions/ilm-rollup.asciidoc
talevy 10487aa
Update docs/reference/ilm/actions/ilm-rollup.asciidoc
talevy 382915d
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy e01d063
Merge remote-tracking branch 'elastic/master' into rollup-ilm
talevy ec30764
prioritize rollup before shrink/forcemerge in hot phase
talevy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| [role="xpack"] | ||
| [[ilm-rollup]] | ||
| === Rollup | ||
|
|
||
| Phases allowed: hot, cold. | ||
|
|
||
| Aggregates an index's time series data and stores the results in a new read-only | ||
| index. For example, you can roll up hourly data into daily or weekly summaries. | ||
|
|
||
| For more information about rollup, see the <<rollup-api, rollup action documentation>> | ||
|
|
||
| The name of the rolled up index will be the original index name of the managed index prefixed | ||
| with `rollup-`. | ||
|
|
||
| [[ilm-rollup-options]] | ||
| ==== Rollup options | ||
| `config`:: | ||
| (Required, integer) | ||
| The rollup configuration, a more detailed description of the | ||
| rollup configuration specification can be found <<rollup-api-request-body,here>>. | ||
|
|
||
| `rollup_policy`:: | ||
| (Optional, string) | ||
| The name of an <<index-lifecycle-management, {ilm}>> ({ilm-init}) policy to associate | ||
| with the newly created rollup index. | ||
|
|
||
| [[ilm-rollup-ex]] | ||
| ==== Example | ||
|
|
||
| [source,console] | ||
| -------------------------------------------------- | ||
| PUT _ilm/policy/my_policy | ||
| { | ||
| "policy": { | ||
| "phases": { | ||
| "cold": { | ||
| "actions": { | ||
| "rollup" : { | ||
| "config": { | ||
| "groups": { | ||
| "date_histogram": { | ||
| "field": "@timestamp", | ||
| "calendar_interval": "1y" | ||
| } | ||
| }, | ||
| "metrics": [ | ||
| { "field": "temperature", "metrics": [ "avg" ] } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| -------------------------------------------------- | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RollupILMAction.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
| package org.elasticsearch.xpack.core.ilm; | ||
|
|
||
| import org.elasticsearch.client.Client; | ||
| import org.elasticsearch.common.Nullable; | ||
| import org.elasticsearch.common.ParseField; | ||
| import org.elasticsearch.common.Strings; | ||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.xcontent.ConstructingObjectParser; | ||
| import org.elasticsearch.common.xcontent.ObjectParser; | ||
| import org.elasticsearch.common.xcontent.XContentBuilder; | ||
| import org.elasticsearch.common.xcontent.XContentParser; | ||
| import org.elasticsearch.xpack.core.ilm.Step.StepKey; | ||
| import org.elasticsearch.xpack.core.rollup.RollupActionConfig; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.List; | ||
| import java.util.Objects; | ||
|
|
||
| /** | ||
| * A {@link LifecycleAction} which calls {@link org.elasticsearch.xpack.core.rollup.action.RollupAction} on an index | ||
| */ | ||
| public class RollupILMAction implements LifecycleAction { | ||
| public static final String NAME = "rollup"; | ||
|
|
||
| private static final ParseField CONFIG_FIELD = new ParseField("config"); | ||
| private static final ParseField POLICY_FIELD = new ParseField("rollup_policy"); | ||
csoulios marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @SuppressWarnings("unchecked") | ||
| private static final ConstructingObjectParser<RollupILMAction, Void> PARSER = new ConstructingObjectParser<>(NAME, | ||
| a -> new RollupILMAction((RollupActionConfig) a[0], (String) a[1])); | ||
|
|
||
| private final RollupActionConfig config; | ||
| private final String rollupPolicy; | ||
|
|
||
| static { | ||
| PARSER.declareField(ConstructingObjectParser.constructorArg(), | ||
| (p, c) -> RollupActionConfig.fromXContent(p), CONFIG_FIELD, ObjectParser.ValueType.OBJECT); | ||
| PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), POLICY_FIELD); | ||
| } | ||
|
|
||
| public static RollupILMAction parse(XContentParser parser) { | ||
| return PARSER.apply(parser, null); | ||
| } | ||
|
|
||
| public RollupILMAction(RollupActionConfig config, @Nullable String rollupPolicy) { | ||
| this.config = config; | ||
| this.rollupPolicy = rollupPolicy; | ||
| } | ||
|
|
||
| public RollupILMAction(StreamInput in) throws IOException { | ||
| this(new RollupActionConfig(in), in.readOptionalString()); | ||
| } | ||
|
|
||
| @Override | ||
| public String getWriteableName() { | ||
| return NAME; | ||
| } | ||
|
|
||
| RollupActionConfig config() { | ||
| return config; | ||
| } | ||
|
|
||
| String rollupPolicy() { | ||
| return rollupPolicy; | ||
| } | ||
|
|
||
| @Override | ||
| public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| builder.startObject(); | ||
| builder.field(CONFIG_FIELD.getPreferredName(), config); | ||
| if (rollupPolicy != null) { | ||
| builder.field(POLICY_FIELD.getPreferredName(), rollupPolicy); | ||
| } | ||
| builder.endObject(); | ||
| return builder; | ||
| } | ||
|
|
||
| @Override | ||
| public void writeTo(StreamOutput out) throws IOException { | ||
| config.writeTo(out); | ||
| out.writeOptionalString(rollupPolicy); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isSafeAction() { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public List<Step> toSteps(Client client, String phase, StepKey nextStepKey) { | ||
| StepKey checkNotWriteIndex = new StepKey(phase, NAME, CheckNotDataStreamWriteIndexStep.NAME); | ||
| StepKey readOnlyKey = new StepKey(phase, NAME, ReadOnlyStep.NAME); | ||
| StepKey rollupKey = new StepKey(phase, NAME, NAME); | ||
| CheckNotDataStreamWriteIndexStep checkNotWriteIndexStep = new CheckNotDataStreamWriteIndexStep(checkNotWriteIndex, | ||
csoulios marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| readOnlyKey); | ||
| ReadOnlyStep readOnlyStep = new ReadOnlyStep(readOnlyKey, rollupKey, client); | ||
| if (rollupPolicy == null) { | ||
| Step rollupStep = new RollupStep(rollupKey, nextStepKey, client, config); | ||
| return List.of(checkNotWriteIndexStep, readOnlyStep, rollupStep); | ||
| } else { | ||
| StepKey updateRollupIndexPolicyStepKey = new StepKey(phase, NAME, UpdateRollupIndexPolicyStep.NAME); | ||
| Step rollupStep = new RollupStep(rollupKey, updateRollupIndexPolicyStepKey, client, config); | ||
| Step updateRollupIndexPolicyStep = new UpdateRollupIndexPolicyStep(updateRollupIndexPolicyStepKey, nextStepKey, | ||
| client, rollupPolicy); | ||
| return List.of(checkNotWriteIndexStep, readOnlyStep, rollupStep, updateRollupIndexPolicyStep); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
|
|
||
| RollupILMAction that = (RollupILMAction) o; | ||
|
|
||
| return Objects.equals(this.config, that.config) | ||
| && Objects.equals(this.rollupPolicy, that.rollupPolicy); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(config, rollupPolicy); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return Strings.toString(this); | ||
| } | ||
| } | ||
71 changes: 71 additions & 0 deletions
71
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RollupStep.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
| package org.elasticsearch.xpack.core.ilm; | ||
|
|
||
| import org.elasticsearch.action.ActionListener; | ||
| import org.elasticsearch.client.Client; | ||
| import org.elasticsearch.cluster.ClusterState; | ||
| import org.elasticsearch.cluster.ClusterStateObserver; | ||
| import org.elasticsearch.cluster.metadata.IndexMetadata; | ||
| import org.elasticsearch.xpack.core.rollup.RollupActionConfig; | ||
| import org.elasticsearch.xpack.core.rollup.action.RollupAction; | ||
|
|
||
| import java.util.Objects; | ||
|
|
||
| /** | ||
| * Rolls up index using a {@link RollupActionConfig} | ||
| */ | ||
| public class RollupStep extends AsyncActionStep { | ||
| public static final String NAME = "rollup"; | ||
| public static final String ROLLUP_INDEX_NAME_PREFIX = "rollup-"; | ||
|
|
||
| private final RollupActionConfig config; | ||
|
|
||
| public RollupStep(StepKey key, StepKey nextStepKey, Client client, RollupActionConfig config) { | ||
| super(key, nextStepKey, client); | ||
| this.config = config; | ||
| } | ||
|
|
||
| public static String getRollupIndexName(String index) { | ||
| return ROLLUP_INDEX_NAME_PREFIX + index; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isRetryable() { | ||
| return true; | ||
| } | ||
|
|
||
| @Override | ||
| public void performAction(IndexMetadata indexMetadata, ClusterState currentState, ClusterStateObserver observer, Listener listener) { | ||
| String originalIndex = indexMetadata.getIndex().getName(); | ||
| RollupAction.Request request = new RollupAction.Request(originalIndex, getRollupIndexName(originalIndex), config); | ||
| // currently RollupAction always acknowledges action was complete when no exceptions are thrown. | ||
| getClient().execute(RollupAction.INSTANCE, request, | ||
| ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); | ||
talevy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public RollupActionConfig getConfig() { | ||
| return config; | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(super.hashCode(), config); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object obj) { | ||
| if (obj == null) { | ||
| return false; | ||
| } | ||
| if (getClass() != obj.getClass()) { | ||
| return false; | ||
| } | ||
| RollupStep other = (RollupStep) obj; | ||
| return super.equals(obj) | ||
| && Objects.equals(config, other.config); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@talevy How does this work in the context of data streams? Does it work in the context of data streams? What are the index names there?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ILM works on the index level, not directly on data streams. You can roll up a backing index for a data stream but not a data stream itself.
If the index is a backing index for a data stream, the rollup index is a backing index for the same stream. The name of the new rollup index is based on the name of the backing index. For example, the name of a rollup index for
.ds-my-data-stream-2021.01.29-000001would berollup-.ds-my-data-stream-2021.01.29-000001.I hope that helps. I'll open up a follow-up PR to better clarify this in the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ruflin and @jrodewig,
this is exactly how it works today, but due to some failure-scenarios we discussed recently, we're going to change this behavior.
In the context of datastreams, we will likely randomize the name of the rollup index to prevent collision and conflict with any past or rogue rollup actions. The belief is that the underlying name of the index should not be of concern to users since they will be added into the datastream and managed in ILM. Do you see any problems with this on your end @ruflin?
For this reason, it might make sense to hold off just a little bit on your docs change PR @jrodewig, but much appreciated!
I've opened #68225 to track it. Will likely change next week
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update, @talevy!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is the case, it is great. I was under the assumption all indices belong to a data stream must use the
.ds-*prefix and be hidden. So I expect index names like.ds-rollup-*or something similar. This would also ensure there are no conflicts and makes it clear that these rollups belong to the data streams.The
rollup-prefix is what put me on the wrong track here and made me assume it does not belong to the data stream.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is actually common for indices managed by ILM to be renamed with a new prefix. For example, shrunken indices start with the
shrunk-prefix.independent of the name, the indices will be hidden and added to the backing datastream
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@talevy Interesting. Why are these not prefixed by a
.and not inside.ds-*-shrunk-*or similar to indicate they belong together? I think I'm derailing but could you share a link where I can read up on this? The part I'm concerned is that this not seem to fully fit into our naming scheme: https://www.elastic.co/blog/an-introduction-to-the-elastic-data-stream-naming-scheme