HBASE-22739 ArrayIndexOutOfBoundsException when balance (#729)

Signed-off-by: stack <stack@apache.org>
This commit is contained in:
binlijin 2019-10-31 04:28:01 +08:00 committed by Michael Stack
parent 54425bf87b
commit e808ea1d04
2 changed files with 12 additions and 2 deletions

View File

@ -142,6 +142,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
int[] serverIndexToRackIndex; //serverIndex -> rack index int[] serverIndexToRackIndex; //serverIndex -> rack index
int[][] regionsPerServer; //serverIndex -> region list int[][] regionsPerServer; //serverIndex -> region list
int[] serverIndexToRegionsOffset; //serverIndex -> offset of region list
int[][] regionsPerHost; //hostIndex -> list of regions int[][] regionsPerHost; //hostIndex -> list of regions
int[][] regionsPerRack; //rackIndex -> region list int[][] regionsPerRack; //rackIndex -> region list
int[][] primariesOfRegionsPerServer; //serverIndex -> sorted list of regions by primary region index int[][] primariesOfRegionsPerServer; //serverIndex -> sorted list of regions by primary region index
@ -276,6 +277,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
serverIndexToHostIndex = new int[numServers]; serverIndexToHostIndex = new int[numServers];
serverIndexToRackIndex = new int[numServers]; serverIndexToRackIndex = new int[numServers];
regionsPerServer = new int[numServers][]; regionsPerServer = new int[numServers][];
serverIndexToRegionsOffset = new int[numServers];
regionsPerHost = new int[numHosts][]; regionsPerHost = new int[numHosts][];
regionsPerRack = new int[numRacks][]; regionsPerRack = new int[numRacks][];
primariesOfRegionsPerServer = new int[numServers][]; primariesOfRegionsPerServer = new int[numServers][];
@ -321,7 +323,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
for (Entry<ServerName, List<RegionInfo>> entry : clusterState.entrySet()) { for (Entry<ServerName, List<RegionInfo>> entry : clusterState.entrySet()) {
int serverIndex = serversToIndex.get(entry.getKey().getHostAndPort()); int serverIndex = serversToIndex.get(entry.getKey().getHostAndPort());
regionPerServerIndex = 0; regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];
int hostIndex = hostsToIndex.get(entry.getKey().getHostname()); int hostIndex = hostsToIndex.get(entry.getKey().getHostname());
serverIndexToHostIndex[serverIndex] = hostIndex; serverIndexToHostIndex[serverIndex] = hostIndex;
@ -334,6 +336,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex; regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;
regionIndex++; regionIndex++;
} }
serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;
} }
for (RegionInfo region : unassignedRegions) { for (RegionInfo region : unassignedRegions) {

View File

@ -473,7 +473,7 @@ public class TestBaseLoadBalancer extends BalancerTestBase {
// sharing same host and port // sharing same host and port
List<ServerName> servers = getListOfServerNames(randomServers(10, 10)); List<ServerName> servers = getListOfServerNames(randomServers(10, 10));
List<RegionInfo> regions = randomRegions(101); List<RegionInfo> regions = randomRegions(101);
Map<ServerName, List<RegionInfo>> clusterState = new HashMap<>(); Map<ServerName, List<RegionInfo>> clusterState = new TreeMap<>();
assignRegions(regions, servers, clusterState); assignRegions(regions, servers, clusterState);
@ -491,6 +491,13 @@ public class TestBaseLoadBalancer extends BalancerTestBase {
BaseLoadBalancer.Cluster cluster = new Cluster(clusterState, null, null, null); BaseLoadBalancer.Cluster cluster = new Cluster(clusterState, null, null, null);
assertEquals(101 + 9, cluster.numRegions); assertEquals(101 + 9, cluster.numRegions);
assertEquals(10, cluster.numServers); // only 10 servers because they share the same host + port assertEquals(10, cluster.numServers); // only 10 servers because they share the same host + port
// test move
ServerName sn = oldServers.get(0);
int r0 = ArrayUtils.indexOf(cluster.regions, clusterState.get(sn).get(0));
int f0 = cluster.serversToIndex.get(sn.getHostAndPort());
int t0 = cluster.serversToIndex.get(servers.get(1).getHostAndPort());
cluster.doAction(new MoveRegionAction(r0, f0, t0));
} }
private void assignRegions(List<RegionInfo> regions, List<ServerName> servers, private void assignRegions(List<RegionInfo> regions, List<ServerName> servers,