use of org.apache.hadoop.hbase.client.RegionInfo in project hbase by apache.
the class RegionStateNode method checkOnline.
public void checkOnline() throws DoNotRetryRegionException {
RegionInfo ri = getRegionInfo();
State s = state;
if (s != State.OPEN) {
throw new DoNotRetryRegionException(ri.getEncodedName() + " is not OPEN; state=" + s);
}
if (ri.isSplitParent()) {
throw new DoNotRetryRegionException(ri.getEncodedName() + " is not online (splitParent=true)");
}
if (ri.isSplit()) {
throw new DoNotRetryRegionException(ri.getEncodedName() + " has split=true");
}
if (ri.isOffline()) {
// RegionOfflineException is not instance of DNRIOE so wrap it.
throw new DoNotRetryRegionException(new RegionOfflineException(ri.getEncodedName()));
}
}
use of org.apache.hadoop.hbase.client.RegionInfo in project hbase by apache.
the class RegionStates method getAssignmentsForBalancer.
/**
* This is an EXPENSIVE clone. Cloning though is the safest thing to do.
* Can't let out original since it can change and at least the load balancer
* wants to iterate this exported list. We need to synchronize on regions
* since all access to this.servers is under a lock on this.regions.
*
* @return A clone of current open or opening assignments.
*/
public Map<TableName, Map<ServerName, List<RegionInfo>>> getAssignmentsForBalancer(TableStateManager tableStateManager, List<ServerName> onlineServers) {
final Map<TableName, Map<ServerName, List<RegionInfo>>> result = new HashMap<>();
for (RegionStateNode node : regionsMap.values()) {
// state because even if still currently open we expect them to be offlined very soon.
if (isTableDisabled(tableStateManager, node.getTable())) {
if (LOG.isTraceEnabled()) {
LOG.trace("Ignoring {} because table is disabled", node);
}
continue;
}
// they are closing, splitting, merging, or otherwise already in transition.
if (!node.isInState(State.OPEN, State.OPENING)) {
if (LOG.isTraceEnabled()) {
LOG.trace("Ignoring {} because region is not OPEN or OPENING", node);
}
continue;
}
Map<ServerName, List<RegionInfo>> tableResult = result.computeIfAbsent(node.getTable(), t -> new HashMap<>());
final ServerName serverName = node.getRegionLocation();
// A region in ONLINE or OPENING state should have a location.
if (serverName == null) {
LOG.warn("Skipping, no server for {}", node);
continue;
}
List<RegionInfo> serverResult = tableResult.computeIfAbsent(serverName, s -> new ArrayList<>());
serverResult.add(node.getRegionInfo());
}
// Add online servers with no assignment for the table.
for (Map<ServerName, List<RegionInfo>> table : result.values()) {
for (ServerName serverName : onlineServers) {
table.computeIfAbsent(serverName, key -> new ArrayList<>());
}
}
return result;
}
use of org.apache.hadoop.hbase.client.RegionInfo in project hbase by apache.
the class RegionStates method createSnapshot.
private void createSnapshot(RegionStateNode node, Map<ServerName, List<RegionInfo>> result) {
final ServerName serverName = node.getRegionLocation();
if (serverName == null) {
return;
}
List<RegionInfo> serverRegions = result.get(serverName);
if (serverRegions == null) {
serverRegions = new ArrayList<RegionInfo>();
result.put(serverName, serverRegions);
}
serverRegions.add(node.getRegionInfo());
}
use of org.apache.hadoop.hbase.client.RegionInfo in project hbase by apache.
the class TransitRegionStateProcedure method executeFromState.
@Override
protected Flow executeFromState(MasterProcedureEnv env, RegionStateTransitionState state) throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {
RegionStateNode regionNode = getRegionStateNode(env);
try {
switch(state) {
case REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE:
// master, do not try to assign the replica region, log error and return.
if (!RegionReplicaUtil.isDefaultReplica(regionNode.getRegionInfo())) {
RegionInfo defaultRI = RegionReplicaUtil.getRegionInfoForDefaultReplica(regionNode.getRegionInfo());
if (env.getMasterServices().getAssignmentManager().getRegionStates().getRegionStateNode(defaultRI) == null) {
LOG.error("Cannot assign replica region {} because its primary region {} does not exist.", regionNode.getRegionInfo(), defaultRI);
regionNode.unsetProcedure(this);
return Flow.NO_MORE_STATE;
}
}
queueAssign(env, regionNode);
return Flow.HAS_MORE_STATE;
case REGION_STATE_TRANSITION_OPEN:
openRegion(env, regionNode);
return Flow.HAS_MORE_STATE;
case REGION_STATE_TRANSITION_CONFIRM_OPENED:
return confirmOpened(env, regionNode);
case REGION_STATE_TRANSITION_CLOSE:
closeRegion(env, regionNode);
return Flow.HAS_MORE_STATE;
case REGION_STATE_TRANSITION_CONFIRM_CLOSED:
return confirmClosed(env, regionNode);
default:
throw new UnsupportedOperationException("unhandled state=" + state);
}
} catch (IOException e) {
if (retryCounter == null) {
retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration());
}
long backoff = retryCounter.getBackoffTimeAndIncrementAttempts();
LOG.warn("Failed transition, suspend {}secs {}; {}; waiting on rectified condition fixed " + "by other Procedure or operator intervention", backoff / 1000, this, regionNode.toShortString(), e);
setTimeout(Math.toIntExact(backoff));
setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT);
skipPersistence();
throw new ProcedureSuspendedException();
}
}
use of org.apache.hadoop.hbase.client.RegionInfo in project hbase by apache.
the class SimpleRegionNormalizer method computeMergeNormalizationPlans.
/**
* Computes the merge plans that should be executed for this table to converge average region
* towards target average or target region count.
*/
private List<NormalizationPlan> computeMergeNormalizationPlans(final NormalizeContext ctx) {
final NormalizerConfiguration configuration = normalizerConfiguration;
if (ctx.getTableRegions().size() < configuration.getMergeMinRegionCount(ctx)) {
LOG.debug("Table {} has {} regions, required min number of regions for normalizer to run" + " is {}, not computing merge plans.", ctx.getTableName(), ctx.getTableRegions().size(), configuration.getMergeMinRegionCount());
return Collections.emptyList();
}
final long avgRegionSizeMb = (long) ctx.getAverageRegionSizeMb();
if (avgRegionSizeMb < configuration.getMergeMinRegionSizeMb(ctx)) {
return Collections.emptyList();
}
LOG.debug("Computing normalization plan for table {}. average region size: {} MB, number of" + " regions: {}.", ctx.getTableName(), avgRegionSizeMb, ctx.getTableRegions().size());
// this nested loop walks the table's region chain once, looking for contiguous sequences of
// regions that meet the criteria for merge. The outer loop tracks the starting point of the
// next sequence, the inner loop looks for the end of that sequence. A single sequence becomes
// an instance of MergeNormalizationPlan.
final List<NormalizationPlan> plans = new LinkedList<>();
final List<NormalizationTarget> rangeMembers = new LinkedList<>();
long sumRangeMembersSizeMb;
int current = 0;
for (int rangeStart = 0; rangeStart < ctx.getTableRegions().size() - 1 && current < ctx.getTableRegions().size(); ) {
// walk the region chain looking for contiguous sequences of regions that can be merged.
rangeMembers.clear();
sumRangeMembersSizeMb = 0;
for (current = rangeStart; current < ctx.getTableRegions().size(); current++) {
final RegionInfo regionInfo = ctx.getTableRegions().get(current);
final long regionSizeMb = getRegionSizeMB(regionInfo);
if (skipForMerge(configuration, ctx, regionInfo)) {
// this region cannot participate in a range. resume the outer loop.
rangeStart = Math.max(current, rangeStart + 1);
break;
}
if (// when there are no range members, seed the range with whatever
rangeMembers.isEmpty() || // 0-size.
(// when there is only one
rangeMembers.size() == 1 && sumRangeMembersSizeMb == 0) || // whatever we have.
regionSizeMb == // always add an empty region to the current range.
0 || (regionSizeMb + sumRangeMembersSizeMb <= avgRegionSizeMb)) {
// add the current region
// to the range when
// there's capacity
// remaining.
rangeMembers.add(new NormalizationTarget(regionInfo, regionSizeMb));
sumRangeMembersSizeMb += regionSizeMb;
continue;
}
// we have accumulated enough regions to fill a range. resume the outer loop.
rangeStart = Math.max(current, rangeStart + 1);
break;
}
if (rangeMembers.size() > 1) {
plans.add(new MergeNormalizationPlan.Builder().setTargets(rangeMembers).build());
}
}
return plans;
}
Aggregations