下面列出了怎么用org.apache.hadoop.hbase.master.RegionPlan的API类实例代码及写法,或者点击链接到github查看源代码。
public static List<RegionPlan> makePlan(HBaseAdmin admin, List<RegionPlan> newRegionPlan) throws IOException {
// snapshot current region assignment
Map<HRegionInfo, ServerName> regionAssignmentMap = createRegionAssignmentMap(admin);
// update with new plan
for (RegionPlan regionPlan : newRegionPlan) {
regionAssignmentMap.put(regionPlan.getRegionInfo(), regionPlan.getDestination());
}
Map<ServerName, List<HRegionInfo>> clusterState = initializeRegionMap(admin);
for (Map.Entry<HRegionInfo, ServerName> entry : regionAssignmentMap.entrySet())
clusterState.get(entry.getValue()).add(entry.getKey());
StochasticLoadBalancer balancer = new StochasticLoadBalancer();
Configuration conf = admin.getConfiguration();
conf.setFloat("hbase.regions.slop", 0.2f);
balancer.setConf(conf);
return balancer.balanceCluster(clusterState);
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean preview(List<RegionPlan> regionPlanList, boolean asynchronous) throws IOException, InterruptedException {
final boolean proceed;
if (args.isForceProceed()) {
proceed = true;
} else {
balance(args, regionPlanList, Phase.PREVIEW, asynchronous);
if (regionPlanList.size() > 0) {
System.out.println(regionPlanList.size() + " of " + getRegionAssignmentMap(admin, tableNameSet).size() + " region(s) will be moved.");
warnBalanceAgain(regionPlanList);
proceed = Util.askProceed();
} else {
System.out.println("There is no region to move.");
proceed = false;
}
}
return proceed;
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean preview(List<RegionPlan> regionPlanList, boolean asynchronous) throws IOException, InterruptedException {
final boolean proceed;
if (args.isForceProceed()) {
proceed = true;
} else {
balance(args, regionPlanList, Phase.PREVIEW, asynchronous);
if (regionPlanList.size() > 0) {
System.out.println(regionPlanList.size() + " of " + getRegionAssignmentMap(admin, tableNameSet).size() + " region(s) will be moved.");
warnBalanceAgain(regionPlanList);
proceed = Util.askProceed();
} else {
System.out.println("There is no region to move.");
proceed = false;
}
}
return proceed;
}
public static List<RegionPlan> makePlan(HBaseAdmin admin, List<RegionPlan> newRegionPlan) throws IOException {
// snapshot current region assignment
Map<HRegionInfo, ServerName> regionAssignmentMap = createRegionAssignmentMap(admin);
// update with new plan
for (RegionPlan regionPlan : newRegionPlan) {
regionAssignmentMap.put(regionPlan.getRegionInfo(), regionPlan.getDestination());
}
Map<ServerName, List<HRegionInfo>> clusterState = initializeRegionMap(admin);
for (Map.Entry<HRegionInfo, ServerName> entry : regionAssignmentMap.entrySet())
clusterState.get(entry.getValue()).add(entry.getKey());
StochasticLoadBalancer balancer = new StochasticLoadBalancer();
Configuration conf = admin.getConfiguration();
conf.setFloat("hbase.regions.slop", 0.2f);
balancer.setConf(conf);
return balancer.balanceCluster(clusterState);
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean preview(List<RegionPlan> regionPlanList, boolean asynchronous) throws IOException, InterruptedException {
final boolean proceed;
if (args.isForceProceed()) {
proceed = true;
} else {
balance(args, regionPlanList, Phase.PREVIEW, asynchronous);
if (regionPlanList.size() > 0) {
System.out.println(regionPlanList.size() + " of " + getRegionAssignmentMap(admin, tableNameSet).size() + " region(s) will be moved.");
warnBalanceAgain(regionPlanList);
proceed = Util.askProceed();
} else {
System.out.println("There is no region to move.");
proceed = false;
}
}
return proceed;
}
public static List<RegionPlan> makePlan(HBaseAdmin admin, List<RegionPlan> newRegionPlan) throws IOException {
// snapshot current region assignment
Map<HRegionInfo, ServerName> regionAssignmentMap = createRegionAssignmentMap(admin);
// update with new plan
for (RegionPlan regionPlan : newRegionPlan) {
regionAssignmentMap.put(regionPlan.getRegionInfo(), regionPlan.getDestination());
}
Map<ServerName, List<HRegionInfo>> clusterState = initializeRegionMap(admin);
for (Map.Entry<HRegionInfo, ServerName> entry : regionAssignmentMap.entrySet())
clusterState.get(entry.getValue()).add(entry.getKey());
StochasticLoadBalancer balancer = new StochasticLoadBalancer();
Configuration conf = admin.getConfiguration();
conf.setFloat("hbase.regions.slop", 0.2f);
balancer.setConf(conf);
return balancer.balanceCluster(clusterState);
}
public static List<RegionPlan> makePlan(HBaseAdmin admin, List<RegionPlan> newRegionPlan) throws IOException {
// snapshot current region assignment
Map<HRegionInfo, ServerName> regionAssignmentMap = createRegionAssignmentMap(admin);
// update with new plan
for (RegionPlan regionPlan : newRegionPlan) {
regionAssignmentMap.put(regionPlan.getRegionInfo(), regionPlan.getDestination());
}
Map<ServerName, List<HRegionInfo>> clusterState = initializeRegionMap(admin);
for (Map.Entry<HRegionInfo, ServerName> entry : regionAssignmentMap.entrySet())
clusterState.get(entry.getValue()).add(entry.getKey());
StochasticLoadBalancer balancer = new StochasticLoadBalancer();
Configuration conf = admin.getConfiguration();
conf.setFloat("hbase.regions.slop", 0.2f);
balancer.setConf(conf);
return balancer.balanceCluster(clusterState);
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean preview(List<RegionPlan> regionPlanList, boolean asynchronous) throws IOException, InterruptedException {
final boolean proceed;
if (args.isForceProceed()) {
proceed = true;
} else {
balance(args, regionPlanList, Phase.PREVIEW, asynchronous);
if (regionPlanList.size() > 0) {
System.out.println(regionPlanList.size() + " of " + getRegionAssignmentMap(admin, tableNameSet).size() + " region(s) will be moved.");
warnBalanceAgain(regionPlanList);
proceed = Util.askProceed();
} else {
System.out.println("There is no region to move.");
proceed = false;
}
}
return proceed;
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean preview(List<RegionPlan> regionPlanList, boolean asynchronous) throws IOException, InterruptedException {
final boolean proceed;
if (args.isForceProceed()) {
proceed = true;
} else {
balance(args, regionPlanList, Phase.PREVIEW, asynchronous);
if (regionPlanList.size() > 0) {
System.out.println(regionPlanList.size() + " of " + getRegionAssignmentMap(admin, tableNameSet).size() + " region(s) will be moved.");
warnBalanceAgain(regionPlanList);
proceed = Util.askProceed();
} else {
System.out.println("There is no region to move.");
proceed = false;
}
}
return proceed;
}
@Override
public void postMove(ObserverContext<MasterCoprocessorEnvironment> ctx, HRegionInfo region,
ServerName srcServer, ServerName destServer) throws IOException {
if (balancer != null && balancer.isTableColocated(region.getTable())) {
AssignmentManager am = ctx.getEnvironment().getMasterServices().getAssignmentManager();
RegionStates regionStates = am.getRegionStates();
String tableName = region.getTable().getNameAsString();
String correspondingTable =
region.getTable().getNameAsString()
.startsWith(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX) ? MetaDataUtil
.getUserTableName(tableName) : MetaDataUtil
.getLocalIndexTableName(tableName);
List<HRegionInfo> regions =
regionStates.getRegionsOfTable(TableName.valueOf(correspondingTable));
for (HRegionInfo hri : regions) {
if (Bytes.compareTo(region.getStartKey(), hri.getStartKey()) == 0
&& destServer != null) {
balancer.regionOnline(hri, destServer);
am.addPlan(hri.getEncodedName(), new RegionPlan(hri, null, destServer));
am.unassign(hri);
}
}
}
super.postMove(ctx, region, srcServer, destServer);
}
@Override
public void postBalance(ObserverContext<MasterCoprocessorEnvironment> ctx, List<RegionPlan> plans) throws IOException {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAuthorizationCoprocessor.postBalance()");
}
try {
activatePluginClassLoader();
implMasterObserver.postBalance(ctx, plans);
} finally {
deactivatePluginClassLoader();
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerAuthorizationCoprocessor.postBalance()");
}
}
/**
* Create all of the RegionPlan's needed to move from the initial cluster state to the desired
* state.
*
* @param cluster The state of the cluster
* @return List of RegionPlan's that represent the moves needed to get to desired final state.
*/
private List<RegionPlan> createRegionPlans(Cluster cluster) {
List<RegionPlan> plans = new LinkedList<>();
for (int regionIndex = 0;
regionIndex < cluster.regionIndexToServerIndex.length; regionIndex++) {
int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];
int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];
if (initialServerIndex != newServerIndex) {
RegionInfo region = cluster.regions[regionIndex];
ServerName initialServer = cluster.servers[initialServerIndex];
ServerName newServer = cluster.servers[newServerIndex];
if (LOG.isTraceEnabled()) {
LOG.trace("Moving Region " + region.getEncodedName() + " from server "
+ initialServer.getHostname() + " to " + newServer.getHostname());
}
RegionPlan rp = new RegionPlan(region, initialServer, newServer);
plans.add(rp);
}
}
return plans;
}
@Override
public List<RegionPlan>
balanceCluster(Map<TableName, Map<ServerName, List<RegionInfo>>> loadOfAllTable) {
if (isByTable) {
List<RegionPlan> result = new ArrayList<>();
loadOfAllTable.forEach((tableName, loadOfOneTable) -> {
LOG.info("Start Generate Balance plan for table: " + tableName);
List<RegionPlan> partialPlans = balanceTable(tableName, loadOfOneTable);
if (partialPlans != null) {
result.addAll(partialPlans);
}
});
return result;
} else {
LOG.info("Start Generate Balance plan for cluster.");
return balanceTable(HConstants.ENSEMBLE_TABLE_NAME, toEnsumbleTableLoad(loadOfAllTable));
}
}
/**
* Test the load balancing algorithm.
*
* Invariant is that all servers of the group should be hosting either floor(average) or
* ceiling(average)
*/
@Test
public void testBalanceCluster() throws Exception {
// Test with/without per table balancer.
boolean[] perTableBalancerConfigs = { true, false };
for (boolean isByTable : perTableBalancerConfigs) {
Configuration conf = loadBalancer.getConf();
conf.setBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);
loadBalancer.setConf(conf);
Map<ServerName, List<RegionInfo>> servers = mockClusterServers();
ArrayListMultimap<String, ServerAndLoad> list = convertToGroupBasedMap(servers);
LOG.info("Mock Cluster : " + printStats(list));
Map<TableName, Map<ServerName, List<RegionInfo>>> LoadOfAllTable =
(Map) mockClusterServersWithTables(servers);
List<RegionPlan> plans = loadBalancer.balanceCluster(LoadOfAllTable);
ArrayListMultimap<String, ServerAndLoad> balancedCluster = reconcile(list, plans);
LOG.info("Mock Balance : " + printStats(balancedCluster));
assertClusterAsBalanced(balancedCluster);
}
}
@Test
public void testNeedBalance() {
float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);
conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);
try {
// Test with/without per table balancer.
boolean[] perTableBalancerConfigs = {true, false};
for (boolean isByTable : perTableBalancerConfigs) {
conf.setBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);
loadBalancer.setConf(conf);
for (int[] mockCluster : clusterStateMocks) {
Map<ServerName, List<RegionInfo>> servers = mockClusterServers(mockCluster);
Map<TableName, Map<ServerName, List<RegionInfo>>> LoadOfAllTable =
(Map) mockClusterServersWithTables(servers);
List<RegionPlan> plans = loadBalancer.balanceCluster(LoadOfAllTable);
boolean emptyPlans = plans == null || plans.isEmpty();
assertTrue(emptyPlans || needsBalanceIdleRegion(mockCluster));
}
}
} finally {
// reset config
conf.unset(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE);
conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);
loadBalancer.setConf(conf);
}
}
/**
* This assumes the RegionPlan HSI instances are the same ones in the map, so
* actually no need to even pass in the map, but I think it's clearer.
*
* @param list
* @param plans
* @return a list of all added {@link ServerAndLoad} values.
*/
protected List<ServerAndLoad> reconcile(List<ServerAndLoad> list,
List<RegionPlan> plans,
Map<ServerName, List<RegionInfo>> servers) {
List<ServerAndLoad> result = new ArrayList<>(list.size());
Map<ServerName, ServerAndLoad> map = new HashMap<>(list.size());
for (ServerAndLoad sl : list) {
map.put(sl.getServerName(), sl);
}
if (plans != null) {
for (RegionPlan plan : plans) {
ServerName source = plan.getSource();
updateLoad(map, source, -1);
ServerName destination = plan.getDestination();
updateLoad(map, destination, +1);
servers.get(source).remove(plan.getRegionInfo());
servers.get(destination).add(plan.getRegionInfo());
}
}
result.clear();
result.addAll(map.values());
return result;
}
@Test
public void testOverloaded() throws IOException {
final List<String> rules = Collections.singletonList("rs[0-1] 50");
final int numNodes = 2;
final int numRegions = 120;
final int numRegionsPerServer = 60;
TestStochasticLoadBalancerHeterogeneousCostRules.createRulesFile(RULES_FILE);
final Map<ServerName, List<RegionInfo>> serverMap =
this.createServerMap(numNodes, numRegions, numRegionsPerServer, 1, 1);
final List<RegionPlan> plans =
BalancerTestBase.loadBalancer.balanceTable(HConstants.ENSEMBLE_TABLE_NAME, serverMap);
// As we disabled all the other cost functions, balancing only according to
// the heterogeneous cost function should return nothing.
assertNull(plans);
}
protected ArrayListMultimap<String, ServerAndLoad> reconcile(
ArrayListMultimap<String, ServerAndLoad> previousLoad,
List<RegionPlan> plans) {
ArrayListMultimap<String, ServerAndLoad> result = ArrayListMultimap
.create();
result.putAll(previousLoad);
if (plans != null) {
for (RegionPlan plan : plans) {
ServerName source = plan.getSource();
updateLoad(result, source, -1);
ServerName destination = plan.getDestination();
updateLoad(result, destination, +1);
}
}
return result;
}
public static List<RegionPlan> makePlan(HBaseAdmin admin,
Map<ServerName, List<HRegionInfo>> clusterState, Configuration conf) throws IOException {
StochasticLoadBalancer balancer = new StochasticLoadBalancer() {
@Override
protected boolean needsBalance(ClusterLoadState cs) {
return true;
}
};
balancer.setConf(conf);
balancer.setClusterStatus(admin.getClusterStatus());
List<RegionPlan> regionPlanList = balancer.balanceCluster(clusterState);
return regionPlanList == null ? new ArrayList<RegionPlan>() : regionPlanList;
}
@Override
public void run() throws Exception {
boolean balancerRunning = false;
try {
balancerRunning = turnBalancerOff();
BalanceRule rule = BalanceRule.valueOf(ruleParam.toUpperCase());
if (rule.equals(BalanceRule.DEFAULT)) {
if (!args.isForceProceed()) {
if (!Util.askProceed()) {
return;
}
}
admin.balancer();
System.out.println("Run hbase default balancer. This is an asynchronous operation.");
} else {
List<RegionPlan> regionPlanList = rule.makePlan(admin, tableNameSet, args);
BalanceFactor.printFactor(BalanceFactor.parseArg(args));
boolean asynchronous = args.has(Args.OPTION_MOVE_ASYNC);
if (preview(regionPlanList, asynchronous))
balance(args, regionPlanList, Phase.BALANCE, asynchronous);
}
} finally {
if (balancerRunning) {
// turn balancer on if needed
admin.setBalancerRunning(true, true);
System.out.println("Turn balancer on.");
}
}
}
private boolean warnBalanceAgain(List<RegionPlan> regionPlanList) throws IOException {
List<RegionPlan> allTablePlanList = CommandAdapter.makePlan(admin, regionPlanList);
if (allTablePlanList != null && allTablePlanList.size() > 0) {
System.out.println("Warning - Default load balancer will balance the cluster again. " + allTablePlanList.size() + " regions may be re-balanced.");
return true;
} else
return false;
}
@SuppressWarnings("deprecation")
private void balance(Args args, List<RegionPlan> regionPlanList, Phase phase, boolean asynchronous) throws IOException, InterruptedException {
int progress = 1;
for (RegionPlan regionPlan : regionPlanList) {
String tableName = Bytes.toString(regionPlan.getRegionInfo().getTableName());
String encodedRegionName = regionPlan.getRegionInfo().getEncodedName();
String serverNameDest = regionPlan.getDestination().getServerName();
String serverNameSource;
if (regionPlan.getSource() == null) {
serverNameSource = "N/A";
} else {
serverNameSource = regionPlan.getSource().getServerName();
}
String planStr = progress++ + "/" + regionPlanList.size() + " - move " + encodedRegionName + " of " + tableName + " from " + serverNameSource + " to " + serverNameDest;
if (phase == Phase.BALANCE) {
System.out.print(planStr);
} else {
System.out.println(planStr);
}
if (phase == Phase.BALANCE) {
Common.moveWithPrintingResult(args, admin, tableName, encodedRegionName, serverNameDest, asynchronous);
}
}
if (asynchronous && phase == Phase.BALANCE)
Thread.sleep(Constant.SMALL_WAIT_INTERVAL_MS);
}
@Override
public void run() throws Exception {
boolean balancerRunning = false;
try {
balancerRunning = turnBalancerOff();
BalanceRule rule = BalanceRule.valueOf(ruleParam.toUpperCase());
if (rule.equals(BalanceRule.DEFAULT)) {
if (!args.isForceProceed()) {
if (!Util.askProceed()) {
return;
}
}
admin.balancer();
System.out.println("Run hbase default balancer. This is an asynchronous operation.");
} else {
List<RegionPlan> regionPlanList = rule.makePlan(admin, tableNameSet, args);
BalanceFactor.printFactor(BalanceFactor.parseArg(args));
boolean asynchronous = args.has(Args.OPTION_MOVE_ASYNC);
if (preview(regionPlanList, asynchronous))
balance(args, regionPlanList, Phase.BALANCE, asynchronous);
}
} finally {
if (balancerRunning) {
// turn balancer on if needed
admin.setBalancerRunning(true, true);
System.out.println("Turn balancer on.");
}
}
}
private boolean warnBalanceAgain(List<RegionPlan> regionPlanList) throws IOException {
List<RegionPlan> allTablePlanList = CommandAdapter.makePlan(admin, regionPlanList);
if (allTablePlanList != null && allTablePlanList.size() > 0) {
System.out.println("Warning - Default load balancer will balance the cluster again. " + allTablePlanList.size() + " regions may be re-balanced.");
return true;
} else
return false;
}
@SuppressWarnings("deprecation")
private void balance(Args args, List<RegionPlan> regionPlanList, Phase phase, boolean asynchronous) throws IOException, InterruptedException {
int progress = 1;
for (RegionPlan regionPlan : regionPlanList) {
String tableName = Bytes.toString(regionPlan.getRegionInfo().getTableName());
String encodedRegionName = regionPlan.getRegionInfo().getEncodedName();
String serverNameDest = regionPlan.getDestination().getServerName();
String serverNameSource;
if (regionPlan.getSource() == null) {
serverNameSource = "N/A";
} else {
serverNameSource = regionPlan.getSource().getServerName();
}
String planStr = progress++ + "/" + regionPlanList.size() + " - move " + encodedRegionName + " of " + tableName + " from " + serverNameSource + " to " + serverNameDest;
if (phase == Phase.BALANCE) {
System.out.print(planStr);
} else {
System.out.println(planStr);
}
if (phase == Phase.BALANCE) {
Common.moveWithPrintingResult(args, admin, tableName, encodedRegionName, serverNameDest, asynchronous);
}
}
if (asynchronous && phase == Phase.BALANCE)
Thread.sleep(Constant.SMALL_WAIT_INTERVAL_MS);
}
public static List<RegionPlan> makePlan(HBaseAdmin admin, Map<ServerName, List<HRegionInfo>> clusterState, Configuration conf) throws IOException {
StochasticLoadBalancer balancer = new StochasticLoadBalancer() {
@Override
protected boolean needsBalance(Cluster c) {
return true;
}
};
balancer.setConf(conf);
balancer.setClusterStatus(admin.getClusterStatus());
List<RegionPlan> regionPlanList = balancer.balanceCluster(clusterState);
return regionPlanList == null ? new ArrayList<RegionPlan>() : regionPlanList;
}
@Override
public void run() throws Exception {
boolean balancerRunning = false;
try {
balancerRunning = turnBalancerOff();
BalanceRule rule = BalanceRule.valueOf(ruleParam.toUpperCase());
if (rule.equals(BalanceRule.DEFAULT)) {
if (!args.isForceProceed()) {
if (!Util.askProceed()) {
return;
}
}
admin.balancer();
System.out.println("Run hbase default balancer. This is an asynchronous operation.");
} else {
List<RegionPlan> regionPlanList = rule.makePlan(admin, tableNameSet, args);
BalanceFactor.printFactor(BalanceFactor.parseArg(args));
boolean asynchronous = args.has(Args.OPTION_MOVE_ASYNC);
if (preview(regionPlanList, asynchronous))
balance(args, regionPlanList, Phase.BALANCE, asynchronous);
}
} finally {
if (balancerRunning) {
// turn balancer on if needed
admin.setBalancerRunning(true, true);
System.out.println("Turn balancer on.");
}
}
}
private boolean warnBalanceAgain(List<RegionPlan> regionPlanList) throws IOException {
List<RegionPlan> allTablePlanList = CommandAdapter.makePlan(admin, regionPlanList);
if (allTablePlanList != null && allTablePlanList.size() > 0) {
System.out.println("Warning - Default load balancer will balance the cluster again. " + allTablePlanList.size() + " regions may be re-balanced.");
return true;
} else
return false;
}
@SuppressWarnings("deprecation")
private void balance(Args args, List<RegionPlan> regionPlanList, Phase phase, boolean asynchronous) throws IOException, InterruptedException {
int progress = 1;
for (RegionPlan regionPlan : regionPlanList) {
String tableName = Bytes.toString(regionPlan.getRegionInfo().getTableName());
String encodedRegionName = regionPlan.getRegionInfo().getEncodedName();
String serverNameDest = regionPlan.getDestination().getServerName();
String serverNameSource;
if (regionPlan.getSource() == null) {
serverNameSource = "N/A";
} else {
serverNameSource = regionPlan.getSource().getServerName();
}
String planStr = progress++ + "/" + regionPlanList.size() + " - move " + encodedRegionName + " of " + tableName + " from " + serverNameSource + " to " + serverNameDest;
if (phase == Phase.BALANCE) {
System.out.print(planStr);
} else {
System.out.println(planStr);
}
if (phase == Phase.BALANCE) {
Common.moveWithPrintingResult(args, admin, tableName, encodedRegionName, serverNameDest, asynchronous);
}
}
if (asynchronous && phase == Phase.BALANCE)
Thread.sleep(Constant.SMALL_WAIT_INTERVAL_MS);
}
@Test
public void testRule() throws Exception {
Balance.reset();
BalanceRule rule;
List<RegionPlan> regionPlanListRR, regionPlanListRD;
Set<String> tableNameSet = new HashSet<>();
tableNameSet.add(tableName);
splitTable("a".getBytes());
splitTable("b".getBytes());
splitTable("c".getBytes());
// rule RR
rule = BalanceRule.RR;
regionPlanListRR = rule.makePlan(admin, tableNameSet, null);
Assert.assertNotEquals(0, regionPlanListRR.size());
for (RegionPlan regionPlan : regionPlanListRR) {
Assert.assertNotEquals(regionPlan.getSource().getServerName(), regionPlan.getDestination().getServerName());
}
// rule RD
int max_iteration = 1000;
rule = BalanceRule.RD;
for (int i = 0; i < max_iteration; i++) {
regionPlanListRD = rule.makePlan(admin, tableNameSet, null);
RegionPlan regionPlanRD = regionPlanListRD.get(0);
RegionPlan regionPlanRR = regionPlanListRR.get(0);
if (!regionPlanRD.getRegionInfo().equals(regionPlanRR.getRegionInfo())) {
// RD plan should be different from RR plan
break;
}
if (i == max_iteration - 1) {
Assert.fail("RD rule is not correct");
}
}
}