/** * The merge scheduler (<code>ConcurrentMergeScheduler</code>) controls the execution of merge * operations once they are needed (according to the merge policy). Merges run in separate threads, * and when the maximum number of threads is reached, further merges will wait until a merge thread * becomes available. * * <p>The merge scheduler supports the following <b>dynamic</b> settings: * * <ul> * <li><code>index.merge.scheduler.max_thread_count</code>: * <p>The maximum number of threads that may be merging at once. Defaults to <code> * Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2))</code> which works * well for a good solid-state-disk (SSD). If your index is on spinning platter drives * instead, decrease this to 1. * <li><code>index.merge.scheduler.auto_throttle</code>: * <p>If this is true (the default), then the merge scheduler will rate-limit IO (writes) for * merges to an adaptive value depending on how many merges are requested over time. An * application with a low indexing rate that unluckily suddenly requires a large merge will * see that merge aggressively throttled, while an application doing heavy indexing will see * the throttle move higher to allow merges to keep up with ongoing indexing. * </ul> */ public final class MergeSchedulerConfig { public static final Setting<Integer> MAX_THREAD_COUNT_SETTING = new Setting<>( "index.merge.scheduler.max_thread_count", (s) -> Integer.toString( Math.max(1, Math.min(4, EsExecutors.boundedNumberOfProcessors(s) / 2))), (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), Property.Dynamic, Property.IndexScope); public static final Setting<Integer> MAX_MERGE_COUNT_SETTING = new Setting<>( "index.merge.scheduler.max_merge_count", (s) -> Integer.toString(MAX_THREAD_COUNT_SETTING.get(s) + 5), (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), Property.Dynamic, Property.IndexScope); public static final Setting<Boolean> AUTO_THROTTLE_SETTING = Setting.boolSetting( "index.merge.scheduler.auto_throttle", true, Property.Dynamic, Property.IndexScope); private volatile boolean autoThrottle; private volatile int maxThreadCount; private volatile int maxMergeCount; MergeSchedulerConfig(IndexSettings indexSettings) { maxThreadCount = indexSettings.getValue(MAX_THREAD_COUNT_SETTING); maxMergeCount = indexSettings.getValue(MAX_MERGE_COUNT_SETTING); this.autoThrottle = indexSettings.getValue(AUTO_THROTTLE_SETTING); } /** * Returns <code>true</code> iff auto throttle is enabled. * * @see ConcurrentMergeScheduler#enableAutoIOThrottle() */ public boolean isAutoThrottle() { return autoThrottle; } /** Enables / disables auto throttling on the {@link ConcurrentMergeScheduler} */ void setAutoThrottle(boolean autoThrottle) { this.autoThrottle = autoThrottle; } /** Returns {@code maxThreadCount}. */ public int getMaxThreadCount() { return maxThreadCount; } /** Expert: directly set the maximum number of merge threads and simultaneous merges allowed. */ void setMaxThreadCount(int maxThreadCount) { this.maxThreadCount = maxThreadCount; } /** Returns {@code maxMergeCount}. */ public int getMaxMergeCount() { return maxMergeCount; } /** Expert: set the maximum number of simultaneous merges allowed. */ void setMaxMergeCount(int maxMergeCount) { this.maxMergeCount = maxMergeCount; } }