HoustonPutman commented on code in PR #1650:
URL: https://github.com/apache/solr/pull/1650#discussion_r1226874002
##########
solr/core/src/java/org/apache/solr/cluster/placement/plugins/SimplePlacementFactory.java:
##########
@@ -53,118 +43,116 @@ public PlacementPlugin createPluginInstance() {
return new SimplePlacementPlugin();
}
- public static class SimplePlacementPlugin implements PlacementPlugin {
- @Override
- public List<PlacementPlan> computePlacements(
- Collection<PlacementRequest> requests, PlacementContext
placementContext)
- throws PlacementException {
- List<PlacementPlan> placementPlans = new ArrayList<>(requests.size());
- Map<Node, ReplicaCount> nodeVsShardCount =
getNodeVsShardCount(placementContext);
- for (PlacementRequest request : requests) {
- int totalReplicasPerShard = 0;
- for (Replica.ReplicaType rt : Replica.ReplicaType.values()) {
- totalReplicasPerShard += request.getCountReplicasToCreate(rt);
- }
-
- Set<ReplicaPlacement> replicaPlacements =
- CollectionUtil.newHashSet(totalReplicasPerShard *
request.getShardNames().size());
-
- Collection<ReplicaCount> replicaCounts = nodeVsShardCount.values();
-
- if (request.getTargetNodes().size() < replicaCounts.size()) {
- replicaCounts =
- replicaCounts.stream()
- .filter(rc -> request.getTargetNodes().contains(rc.node()))
- .collect(Collectors.toList());
- }
-
- for (String shard : request.getShardNames()) {
- // Reset the ordering of the nodes for each shard, using the
replicas added in the
- // previous shards and assign requests
- List<Node> nodeList =
- replicaCounts.stream()
- .sorted(
- Comparator.<ReplicaCount>comparingInt(
- rc ->
rc.weight(request.getCollection().getName()))
- .thenComparing(ReplicaCount::nodeName))
- .map(ReplicaCount::node)
- .collect(Collectors.toList());
- int replicaNumOfShard = 0;
- for (Replica.ReplicaType replicaType : Replica.ReplicaType.values())
{
- for (int i = 0; i < request.getCountReplicasToCreate(replicaType);
i++) {
- Node assignedNode = nodeList.get(replicaNumOfShard++ %
nodeList.size());
-
- replicaPlacements.add(
- placementContext
- .getPlacementPlanFactory()
- .createReplicaPlacement(
- request.getCollection(), shard, assignedNode,
replicaType));
-
- ReplicaCount replicaCount =
- nodeVsShardCount.computeIfAbsent(assignedNode,
ReplicaCount::new);
- replicaCount.totalReplicas++;
- replicaCount.collectionReplicas.merge(
- request.getCollection().getName(), 1, Integer::sum);
- }
- }
- }
-
- placementPlans.add(
- placementContext
- .getPlacementPlanFactory()
- .createPlacementPlan(request, replicaPlacements));
- }
- return placementPlans;
- }
+ public static class SimplePlacementPlugin extends OrderedNodePlacementPlugin
{
- private Map<Node, ReplicaCount> getNodeVsShardCount(PlacementContext
placementContext) {
- HashMap<Node, ReplicaCount> nodeVsShardCount = new HashMap<>();
-
- for (Node s : placementContext.getCluster().getLiveDataNodes()) {
- nodeVsShardCount.computeIfAbsent(s, ReplicaCount::new);
+ @Override
+ protected Map<Node, WeightedNode> getBaseWeightedNodes(
+ PlacementContext placementContext,
+ Set<Node> nodes,
+ Iterable<SolrCollection> relevantCollections,
+ boolean skipNodesWithErrors) {
+ HashMap<Node, WeightedNode> nodeVsShardCount = new HashMap<>();
+
+ for (Node n : nodes) {
+ nodeVsShardCount.computeIfAbsent(n, SameCollWeightedNode::new);
}
- // if we get here we were not given a createNodeList, build a map with
real counts.
- for (SolrCollection collection :
placementContext.getCluster().collections()) {
- // identify suitable nodes by checking the no:of cores in each of them
- for (Shard shard : collection.shards()) {
- for (Replica replica : shard.replicas()) {
- ReplicaCount count = nodeVsShardCount.get(replica.getNode());
- if (count != null) {
- count.addReplica(collection.getName(), shard.getShardName());
- }
- }
- }
- }
return nodeVsShardCount;
}
}
- static class ReplicaCount {
- public final Node node;
+ private static class SameCollWeightedNode extends
OrderedNodePlacementPlugin.WeightedNode {
+ private static final int SAME_COL_MULT = 5;
+ private static final int SAME_SHARD_MULT = 1000;
public Map<String, Integer> collectionReplicas;
- public int totalReplicas = 0;
+ public int totalWeight = 0;
- ReplicaCount(Node node) {
- this.node = node;
+ SameCollWeightedNode(Node node) {
+ super(node);
this.collectionReplicas = new HashMap<>();
}
- public int weight(String collection) {
- return (collectionReplicas.getOrDefault(collection, 0) * 5) +
totalReplicas;
+ /**
+ * The weight of the SameCollWeightedNode is the sum of:
Review Comment:
This formula kind of existed beforehand.
Basically there didn't use to be a "node weight", but this one class in
particular had a "node weight for replica". It was basically:
`(the number of replicas in the collection on the node) * 5 + (total
replicas on node)`.
As a part of this PR I made this a bit better with:
`(the number of replicas in the collection on the node) * 5 + (the number of
replicas in the shard on the node) * 100 + (total replicas on node)`
When trying to convert this to a full node weight, a node with 4 replicas of
the same collection will be weighted the same as a node with 2 replicas of one
collection, and 2 replicas of another collection (because `2*5 + 2*5 = 4*5`).
This isn't really in the spirit of the logic, we want to end up with less
replicas of the same collections on nodes. So it makes more sense to square the
number of replicas in the same (collection|shard). That way`12^2*5 + 2^2*5 <
4^2* 5`. (And then I subtracted 1, because there's no reason to penalize the
first replica of each shard/collection.)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]