/** * 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; }
/** * 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 */ 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 testCompareTo() { RegionInfo hri = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName())).build(); RegionPlan a = new RegionPlan(hri, null, null); RegionPlan b = new RegionPlan(hri, null, null); assertEquals(0, a.compareTo(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, null, null); assertEquals(1, a.compareTo(b)); a = new RegionPlan(hri, null, null); b = new RegionPlan(hri, SRC, null); assertEquals(-1, a.compareTo(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, SRC, null); assertEquals(0, a.compareTo(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, SRC, DEST); assertEquals(-1, a.compareTo(b)); a = new RegionPlan(hri, SRC, DEST); b = new RegionPlan(hri, SRC, DEST); assertEquals(0, a.compareTo(b)); }
public Future<byte[]> moveAsync(RegionPlan regionPlan) throws HBaseIOException { TransitRegionStateProcedure proc = createMoveRegionProcedure(regionPlan.getRegionInfo(), regionPlan.getDestination()); return ProcedureSyncWait.submitProcedure(master.getMasterProcedureExecutor(), proc); }
@Override protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException { super.serializeStateData(serializer); final MoveRegionStateData.Builder state = MoveRegionStateData.newBuilder() // No need to serialize the RegionInfo. The super class has the region. .setSourceServer(ProtobufUtil.toServerName(plan.getSource())); if (plan.getDestination() != null) { state.setDestinationServer(ProtobufUtil.toServerName(plan.getDestination())); } serializer.serialize(state.build()); }
@Test public void testEqualsWithNulls() { RegionInfo hri = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName())).build(); RegionPlan a = new RegionPlan(hri, null, null); RegionPlan b = new RegionPlan(hri, null, null); assertTrue(a.equals(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, null, null); assertFalse(a.equals(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, SRC, null); assertTrue(a.equals(b)); a = new RegionPlan(hri, SRC, null); b = new RegionPlan(hri, SRC, DEST); assertFalse(a.equals(b)); }
List<Integer> pos = returnMap.get(regionsToReturn.get(i).getDestination()); if (pos == null) { pos = new ArrayList<>(); returnMap.put(regionsToReturn.get(i).getDestination(), pos); hriToPlan = balanceInfo.getHriList().get(balanceInfo.getNextRegionForUnload()); RegionPlan maxPlan = new RegionPlan(hriToPlan, serverload.getServerName(), null); regionsToMove.add(maxPlan); setLoad(serverLoadList, i, -1); shredLoad = SnLoadMap.get(plan.getSource()); if(!sourceMap.containsKey(plan.getSource())) sourceMap.put(plan.getSource(), 0); sourceMap.put(plan.getSource(), sourceMap.get(plan.getSource()) + 1); if(shredLoad.getSecond() < assignLength && sourceMap.get(plan.getSource()) == 1) { planToRemoveList.add(plan); List<Integer> pos = returnMap.get(regionsToReturn.get(regionsToReturn.size() - 1).getSource()); if (pos != null && pos.size() != 0) { regionsToReturn.get(pos.get(pos.size() - 1)).setDestination( regionsToReturn.get(regionsToReturn.size() - 1).getDestination()); pos.remove(pos.size() - 1); regionsToReturn.remove(regionsToReturn.size() - 1);
RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest); assert rp.getDestination() != null: rp.toString() + " " + dest; this.cpHost.preMove(hri, rp.getSource(), rp.getDestination()); serverManager.sendRegionWarmup(rp.getDestination(), hri); this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());
existingPlan = this.regionPlans.get(encodedName); if (existingPlan != null && existingPlan.getDestination() != null) { LOG.debug("Found an existing plan for " + state.getRegion().getRegionNameAsString() + " destination server is " + existingPlan.getDestination().toString()); || existingPlan.getDestination() == null || drainingServers.contains(existingPlan.getDestination())) { newPlan = true; randomPlan = new RegionPlan(state.getRegion(), null, balancer .randomAssignment(servers)); this.regionPlans.put(encodedName, randomPlan);
for (RegionInfo regionInfo : regionsShouldMove) { RegionPlan plan = new RegionPlan(regionInfo, server, null); if (regionInfo.isMetaRegion()) { plan.getRegionInfo().getEncodedName(), server); moveAsync(plan);
RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest); if (this.cpHost.preMove(hri, rp.getSource(), rp.getDestination())) { return; serverManager.sendRegionWarmup(rp.getDestination(), hri); this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());
/** * @param plan Plan to execute. */ public void balance(final RegionPlan plan) { HRegionInfo hri = plan.getRegionInfo(); TableName tableName = hri.getTable(); if (tableStateManager.isTableState(tableName, ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING)) { LOG.info("Ignored moving region of disabling/disabled table " + tableName); return; } // Move the region only if it's assigned String encodedName = hri.getEncodedName(); ReentrantLock lock = locker.acquireLock(encodedName); try { if (!regionStates.isRegionOnline(hri)) { RegionState state = regionStates.getRegionState(encodedName); LOG.info("Ignored moving region not assigned: " + hri + ", " + (state == null ? "not in region states" : state)); return; } synchronized (this.regionPlans) { this.regionPlans.put(plan.getRegionName(), plan); } unassign(hri, false, plan.getDestination()); } finally { lock.unlock(); } }
if (e.getValue() == null || e.getValue().getDestination() == null) continue; if (!e.getValue().getDestination().equals(sn)) continue; RegionState rs = null; synchronized (this.regionsInTransition) {
@Override public TableName getTableName() { return plan.getRegionInfo().getTable(); }
@Test public void testEquals() { RegionInfo hri = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName())).build(); // Identity equality RegionPlan plan = new RegionPlan(hri, SRC, DEST); assertEquals(plan.hashCode(), new RegionPlan(hri, SRC, DEST).hashCode()); assertEquals(plan, new RegionPlan(hri, SRC, DEST)); // HRI is used for equality RegionInfo other = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName() + "other")).build(); assertNotEquals(plan.hashCode(), new RegionPlan(other, SRC, DEST).hashCode()); assertNotEquals(plan, new RegionPlan(other, SRC, DEST)); } }
/** * @param plan Plan to execute. */ void balance(final RegionPlan plan) { synchronized (this.regionPlans) { this.regionPlans.put(plan.getRegionName(), plan); } unassign(plan.getRegionInfo()); }
RegionPlan regionPlan = new RegionPlan(region_b, region_b_location, region_a_location); LOG.info("Moving regions to same server for merge: " + regionPlan.toString()); masterServices.getAssignmentManager().balance(regionPlan); while (!masterServices.isStopped()) {
/** * Add a region from the head or tail to the List of regions to return. */ private void addRegionPlan(final MinMaxPriorityQueue<RegionPlan> regionsToMove, final boolean fetchFromTail, final ServerName sn, List<RegionPlan> regionsToReturn) { RegionPlan rp = null; if (!fetchFromTail) rp = regionsToMove.remove(); else rp = regionsToMove.removeLast(); rp.setDestination(sn); regionsToReturn.add(rp); }
/** * Compare the region info. * @param other region plan you are comparing against */ @Override public int compareTo(RegionPlan other) { return compareTo(this, other); }
/** * Compare the region info. * @param o region plan you are comparing against */ @Override public int compareTo(RegionPlan o) { return getRegionName().compareTo(o.getRegionName()); }