Skip to content

Commit 8d2be34

Browse files
committed
refactor two candidate generators to stick to immutable annonation
1 parent 846982b commit 8d2be34

File tree

5 files changed

+214
-147
lines changed

5 files changed

+214
-147
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.master.balancer;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import org.apache.hadoop.hbase.ServerName;
23+
import org.apache.hadoop.hbase.client.RegionInfo;
24+
import org.apache.hadoop.hbase.favored.FavoredNodesManager;
25+
import org.apache.yetus.audience.InterfaceAudience;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/*
30+
* This is like LoadCandidateGenerator, but we choose appropriate FN for the region on the
31+
* most loaded server.
32+
*/
33+
@InterfaceAudience.Private
34+
public class FavoredNodeLoadPicker extends CandidateGenerator {
35+
private static final Logger LOG = LoggerFactory.getLogger(FavoredNodeLoadPicker.class);
36+
private final FavoredNodesManager fnm;
37+
38+
public FavoredNodeLoadPicker(FavoredNodesManager fnm) {
39+
this.fnm = fnm;
40+
}
41+
42+
@Override
43+
BalanceAction generate(BalancerClusterState cluster) {
44+
cluster.sortServersByRegionCount();
45+
int thisServer = pickMostLoadedServer(cluster);
46+
int thisRegion = pickRandomRegion(cluster, thisServer, 0);
47+
RegionInfo hri = cluster.regions[thisRegion];
48+
int otherServer;
49+
List<ServerName> favoredNodes = fnm.getFavoredNodes(hri);
50+
if (favoredNodes == null) {
51+
if (!FavoredNodesManager.isFavoredNodeApplicable(hri)) {
52+
otherServer = pickLeastLoadedServer(cluster, thisServer);
53+
} else {
54+
return BalanceAction.NULL_ACTION;
55+
}
56+
} else {
57+
otherServer = pickLeastLoadedFNServer(cluster, favoredNodes, thisServer);
58+
}
59+
return getAction(thisServer, thisRegion, otherServer, -1);
60+
}
61+
62+
private int pickLeastLoadedServer(final BalancerClusterState cluster, int thisServer) {
63+
Integer[] servers = cluster.serverIndicesSortedByRegionCount;
64+
int index;
65+
for (index = 0; index < servers.length ; index++) {
66+
if ((servers[index] != null) && servers[index] != thisServer) {
67+
break;
68+
}
69+
}
70+
return servers[index];
71+
}
72+
73+
private int pickLeastLoadedFNServer(final BalancerClusterState cluster,
74+
List<ServerName> favoredNodes, int currentServerIndex) {
75+
List<Integer> fnIndex = new ArrayList<>();
76+
for (ServerName sn : favoredNodes) {
77+
if (cluster.serversToIndex.containsKey(sn.getAddress())) {
78+
fnIndex.add(cluster.serversToIndex.get(sn.getAddress()));
79+
}
80+
}
81+
int leastLoadedFN = -1;
82+
int load = Integer.MAX_VALUE;
83+
for (Integer index : fnIndex) {
84+
if (index != currentServerIndex) {
85+
int temp = cluster.getNumRegions(index);
86+
if (temp < load) {
87+
load = temp;
88+
leastLoadedFN = index;
89+
}
90+
}
91+
}
92+
return leastLoadedFN;
93+
}
94+
95+
private int pickMostLoadedServer(final BalancerClusterState cluster) {
96+
Integer[] servers = cluster.serverIndicesSortedByRegionCount;
97+
int index;
98+
for (index = servers.length - 1; index > 0 ; index--) {
99+
if (servers[index] != null) {
100+
break;
101+
}
102+
}
103+
return servers[index];
104+
}
105+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.master.balancer;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import org.apache.hadoop.hbase.ServerName;
23+
import org.apache.hadoop.hbase.client.RegionInfo;
24+
import org.apache.hadoop.hbase.favored.FavoredNodesManager;
25+
import org.apache.yetus.audience.InterfaceAudience;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/**
30+
* Pick favored nodes with the highest locality for a region with lowest locality.
31+
*/
32+
@InterfaceAudience.Private
33+
public class FavoredNodeLocalityPicker extends CandidateGenerator {
34+
private static final Logger LOG = LoggerFactory.getLogger(FavoredNodeLocalityPicker.class);
35+
private final FavoredNodesManager fnm;
36+
37+
public FavoredNodeLocalityPicker(FavoredNodesManager fnm) {
38+
this.fnm = fnm;
39+
}
40+
41+
@Override
42+
protected BalanceAction generate(BalancerClusterState cluster) {
43+
44+
int thisServer = pickRandomServer(cluster);
45+
int thisRegion;
46+
if (thisServer == -1) {
47+
LOG.trace("Could not pick lowest local region server");
48+
return BalanceAction.NULL_ACTION;
49+
} else {
50+
// Pick lowest local region on this server
51+
thisRegion = pickLowestLocalRegionOnServer(cluster, thisServer);
52+
}
53+
if (thisRegion == -1) {
54+
if (cluster.regionsPerServer[thisServer].length > 0) {
55+
LOG.trace("Could not pick lowest local region even when region server held "
56+
+ cluster.regionsPerServer[thisServer].length + " regions");
57+
}
58+
return BalanceAction.NULL_ACTION;
59+
}
60+
61+
RegionInfo hri = cluster.regions[thisRegion];
62+
List<ServerName> favoredNodes = fnm.getFavoredNodes(hri);
63+
int otherServer;
64+
if (favoredNodes == null) {
65+
if (!FavoredNodesManager.isFavoredNodeApplicable(hri)) {
66+
otherServer = pickOtherRandomServer(cluster, thisServer);
67+
} else {
68+
// No FN, ignore
69+
LOG.trace("Ignoring, no favored nodes for region: " + hri);
70+
return BalanceAction.NULL_ACTION;
71+
}
72+
} else {
73+
// Pick other favored node with the highest locality
74+
otherServer = getDifferentFavoredNode(cluster, favoredNodes, thisServer);
75+
}
76+
return getAction(thisServer, thisRegion, otherServer, -1);
77+
}
78+
79+
private int getDifferentFavoredNode(BalancerClusterState cluster, List<ServerName> favoredNodes,
80+
int currentServer) {
81+
List<Integer> fnIndex = new ArrayList<>();
82+
for (ServerName sn : favoredNodes) {
83+
if (cluster.serversToIndex.containsKey(sn.getAddress())) {
84+
fnIndex.add(cluster.serversToIndex.get(sn.getAddress()));
85+
}
86+
}
87+
float locality = 0;
88+
int highestLocalRSIndex = -1;
89+
for (Integer index : fnIndex) {
90+
if (index != currentServer) {
91+
float temp = cluster.localityPerServer[index];
92+
if (temp >= locality) {
93+
locality = temp;
94+
highestLocalRSIndex = index;
95+
}
96+
}
97+
}
98+
return highestLocalRSIndex;
99+
}
100+
101+
private int pickLowestLocalRegionOnServer(BalancerClusterState cluster, int server) {
102+
return cluster.getLowestLocalityRegionOnServer(server);
103+
}
104+
}

hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredStochasticBalancer.java

Lines changed: 3 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class FavoredStochasticBalancer extends StochasticLoadBalancer implements
7575

7676
private static final Logger LOG = LoggerFactory.getLogger(FavoredStochasticBalancer.class);
7777

78-
private FavoredNodesManager fnm;
78+
protected FavoredNodesManager fnm;
7979

8080
@Override
8181
public void setFavoredNodesManager(FavoredNodesManager fnm) {
@@ -85,8 +85,8 @@ public void setFavoredNodesManager(FavoredNodesManager fnm) {
8585
@Override
8686
protected List<CandidateGenerator> createCandidateGenerators() {
8787
List<CandidateGenerator> fnPickers = new ArrayList<>(2);
88-
fnPickers.add(new FavoredNodeLoadPicker());
89-
fnPickers.add(new FavoredNodeLocalityPicker());
88+
fnPickers.add(new FavoredNodeLoadPicker(fnm));
89+
fnPickers.add(new FavoredNodeLocalityPicker(fnm));
9090
return fnPickers;
9191
}
9292

@@ -516,147 +516,6 @@ public void generateFavoredNodesForMergedRegion(RegionInfo merged, RegionInfo []
516516
updateFavoredNodesForRegion(merged, fnm.getFavoredNodes(mergeParents[0]));
517517
}
518518

519-
/**
520-
* Pick favored nodes with the highest locality for a region with lowest locality.
521-
*/
522-
private class FavoredNodeLocalityPicker extends CandidateGenerator {
523-
524-
@Override
525-
protected BalanceAction generate(BalancerClusterState cluster) {
526-
527-
int thisServer = pickRandomServer(cluster);
528-
int thisRegion;
529-
if (thisServer == -1) {
530-
LOG.trace("Could not pick lowest local region server");
531-
return BalanceAction.NULL_ACTION;
532-
} else {
533-
// Pick lowest local region on this server
534-
thisRegion = pickLowestLocalRegionOnServer(cluster, thisServer);
535-
}
536-
if (thisRegion == -1) {
537-
if (cluster.regionsPerServer[thisServer].length > 0) {
538-
LOG.trace("Could not pick lowest local region even when region server held "
539-
+ cluster.regionsPerServer[thisServer].length + " regions");
540-
}
541-
return BalanceAction.NULL_ACTION;
542-
}
543-
544-
RegionInfo hri = cluster.regions[thisRegion];
545-
List<ServerName> favoredNodes = fnm.getFavoredNodes(hri);
546-
int otherServer;
547-
if (favoredNodes == null) {
548-
if (!FavoredNodesManager.isFavoredNodeApplicable(hri)) {
549-
otherServer = pickOtherRandomServer(cluster, thisServer);
550-
} else {
551-
// No FN, ignore
552-
LOG.trace("Ignoring, no favored nodes for region: " + hri);
553-
return BalanceAction.NULL_ACTION;
554-
}
555-
} else {
556-
// Pick other favored node with the highest locality
557-
otherServer = getDifferentFavoredNode(cluster, favoredNodes, thisServer);
558-
}
559-
return getAction(thisServer, thisRegion, otherServer, -1);
560-
}
561-
562-
private int getDifferentFavoredNode(BalancerClusterState cluster, List<ServerName> favoredNodes,
563-
int currentServer) {
564-
List<Integer> fnIndex = new ArrayList<>();
565-
for (ServerName sn : favoredNodes) {
566-
if (cluster.serversToIndex.containsKey(sn.getAddress())) {
567-
fnIndex.add(cluster.serversToIndex.get(sn.getAddress()));
568-
}
569-
}
570-
float locality = 0;
571-
int highestLocalRSIndex = -1;
572-
for (Integer index : fnIndex) {
573-
if (index != currentServer) {
574-
float temp = cluster.localityPerServer[index];
575-
if (temp >= locality) {
576-
locality = temp;
577-
highestLocalRSIndex = index;
578-
}
579-
}
580-
}
581-
return highestLocalRSIndex;
582-
}
583-
584-
private int pickLowestLocalRegionOnServer(BalancerClusterState cluster, int server) {
585-
return cluster.getLowestLocalityRegionOnServer(server);
586-
}
587-
}
588-
589-
/*
590-
* This is like LoadCandidateGenerator, but we choose appropriate FN for the region on the
591-
* most loaded server.
592-
*/
593-
class FavoredNodeLoadPicker extends CandidateGenerator {
594-
595-
@Override
596-
BalanceAction generate(BalancerClusterState cluster) {
597-
cluster.sortServersByRegionCount();
598-
int thisServer = pickMostLoadedServer(cluster);
599-
int thisRegion = pickRandomRegion(cluster, thisServer, 0);
600-
RegionInfo hri = cluster.regions[thisRegion];
601-
int otherServer;
602-
List<ServerName> favoredNodes = fnm.getFavoredNodes(hri);
603-
if (favoredNodes == null) {
604-
if (!FavoredNodesManager.isFavoredNodeApplicable(hri)) {
605-
otherServer = pickLeastLoadedServer(cluster, thisServer);
606-
} else {
607-
return BalanceAction.NULL_ACTION;
608-
}
609-
} else {
610-
otherServer = pickLeastLoadedFNServer(cluster, favoredNodes, thisServer);
611-
}
612-
return getAction(thisServer, thisRegion, otherServer, -1);
613-
}
614-
615-
private int pickLeastLoadedServer(final BalancerClusterState cluster, int thisServer) {
616-
Integer[] servers = cluster.serverIndicesSortedByRegionCount;
617-
int index;
618-
for (index = 0; index < servers.length ; index++) {
619-
if ((servers[index] != null) && servers[index] != thisServer) {
620-
break;
621-
}
622-
}
623-
return servers[index];
624-
}
625-
626-
private int pickLeastLoadedFNServer(final BalancerClusterState cluster,
627-
List<ServerName> favoredNodes, int currentServerIndex) {
628-
List<Integer> fnIndex = new ArrayList<>();
629-
for (ServerName sn : favoredNodes) {
630-
if (cluster.serversToIndex.containsKey(sn.getAddress())) {
631-
fnIndex.add(cluster.serversToIndex.get(sn.getAddress()));
632-
}
633-
}
634-
int leastLoadedFN = -1;
635-
int load = Integer.MAX_VALUE;
636-
for (Integer index : fnIndex) {
637-
if (index != currentServerIndex) {
638-
int temp = cluster.getNumRegions(index);
639-
if (temp < load) {
640-
load = temp;
641-
leastLoadedFN = index;
642-
}
643-
}
644-
}
645-
return leastLoadedFN;
646-
}
647-
648-
private int pickMostLoadedServer(final BalancerClusterState cluster) {
649-
Integer[] servers = cluster.serverIndicesSortedByRegionCount;
650-
int index;
651-
for (index = servers.length - 1; index > 0 ; index--) {
652-
if (servers[index] != null) {
653-
break;
654-
}
655-
}
656-
return servers[index];
657-
}
658-
}
659-
660519
/**
661520
* For all regions correctly assigned to favored nodes, we just use the stochastic balancer
662521
* implementation. For the misplaced regions, we assign a bogus server to it and AM takes care.

hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/LoadOnlyFavoredStochasticBalancer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class LoadOnlyFavoredStochasticBalancer extends FavoredStochasticBalancer
2828
@Override
2929
protected List<CandidateGenerator> createCandidateGenerators() {
3030
List<CandidateGenerator> fnPickers = new ArrayList<>(1);
31-
fnPickers.add(new FavoredNodeLoadPicker());
31+
fnPickers.add(new FavoredNodeLoadPicker(fnm));
3232
return fnPickers;
3333
}
3434
}

hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,7 @@ public boolean evaluate() throws Exception {
197197
+ cluster.servers[servers[servers.length -1]]);
198198
}
199199
assertEquals(mostLoadedServer, cluster.servers[servers[servers.length - 1]]);
200-
FavoredStochasticBalancer.FavoredNodeLoadPicker loadPicker =
201-
balancer.new FavoredNodeLoadPicker();
200+
FavoredNodeLoadPicker loadPicker = new FavoredNodeLoadPicker(fnm);
202201
boolean userRegionPicked = false;
203202
for (int i = 0; i < 100; i++) {
204203
if (userRegionPicked) {

0 commit comments

Comments
 (0)