@@ -168,14 +168,17 @@ private void collectAndRecordNodeWeightStats(Balancer balancer, WeightFunction w
168168 Map <DiscoveryNode , DesiredBalanceMetrics .NodeWeightStats > nodeLevelWeights = new HashMap <>();
169169 for (var entry : balancer .nodes .entrySet ()) {
170170 var node = entry .getValue ();
171+ var nodeWeight = weightFunction .nodeWeight (
172+ node .numShards (),
173+ balancer .avgShardsPerNode (),
174+ node .writeLoad (),
175+ balancer .avgWriteLoadPerNode (),
176+ node .diskUsageInBytes (),
177+ balancer .avgDiskUsageInBytesPerNode ()
178+ );
171179 nodeLevelWeights .put (
172180 node .routingNode .node (),
173- new DesiredBalanceMetrics .NodeWeightStats (
174- node .numShards (),
175- node .diskUsageInBytes (),
176- node .writeLoad (),
177- weightFunction .nodeWeight (balancer , node )
178- )
181+ new DesiredBalanceMetrics .NodeWeightStats (node .numShards (), node .diskUsageInBytes (), node .writeLoad (), nodeWeight )
179182 );
180183 }
181184 allocation .routingNodes ().setBalanceWeightStatsPerNode (nodeLevelWeights );
@@ -252,65 +255,6 @@ public float getShardBalance() {
252255 return shardBalanceFactor ;
253256 }
254257
255- /**
256- * This class is the primary weight function used to create balanced over nodes and shards in the cluster.
257- * Currently this function has 3 properties:
258- * <ul>
259- * <li><code>index balance</code> - balance property over shards per index</li>
260- * <li><code>shard balance</code> - balance property over shards per cluster</li>
261- * </ul>
262- * <p>
263- * Each of these properties are expressed as factor such that the properties factor defines the relative
264- * importance of the property for the weight function. For example if the weight function should calculate
265- * the weights only based on a global (shard) balance the index balance can be set to {@code 0.0} and will
266- * in turn have no effect on the distribution.
267- * </p>
268- * The weight per index is calculated based on the following formula:
269- * <ul>
270- * <li>
271- * <code>weight<sub>index</sub>(node, index) = indexBalance * (node.numShards(index) - avgShardsPerNode(index))</code>
272- * </li>
273- * <li>
274- * <code>weight<sub>node</sub>(node, index) = shardBalance * (node.numShards() - avgShardsPerNode)</code>
275- * </li>
276- * </ul>
277- * <code>weight(node, index) = weight<sub>index</sub>(node, index) + weight<sub>node</sub>(node, index)</code>
278- */
279- private static class WeightFunction {
280-
281- private final float theta0 ;
282- private final float theta1 ;
283- private final float theta2 ;
284- private final float theta3 ;
285-
286- WeightFunction (float shardBalance , float indexBalance , float writeLoadBalance , float diskUsageBalance ) {
287- float sum = shardBalance + indexBalance + writeLoadBalance + diskUsageBalance ;
288- if (sum <= 0.0f ) {
289- throw new IllegalArgumentException ("Balance factors must sum to a value > 0 but was: " + sum );
290- }
291- theta0 = shardBalance / sum ;
292- theta1 = indexBalance / sum ;
293- theta2 = writeLoadBalance / sum ;
294- theta3 = diskUsageBalance / sum ;
295- }
296-
297- float weight (Balancer balancer , ModelNode node , String index ) {
298- final float weightIndex = node .numShards (index ) - balancer .avgShardsPerNode (index );
299- return nodeWeight (balancer , node ) + theta1 * weightIndex ;
300- }
301-
302- float nodeWeight (Balancer balancer , ModelNode node ) {
303- final float weightShard = node .numShards () - balancer .avgShardsPerNode ();
304- final float ingestLoad = (float ) (node .writeLoad () - balancer .avgWriteLoadPerNode ());
305- final float diskUsage = (float ) (node .diskUsageInBytes () - balancer .avgDiskUsageInBytesPerNode ());
306- return theta0 * weightShard + theta2 * ingestLoad + theta3 * diskUsage ;
307- }
308-
309- float minWeightDelta (Balancer balancer , String index ) {
310- return theta0 * 1 + theta1 * 1 + theta2 * balancer .getShardWriteLoad (index ) + theta3 * balancer .maxShardSizeBytes (index );
311- }
312- }
313-
314258 /**
315259 * A {@link Balancer}
316260 */
@@ -335,63 +279,13 @@ private Balancer(WriteLoadForecaster writeLoadForecaster, RoutingAllocation allo
335279 this .metadata = allocation .metadata ();
336280 this .weight = weight ;
337281 this .threshold = threshold ;
338- avgShardsPerNode = (( float ) metadata . getTotalNumberOfShards ()) / routingNodes . size ( );
339- avgWriteLoadPerNode = getTotalWriteLoad (writeLoadForecaster , metadata ) / routingNodes . size ( );
340- avgDiskUsageInBytesPerNode = (( double ) getTotalDiskUsageInBytes ( allocation .clusterInfo (), metadata ) / routingNodes . size () );
282+ avgShardsPerNode = WeightFunction . avgShardPerNode ( metadata , routingNodes );
283+ avgWriteLoadPerNode = WeightFunction . avgWriteLoadPerNode (writeLoadForecaster , metadata , routingNodes );
284+ avgDiskUsageInBytesPerNode = WeightFunction . avgDiskUsageInBytesPerNode ( allocation .clusterInfo (), metadata , routingNodes );
341285 nodes = Collections .unmodifiableMap (buildModelFromAssigned ());
342286 sorter = newNodeSorter ();
343287 }
344288
345- private static double getTotalWriteLoad (WriteLoadForecaster writeLoadForecaster , Metadata metadata ) {
346- double writeLoad = 0.0 ;
347- for (IndexMetadata indexMetadata : metadata .indices ().values ()) {
348- writeLoad += getIndexWriteLoad (writeLoadForecaster , indexMetadata );
349- }
350- return writeLoad ;
351- }
352-
353- private static double getIndexWriteLoad (WriteLoadForecaster writeLoadForecaster , IndexMetadata indexMetadata ) {
354- var shardWriteLoad = writeLoadForecaster .getForecastedWriteLoad (indexMetadata ).orElse (0.0 );
355- return shardWriteLoad * numberOfCopies (indexMetadata );
356- }
357-
358- private static long getTotalDiskUsageInBytes (ClusterInfo clusterInfo , Metadata metadata ) {
359- long totalDiskUsageInBytes = 0 ;
360- for (IndexMetadata indexMetadata : metadata .indices ().values ()) {
361- totalDiskUsageInBytes += getIndexDiskUsageInBytes (clusterInfo , indexMetadata );
362- }
363- return totalDiskUsageInBytes ;
364- }
365-
366- // Visible for testing
367- static long getIndexDiskUsageInBytes (ClusterInfo clusterInfo , IndexMetadata indexMetadata ) {
368- if (indexMetadata .ignoreDiskWatermarks ()) {
369- // disk watermarks are ignored for partial searchable snapshots
370- // and is equivalent to indexMetadata.isPartialSearchableSnapshot()
371- return 0 ;
372- }
373- final long forecastedShardSize = indexMetadata .getForecastedShardSizeInBytes ().orElse (-1L );
374- long totalSizeInBytes = 0 ;
375- int shardCount = 0 ;
376- for (int shard = 0 ; shard < indexMetadata .getNumberOfShards (); shard ++) {
377- final ShardId shardId = new ShardId (indexMetadata .getIndex (), shard );
378- final long primaryShardSize = Math .max (forecastedShardSize , clusterInfo .getShardSize (shardId , true , -1L ));
379- if (primaryShardSize != -1L ) {
380- totalSizeInBytes += primaryShardSize ;
381- shardCount ++;
382- }
383- final long replicaShardSize = Math .max (forecastedShardSize , clusterInfo .getShardSize (shardId , false , -1L ));
384- if (replicaShardSize != -1L ) {
385- totalSizeInBytes += replicaShardSize * indexMetadata .getNumberOfReplicas ();
386- shardCount += indexMetadata .getNumberOfReplicas ();
387- }
388- }
389- if (shardCount == numberOfCopies (indexMetadata )) {
390- return totalSizeInBytes ;
391- }
392- return shardCount == 0 ? 0 : (totalSizeInBytes / shardCount ) * numberOfCopies (indexMetadata );
393- }
394-
395289 private static long getShardDiskUsageInBytes (ShardRouting shardRouting , IndexMetadata indexMetadata , ClusterInfo clusterInfo ) {
396290 if (indexMetadata .ignoreDiskWatermarks ()) {
397291 // disk watermarks are ignored for partial searchable snapshots
@@ -401,10 +295,6 @@ private static long getShardDiskUsageInBytes(ShardRouting shardRouting, IndexMet
401295 return Math .max (indexMetadata .getForecastedShardSizeInBytes ().orElse (0L ), clusterInfo .getShardSize (shardRouting , 0L ));
402296 }
403297
404- private static int numberOfCopies (IndexMetadata indexMetadata ) {
405- return indexMetadata .getNumberOfShards () * (1 + indexMetadata .getNumberOfReplicas ());
406- }
407-
408298 private float getShardWriteLoad (String index ) {
409299 return (float ) writeLoadForecaster .getForecastedWriteLoad (metadata .index (index )).orElse (0.0 );
410300 }
@@ -1433,7 +1323,7 @@ public float weight(ModelNode node) {
14331323 }
14341324
14351325 public float minWeightDelta () {
1436- return function .minWeightDelta (balancer , index );
1326+ return function .minWeightDelta (balancer . getShardWriteLoad ( index ), balancer . maxShardSizeBytes ( index ) );
14371327 }
14381328
14391329 @ Override
0 commit comments