Skip to content

Remove "best_compression" option from the ForceMergeAction #32373

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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.codec.CodecService;
import org.elasticsearch.index.engine.EngineConfig;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;

import java.io.IOException;
Expand All @@ -29,53 +26,42 @@
public class ForceMergeAction implements LifecycleAction {
public static final String NAME = "forcemerge";
public static final ParseField MAX_NUM_SEGMENTS_FIELD = new ParseField("max_num_segments");
public static final ParseField BEST_COMPRESSION_FIELD = new ParseField("best_compression");

private static final ConstructingObjectParser<ForceMergeAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
false, a -> {
int maxNumSegments = (int) a[0];
boolean bestCompression = a[1] == null ? false : (boolean) a[1];
return new ForceMergeAction(maxNumSegments, bestCompression);
return new ForceMergeAction(maxNumSegments);
});

static {
PARSER.declareInt(ConstructingObjectParser.constructorArg(), MAX_NUM_SEGMENTS_FIELD);
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), BEST_COMPRESSION_FIELD);
}

private final int maxNumSegments;
private final boolean bestCompression;

public static ForceMergeAction parse(XContentParser parser) {
return PARSER.apply(parser, null);
}

public ForceMergeAction(int maxNumSegments, boolean bestCompression) {
public ForceMergeAction(int maxNumSegments) {
if (maxNumSegments <= 0) {
throw new IllegalArgumentException("[" + MAX_NUM_SEGMENTS_FIELD.getPreferredName()
+ "] must be a positive integer");
}
this.maxNumSegments = maxNumSegments;
this.bestCompression = bestCompression;
}

public ForceMergeAction(StreamInput in) throws IOException {
this.maxNumSegments = in.readVInt();
this.bestCompression = in.readBoolean();
}

public int getMaxNumSegments() {
return maxNumSegments;
}

public boolean isBestCompression() {
return bestCompression;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(maxNumSegments);
out.writeBoolean(bestCompression);
}

@Override
Expand All @@ -92,7 +78,6 @@ public boolean isSafeAction() {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(MAX_NUM_SEGMENTS_FIELD.getPreferredName(), maxNumSegments);
builder.field(BEST_COMPRESSION_FIELD.getPreferredName(), bestCompression);
builder.endObject();
return builder;
}
Expand All @@ -103,20 +88,13 @@ public List<Step> toSteps(Client client, String phase, Step.StepKey nextStepKey)
StepKey forceMergeKey = new StepKey(phase, NAME, ForceMergeStep.NAME);
StepKey countKey = new StepKey(phase, NAME, SegmentCountStep.NAME);
ForceMergeStep forceMergeStep = new ForceMergeStep(forceMergeKey, countKey, client, maxNumSegments);
SegmentCountStep segmentCountStep = new SegmentCountStep(countKey, nextStepKey, client, maxNumSegments, bestCompression);
if (bestCompression) {
Settings compressionSettings = Settings.builder()
.put(EngineConfig.INDEX_CODEC_SETTING.getKey(), CodecService.BEST_COMPRESSION_CODEC).build();
UpdateSettingsStep updateBestCompression = new UpdateSettingsStep(updateCompressionKey,
forceMergeKey, client, compressionSettings);
return Arrays.asList(updateBestCompression, forceMergeStep, segmentCountStep);
}
SegmentCountStep segmentCountStep = new SegmentCountStep(countKey, nextStepKey, client, maxNumSegments);
return Arrays.asList(forceMergeStep, segmentCountStep);
}

@Override
public int hashCode() {
return Objects.hash(maxNumSegments, bestCompression);
return Objects.hash(maxNumSegments);
}

@Override
Expand All @@ -128,8 +106,7 @@ public boolean equals(Object obj) {
return false;
}
ForceMergeAction other = (ForceMergeAction) obj;
return Objects.equals(maxNumSegments, other.maxNumSegments)
&& Objects.equals(bestCompression, other.bestCompression);
return Objects.equals(maxNumSegments, other.maxNumSegments);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,28 @@ public class SegmentCountStep extends AsyncWaitStep {
public static final String NAME = "segment-count";

private final int maxNumSegments;
private final boolean bestCompression;

public SegmentCountStep(StepKey key, StepKey nextStepKey, Client client, int maxNumSegments, boolean bestCompression) {
public SegmentCountStep(StepKey key, StepKey nextStepKey, Client client, int maxNumSegments) {
super(key, nextStepKey, client);
this.maxNumSegments = maxNumSegments;
this.bestCompression = bestCompression;
}

public int getMaxNumSegments() {
return maxNumSegments;
}

public boolean isBestCompression() {
return bestCompression;
}

@Override
public void evaluateCondition(Index index, Listener listener) {
getClient().admin().indices().segments(new IndicesSegmentsRequest(index.getName()), ActionListener.wrap(response -> {
long numberShardsLeftToMerge = StreamSupport.stream(response.getIndices().get(index.getName()).spliterator(), false)
.filter(iss -> Arrays.stream(iss.getShards()).anyMatch(p -> {
boolean hasRightAmountOfSegments = p.getSegments().size() <= maxNumSegments;
if (bestCompression) {
// // TODO(talevy): discuss
// boolean allUsingCorrectCompression = p.getSegments().stream().anyMatch(s ->
// Lucene50StoredFieldsFormat.Mode.BEST_COMPRESSION.equals(
// Lucene50StoredFieldsFormat.Mode.BEST_COMPRESSION.toString().equals(
// s.getAttributes().get(Lucene50StoredFieldsFormat.MODE_KEY)))
// );
boolean allUsingCorrectCompression = true;
return (hasRightAmountOfSegments && allUsingCorrectCompression) == false;
} else {
return hasRightAmountOfSegments == false;
}
})).count();
.filter(iss -> Arrays.stream(iss.getShards()).anyMatch(p -> p.getSegments().size() > maxNumSegments)).count();
listener.onResponse(numberShardsLeftToMerge == 0, new Info(numberShardsLeftToMerge));
}, listener::onFailure));
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), maxNumSegments, bestCompression);
return Objects.hash(super.hashCode(), maxNumSegments);
}

@Override
Expand All @@ -81,8 +61,7 @@ public boolean equals(Object obj) {
}
SegmentCountStep other = (SegmentCountStep) obj;
return super.equals(obj)
&& Objects.equals(maxNumSegments, other.maxNumSegments)
&& Objects.equals(bestCompression, other.bestCompression);
&& Objects.equals(maxNumSegments, other.maxNumSegments);
}

public static class Info implements ToXContentObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
Expand All @@ -29,19 +28,14 @@ protected ForceMergeAction doParseInstance(XContentParser parser) {

@Override
protected ForceMergeAction createTestInstance() {
return new ForceMergeAction(randomIntBetween(1, 100), randomBoolean());
return new ForceMergeAction(randomIntBetween(1, 100));
}

@Override
protected ForceMergeAction mutateInstance(ForceMergeAction instance) {
int maxNumSegments = instance.getMaxNumSegments();
boolean bestCompression = instance.isBestCompression();
if (randomBoolean()) {
maxNumSegments = maxNumSegments + randomIntBetween(1, 10);
} else {
bestCompression = !bestCompression;
}
return new ForceMergeAction(maxNumSegments, bestCompression);
maxNumSegments = maxNumSegments + randomIntBetween(1, 10);
return new ForceMergeAction(maxNumSegments);
}

@Override
Expand All @@ -58,7 +52,7 @@ public void testMissingMaxNumSegments() throws IOException {
}

public void testInvalidNegativeSegmentNumber() {
Exception r = expectThrows(IllegalArgumentException.class, () -> new ForceMergeAction(randomIntBetween(-10, 0), false));
Exception r = expectThrows(IllegalArgumentException.class, () -> new ForceMergeAction(randomIntBetween(-10, 0)));
assertThat(r.getMessage(), equalTo("[max_num_segments] must be a positive integer"));
}

Expand All @@ -69,16 +63,7 @@ public void testToSteps() {
List<Step> steps = instance.toSteps(null, phase, nextStepKey);
assertNotNull(steps);
int nextFirstIndex = 0;
if (instance.isBestCompression()) {
Settings expectedSettings = Settings.builder().put("index.codec", "best_compression").build();
assertEquals(3, steps.size());
UpdateSettingsStep firstStep = (UpdateSettingsStep) steps.get(0);
assertThat(firstStep.getKey(), equalTo(new StepKey(phase, ForceMergeAction.NAME, "best_compression")));
assertThat(firstStep.getSettings(), equalTo(expectedSettings));
nextFirstIndex = 1;
} else {
assertEquals(2, steps.size());
}
assertEquals(2, steps.size());
ForceMergeStep firstStep = (ForceMergeStep) steps.get(nextFirstIndex);
SegmentCountStep secondStep = (SegmentCountStep) steps.get(nextFirstIndex + 1);
assertThat(firstStep.getKey(), equalTo(new StepKey(phase, ForceMergeAction.NAME, ForceMergeStep.NAME)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,17 @@ public SegmentCountStep createRandomInstance() {
Step.StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
int maxNumSegments = randomIntBetween(1, 10);
boolean bestCompression = randomBoolean();

return new SegmentCountStep(stepKey, nextStepKey, null, maxNumSegments, bestCompression);
return new SegmentCountStep(stepKey, nextStepKey, null, maxNumSegments);
}

@Override
public SegmentCountStep mutateInstance(SegmentCountStep instance) {
StepKey key = instance.getKey();
StepKey nextKey = instance.getNextStepKey();
int maxNumSegments = instance.getMaxNumSegments();
boolean bestCompression = instance.isBestCompression();

switch (between(0, 3)) {
switch (between(0, 2)) {
case 0:
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
break;
Expand All @@ -59,20 +57,16 @@ public SegmentCountStep mutateInstance(SegmentCountStep instance) {
case 2:
maxNumSegments += 1;
break;
case 3:
bestCompression = !bestCompression;
break;
default:
throw new AssertionError("Illegal randomisation branch");
}

return new SegmentCountStep(key, nextKey, null, maxNumSegments, bestCompression);
return new SegmentCountStep(key, nextKey, null, maxNumSegments);
}

@Override
public SegmentCountStep copyInstance(SegmentCountStep instance) {
return new SegmentCountStep(instance.getKey(), instance.getNextStepKey(),
null, instance.getMaxNumSegments(), instance.isBestCompression());
return new SegmentCountStep(instance.getKey(), instance.getNextStepKey(), null, instance.getMaxNumSegments());
}

public void testIsConditionMet() {
Expand Down Expand Up @@ -103,7 +97,6 @@ public void testIsConditionMet() {

Step.StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
boolean bestCompression = randomBoolean();

Mockito.doAnswer(invocationOnMock -> {
@SuppressWarnings("unchecked")
Expand All @@ -115,7 +108,7 @@ public void testIsConditionMet() {
SetOnce<Boolean> conditionMetResult = new SetOnce<>();
SetOnce<ToXContentObject> conditionInfo = new SetOnce<>();

SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments);
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
@Override
public void onResponse(boolean conditionMet, ToXContentObject info) {
Expand Down Expand Up @@ -161,7 +154,6 @@ public void testIsConditionFails() {

Step.StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
boolean bestCompression = randomBoolean();

Mockito.doAnswer(invocationOnMock -> {
@SuppressWarnings("unchecked")
Expand All @@ -173,7 +165,7 @@ public void testIsConditionFails() {
SetOnce<Boolean> conditionMetResult = new SetOnce<>();
SetOnce<ToXContentObject> conditionInfo = new SetOnce<>();

SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments);
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
@Override
public void onResponse(boolean conditionMet, ToXContentObject info) {
Expand Down Expand Up @@ -203,7 +195,6 @@ public void testThrowsException() {
Step.StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
int maxNumSegments = randomIntBetween(3, 10);
boolean bestCompression = randomBoolean();

Mockito.doAnswer(invocationOnMock -> {
@SuppressWarnings("unchecked")
Expand All @@ -214,7 +205,7 @@ public void testThrowsException() {

SetOnce<Boolean> exceptionThrown = new SetOnce<>();

SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments);
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
@Override
public void onResponse(boolean conditionMet, ToXContentObject info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
import static org.hamcrest.Matchers.equalTo;

public class TimeseriesLifecycleTypeTests extends ESTestCase {

private static final AllocateAction TEST_ALLOCATE_ACTION = new AllocateAction(Collections.singletonMap("node", "node1"),null, null);
private static final DeleteAction TEST_DELETE_ACTION = new DeleteAction();
private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1, true);
private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1);
private static final ReplicasAction TEST_REPLICAS_ACTION = new ReplicasAction(1);
private static final RolloverAction TEST_ROLLOVER_ACTION = new RolloverAction(new ByteSizeValue(1), null, null);
private static final ShrinkAction TEST_SHRINK_ACTION = new ShrinkAction(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void init() {
.put(SETTING_NUMBER_OF_REPLICAS, 0).put(LifecycleSettings.LIFECYCLE_NAME, "test").build();
Map<String, Phase> phases = new HashMap<>();

Map<String, LifecycleAction> warmPhaseActions = Collections.singletonMap(ForceMergeAction.NAME, new ForceMergeAction(10000, false));
Map<String, LifecycleAction> warmPhaseActions = Collections.singletonMap(ForceMergeAction.NAME, new ForceMergeAction(10000));
phases.put("warm", new Phase("warm", TimeValue.timeValueSeconds(2), warmPhaseActions));

Map<String, LifecycleAction> deletePhaseActions = Collections.singletonMap(DeleteAction.NAME, new DeleteAction());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public void testForceMergeAction() throws Exception {
};
assertThat(numSegments.get(), greaterThan(1));

createNewSingletonPolicy("warm", new ForceMergeAction(1, false));
createNewSingletonPolicy("warm", new ForceMergeAction(1));
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));

assertBusy(() -> {
Expand Down