|
63 | 63 | * unluckily suddenly requires a large merge will see that merge aggressively |
64 | 64 | * throttled, while an application doing heavy indexing will see the throttle |
65 | 65 | * move higher to allow merges to keep up with ongoing indexing. |
| 66 | + * |
| 67 | + * <li><code>index.merge.scheduler.max_forced_merge_mb_per_sec</code>: |
| 68 | + * <p> |
| 69 | + * Controls the rate limiting for forced merges in MB per second at the index level. |
| 70 | + * The default value of Double.POSITIVE_INFINITY means no rate limiting is applied. |
| 71 | + * Setting a finite positive value will limit the throughput of forced merge operations |
| 72 | + * to the specified rate. This setting takes precedence over the cluster-level setting. |
| 73 | + * |
| 74 | + * <li><code>cluster.merge.scheduler.max_forced_merge_mb_per_sec</code>: |
| 75 | + * <p> |
| 76 | + * Controls the rate limiting for forced merges in MB per second at the cluster level. |
| 77 | + * The default value of Double.POSITIVE_INFINITY means no rate limiting is applied. |
| 78 | + * This setting is used as a fallback when the index-level setting is not specified. |
| 79 | + * Index-level settings take precedence over this cluster-level setting. |
| 80 | + * </ul> |
| 81 | + * |
| 82 | + * <p><b>Setting Precedence:</b> |
| 83 | + * <ul> |
| 84 | + * <li>If only index-level setting is specified: uses index value |
| 85 | + * <li>If only cluster-level setting is specified: uses cluster value |
| 86 | + * <li>If both settings are specified: uses index value (index takes precedence) |
| 87 | + * <li>If neither setting is specified: uses default value (Double.POSITIVE_INFINITY) |
66 | 88 | * </ul> |
67 | 89 | * |
68 | 90 | * @opensearch.api |
@@ -90,16 +112,41 @@ public final class MergeSchedulerConfig { |
90 | 112 | Property.Dynamic, |
91 | 113 | Property.IndexScope |
92 | 114 | ); |
| 115 | + public static final Setting<Double> MAX_FORCED_MERGE_MB_PER_SEC_SETTING = Setting.doubleSetting( |
| 116 | + "index.merge.scheduler.max_forced_merge_mb_per_sec", |
| 117 | + Double.POSITIVE_INFINITY, |
| 118 | + 0.0d, |
| 119 | + Double.POSITIVE_INFINITY, |
| 120 | + Property.Dynamic, |
| 121 | + Property.IndexScope |
| 122 | + ); |
| 123 | + |
| 124 | + public static final Setting<Double> CLUSTER_MAX_FORCED_MERGE_MB_PER_SEC_SETTING = Setting.doubleSetting( |
| 125 | + "cluster.merge.scheduler.max_forced_merge_mb_per_sec", |
| 126 | + Double.POSITIVE_INFINITY, |
| 127 | + 0.0d, |
| 128 | + Double.POSITIVE_INFINITY, |
| 129 | + Property.Dynamic, |
| 130 | + Property.NodeScope |
| 131 | + ); |
93 | 132 |
|
94 | 133 | private volatile boolean autoThrottle; |
95 | 134 | private volatile int maxThreadCount; |
96 | 135 | private volatile int maxMergeCount; |
| 136 | + private volatile double maxForcedMergeMBPerSec; |
97 | 137 |
|
98 | 138 | MergeSchedulerConfig(IndexSettings indexSettings) { |
99 | 139 | int maxThread = indexSettings.getValue(MAX_THREAD_COUNT_SETTING); |
100 | 140 | int maxMerge = indexSettings.getValue(MAX_MERGE_COUNT_SETTING); |
101 | 141 | setMaxThreadAndMergeCount(maxThread, maxMerge); |
102 | 142 | this.autoThrottle = indexSettings.getValue(AUTO_THROTTLE_SETTING); |
| 143 | + |
| 144 | + // Index setting takes precedence over cluster setting |
| 145 | + if (MAX_FORCED_MERGE_MB_PER_SEC_SETTING.exists(indexSettings.getSettings())) { |
| 146 | + this.maxForcedMergeMBPerSec = indexSettings.getValue(MAX_FORCED_MERGE_MB_PER_SEC_SETTING); |
| 147 | + } else { |
| 148 | + this.maxForcedMergeMBPerSec = CLUSTER_MAX_FORCED_MERGE_MB_PER_SEC_SETTING.get(indexSettings.getNodeSettings()); |
| 149 | + } |
103 | 150 | } |
104 | 151 |
|
105 | 152 | /** |
@@ -151,4 +198,20 @@ void setMaxThreadAndMergeCount(int maxThreadCount, int maxMergeCount) { |
151 | 198 | public int getMaxMergeCount() { |
152 | 199 | return maxMergeCount; |
153 | 200 | } |
| 201 | + |
| 202 | + /** |
| 203 | + * Returns the maximum forced merge rate in MB per second. |
| 204 | + * A value of Double.POSITIVE_INFINITY indicates no rate limiting. |
| 205 | + */ |
| 206 | + public double getMaxForcedMergeMBPerSec() { |
| 207 | + return maxForcedMergeMBPerSec; |
| 208 | + } |
| 209 | + |
| 210 | + /** |
| 211 | + * Sets the maximum forced merge rate in MB per second. |
| 212 | + * A value of Double.POSITIVE_INFINITY disables rate limiting. |
| 213 | + */ |
| 214 | + void setMaxForcedMergeMBPerSec(double maxForcedMergeMBPerSec) { |
| 215 | + this.maxForcedMergeMBPerSec = maxForcedMergeMBPerSec; |
| 216 | + } |
154 | 217 | } |
0 commit comments