Make setting index.translog.sync_interval be dynamic (#37382)

Currently, we cannot update index setting index.translog.sync_interval if index is open, because it's
not dynamic which can be updated for closed index only.

Closes #32763
This commit is contained in:
Like 2019-03-20 23:55:59 +08:00 committed by Yannick Welsch
parent 5ec56d7d22
commit 6f64267626
4 changed files with 66 additions and 18 deletions

View File

@ -199,7 +199,7 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
this.trimTranslogTask = new AsyncTrimTranslogTask(this); this.trimTranslogTask = new AsyncTrimTranslogTask(this);
this.globalCheckpointTask = new AsyncGlobalCheckpointTask(this); this.globalCheckpointTask = new AsyncGlobalCheckpointTask(this);
this.retentionLeaseSyncTask = new AsyncRetentionLeaseSyncTask(this); this.retentionLeaseSyncTask = new AsyncRetentionLeaseSyncTask(this);
rescheduleFsyncTask(indexSettings.getTranslogDurability()); updateFsyncTaskIfNecessary();
} }
public int numberOfShards() { public int numberOfShards() {
@ -640,8 +640,6 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
@Override @Override
public synchronized void updateMetaData(final IndexMetaData currentIndexMetaData, final IndexMetaData newIndexMetaData) { public synchronized void updateMetaData(final IndexMetaData currentIndexMetaData, final IndexMetaData newIndexMetaData) {
final Translog.Durability oldTranslogDurability = indexSettings.getTranslogDurability();
final boolean updateIndexMetaData = indexSettings.updateIndexMetaData(newIndexMetaData); final boolean updateIndexMetaData = indexSettings.updateIndexMetaData(newIndexMetaData);
if (Assertions.ENABLED if (Assertions.ENABLED
@ -693,20 +691,23 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
}); });
rescheduleRefreshTasks(); rescheduleRefreshTasks();
} }
final Translog.Durability durability = indexSettings.getTranslogDurability(); updateFsyncTaskIfNecessary();
if (durability != oldTranslogDurability) {
rescheduleFsyncTask(durability);
}
} }
} }
private void rescheduleFsyncTask(Translog.Durability durability) { private void updateFsyncTaskIfNecessary() {
try { if (indexSettings.getTranslogDurability() == Translog.Durability.REQUEST) {
if (fsyncTask != null) { try {
fsyncTask.close(); if (fsyncTask != null) {
fsyncTask.close();
}
} finally {
fsyncTask = null;
} }
} finally { } else if (fsyncTask == null) {
fsyncTask = durability == Translog.Durability.REQUEST ? null : new AsyncTranslogFSync(this); fsyncTask = new AsyncTranslogFSync(this);
} else {
fsyncTask.updateIfNeeded();
} }
} }
@ -868,6 +869,13 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
indexService.maybeFSyncTranslogs(); indexService.maybeFSyncTranslogs();
} }
void updateIfNeeded() {
final TimeValue newInterval = indexService.getIndexSettings().getTranslogSyncInterval();
if (newInterval.equals(getInterval()) == false) {
setInterval(newInterval);
}
}
@Override @Override
public String toString() { public String toString() {
return "translog_sync"; return "translog_sync";

View File

@ -62,7 +62,7 @@ public final class IndexSettings {
Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, Property.IndexScope); Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, Property.IndexScope);
public static final Setting<TimeValue> INDEX_TRANSLOG_SYNC_INTERVAL_SETTING = public static final Setting<TimeValue> INDEX_TRANSLOG_SYNC_INTERVAL_SETTING =
Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100),
Property.IndexScope); Property.Dynamic, Property.IndexScope);
public static final Setting<TimeValue> INDEX_SEARCH_IDLE_AFTER = public static final Setting<TimeValue> INDEX_SEARCH_IDLE_AFTER =
Setting.timeSetting("index.search.idle.after", TimeValue.timeValueSeconds(30), Setting.timeSetting("index.search.idle.after", TimeValue.timeValueSeconds(30),
TimeValue.timeValueMinutes(0), Property.IndexScope, Property.Dynamic); TimeValue.timeValueMinutes(0), Property.IndexScope, Property.Dynamic);
@ -316,7 +316,7 @@ public final class IndexSettings {
private final boolean queryStringAllowLeadingWildcard; private final boolean queryStringAllowLeadingWildcard;
private final boolean defaultAllowUnmappedFields; private final boolean defaultAllowUnmappedFields;
private volatile Translog.Durability durability; private volatile Translog.Durability durability;
private final TimeValue syncInterval; private volatile TimeValue syncInterval;
private volatile TimeValue refreshInterval; private volatile TimeValue refreshInterval;
private volatile ByteSizeValue flushThresholdSize; private volatile ByteSizeValue flushThresholdSize;
private volatile TimeValue translogRetentionAge; private volatile TimeValue translogRetentionAge;
@ -501,6 +501,7 @@ public final class IndexSettings {
MergeSchedulerConfig.MAX_MERGE_COUNT_SETTING, mergeSchedulerConfig::setMaxThreadAndMergeCount); MergeSchedulerConfig.MAX_MERGE_COUNT_SETTING, mergeSchedulerConfig::setMaxThreadAndMergeCount);
scopedSettings.addSettingsUpdateConsumer(MergeSchedulerConfig.AUTO_THROTTLE_SETTING, mergeSchedulerConfig::setAutoThrottle); scopedSettings.addSettingsUpdateConsumer(MergeSchedulerConfig.AUTO_THROTTLE_SETTING, mergeSchedulerConfig::setAutoThrottle);
scopedSettings.addSettingsUpdateConsumer(INDEX_TRANSLOG_DURABILITY_SETTING, this::setTranslogDurability); scopedSettings.addSettingsUpdateConsumer(INDEX_TRANSLOG_DURABILITY_SETTING, this::setTranslogDurability);
scopedSettings.addSettingsUpdateConsumer(INDEX_TRANSLOG_SYNC_INTERVAL_SETTING, this::setTranslogSyncInterval);
scopedSettings.addSettingsUpdateConsumer(MAX_RESULT_WINDOW_SETTING, this::setMaxResultWindow); scopedSettings.addSettingsUpdateConsumer(MAX_RESULT_WINDOW_SETTING, this::setMaxResultWindow);
scopedSettings.addSettingsUpdateConsumer(MAX_INNER_RESULT_WINDOW_SETTING, this::setMaxInnerResultWindow); scopedSettings.addSettingsUpdateConsumer(MAX_INNER_RESULT_WINDOW_SETTING, this::setMaxInnerResultWindow);
scopedSettings.addSettingsUpdateConsumer(MAX_ADJACENCY_MATRIX_FILTERS_SETTING, this::setMaxAdjacencyMatrixFilters); scopedSettings.addSettingsUpdateConsumer(MAX_ADJACENCY_MATRIX_FILTERS_SETTING, this::setMaxAdjacencyMatrixFilters);
@ -701,6 +702,10 @@ public final class IndexSettings {
return syncInterval; return syncInterval;
} }
public void setTranslogSyncInterval(TimeValue translogSyncInterval) {
this.syncInterval = translogSyncInterval;
}
/** /**
* Returns this interval in which the shards of this index are asynchronously refreshed. {@code -1} means async refresh is disabled. * Returns this interval in which the shards of this index are asynchronously refreshed. {@code -1} means async refresh is disabled.
*/ */

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index;
import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopDocs;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -320,9 +321,7 @@ public class IndexServiceTests extends ESSingleNodeTestCase {
assertTrue(indexService.getRefreshTask().mustReschedule()); assertTrue(indexService.getRefreshTask().mustReschedule());
client().prepareIndex("test", "test", "1").setSource("{\"foo\": \"bar\"}", XContentType.JSON).get(); client().prepareIndex("test", "test", "1").setSource("{\"foo\": \"bar\"}", XContentType.JSON).get();
IndexShard shard = indexService.getShard(0); IndexShard shard = indexService.getShard(0);
assertBusy(() -> { assertBusy(() -> assertFalse(shard.isSyncNeeded()));
assertFalse(shard.isSyncNeeded());
});
} }
public void testRescheduleAsyncFsync() throws Exception { public void testRescheduleAsyncFsync() throws Exception {
@ -394,4 +393,39 @@ public class IndexServiceTests extends ESSingleNodeTestCase {
assertEquals("failed to parse value [0ms] for setting [index.translog.sync_interval], must be >= [100ms]", ex.getMessage()); assertEquals("failed to parse value [0ms] for setting [index.translog.sync_interval], must be >= [100ms]", ex.getMessage());
} }
} }
public void testUpdateSyncIntervalDynamically() {
Settings settings = Settings.builder()
.put(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey(), "10s") // very often :)
.build();
IndexService indexService = createIndex("test", settings);
ensureGreen("test");
assertNull(indexService.getFsyncTask());
Settings.Builder builder = Settings.builder().put(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey(), "5s")
.put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), Translog.Durability.ASYNC.name());
client()
.admin()
.indices()
.prepareUpdateSettings("test")
.setSettings(builder)
.get();
assertNotNull(indexService.getFsyncTask());
assertTrue(indexService.getFsyncTask().mustReschedule());
IndexMetaData indexMetaData = client().admin().cluster().prepareState().execute().actionGet().getState().metaData().index("test");
assertEquals("5s", indexMetaData.getSettings().get(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey()));
client().admin().indices().prepareClose("test").get();
client()
.admin()
.indices()
.prepareUpdateSettings("test")
.setSettings(Settings.builder().put(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey(), "20s"))
.get();
indexMetaData = client().admin().cluster().prepareState().execute().actionGet().getState().metaData().index("test");
assertEquals("20s", indexMetaData.getSettings().get(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey()));
}
} }

View File

@ -402,6 +402,7 @@ public class TransportResumeFollowAction extends TransportMasterNodeAction<Resum
nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_GENERATION_THRESHOLD_SIZE_SETTING); nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_GENERATION_THRESHOLD_SIZE_SETTING);
nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING); nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING);
nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING); nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING);
nonReplicatedSettings.add(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING);
nonReplicatedSettings.add(IndexSettings.INDEX_GC_DELETES_SETTING); nonReplicatedSettings.add(IndexSettings.INDEX_GC_DELETES_SETTING);
nonReplicatedSettings.add(IndexSettings.MAX_REFRESH_LISTENERS_PER_SHARD); nonReplicatedSettings.add(IndexSettings.MAX_REFRESH_LISTENERS_PER_SHARD);