Search in sources :

Example 21 with HRegionInfo

use of org.apache.hadoop.hbase.HRegionInfo in project hbase by apache.

the class AssignmentManager method waitForAssignment.

/**
   * Waits until the specified region has completed assignment, or the deadline is reached.
   * @param regionSet set of region to wait on. the set is modified and the assigned regions removed
   * @param waitTillAllAssigned true if we should wait all the regions to be assigned
   * @param deadline the timestamp after which the wait is aborted
   * @return true if all the regions are assigned false otherwise.
   * @throws InterruptedException
   */
protected boolean waitForAssignment(final Collection<HRegionInfo> regionSet, final boolean waitTillAllAssigned, final long deadline) throws InterruptedException {
    // We're not synchronizing on regionsInTransition now because we don't use any iterator.
    while (!regionSet.isEmpty() && !server.isStopped() && deadline > System.currentTimeMillis()) {
        int failedOpenCount = 0;
        Iterator<HRegionInfo> regionInfoIterator = regionSet.iterator();
        while (regionInfoIterator.hasNext()) {
            HRegionInfo hri = regionInfoIterator.next();
            if (regionStates.isRegionOnline(hri) || regionStates.isRegionInState(hri, State.SPLITTING, State.SPLIT, State.MERGING, State.MERGED)) {
                regionInfoIterator.remove();
            } else if (regionStates.isRegionInState(hri, State.FAILED_OPEN)) {
                failedOpenCount++;
            }
        }
        if (!waitTillAllAssigned) {
            // No need to wait, let assignment going on asynchronously
            break;
        }
        if (!regionSet.isEmpty()) {
            if (failedOpenCount == regionSet.size()) {
                // all the regions we are waiting had an error on open.
                break;
            }
            regionStates.waitForUpdate(100);
        }
    }
    return regionSet.isEmpty();
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo)

Example 22 with HRegionInfo

use of org.apache.hadoop.hbase.HRegionInfo in project hbase by apache.

the class AssignmentManager method onRegionTransition.

/**
   * Try to update some region states. If the state machine prevents
   * such update, an error message is returned to explain the reason.
   *
   * It's expected that in each transition there should have just one
   * region for opening/closing, 3 regions for splitting/merging.
   * These regions should be on the server that requested the change.
   *
   * Region state machine. Only these transitions
   * are expected to be triggered by a region server.
   *
   * On the state transition:
   *  (1) Open/Close should be initiated by master
   *      (a) Master sets the region to pending_open/pending_close
   *        in memory and hbase:meta after sending the request
   *        to the region server
   *      (b) Region server reports back to the master
   *        after open/close is done (either success/failure)
   *      (c) If region server has problem to report the status
   *        to master, it must be because the master is down or some
   *        temporary network issue. Otherwise, the region server should
   *        abort since it must be a bug. If the master is not accessible,
   *        the region server should keep trying until the server is
   *        stopped or till the status is reported to the (new) master
   *      (d) If region server dies in the middle of opening/closing
   *        a region, SSH picks it up and finishes it
   *      (e) If master dies in the middle, the new master recovers
   *        the state during initialization from hbase:meta. Region server
   *        can report any transition that has not been reported to
   *        the previous active master yet
   *  (2) Split/merge is initiated by region servers
   *      (a) To split a region, a region server sends a request
   *        to master to try to set a region to splitting, together with
   *        two daughters (to be created) to splitting new. If approved
   *        by the master, the splitting can then move ahead
   *      (b) To merge two regions, a region server sends a request to
   *        master to try to set the new merged region (to be created) to
   *        merging_new, together with two regions (to be merged) to merging.
   *        If it is ok with the master, the merge can then move ahead
   *      (c) Once the splitting/merging is done, the region server
   *        reports the status back to the master either success/failure.
   *      (d) Other scenarios should be handled similarly as for
   *        region open/close
   */
public String onRegionTransition(final ServerName serverName, final RegionStateTransition transition) {
    TransitionCode code = transition.getTransitionCode();
    HRegionInfo hri = HRegionInfo.convert(transition.getRegionInfo(0));
    Lock lock = locker.acquireLock(hri.getEncodedName());
    try {
        RegionState current = regionStates.getRegionState(hri);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Got transition " + code + " for " + (current != null ? current.toString() : hri.getShortNameToLog()) + " from " + serverName);
        }
        String errorMsg = null;
        switch(code) {
            case OPENED:
                errorMsg = onRegionOpen(current, hri, serverName, transition);
                break;
            case FAILED_OPEN:
                errorMsg = onRegionFailedOpen(current, hri, serverName);
                break;
            case CLOSED:
                errorMsg = onRegionClosed(current, hri, serverName);
                break;
            case READY_TO_SPLIT:
                try {
                    regionStateListener.onRegionSplit(hri);
                    errorMsg = onRegionReadyToSplit(current, hri, serverName, transition);
                } catch (IOException exp) {
                    if (exp instanceof QuotaExceededException) {
                        server.getRegionNormalizer().planSkipped(hri, PlanType.SPLIT);
                    }
                    errorMsg = StringUtils.stringifyException(exp);
                }
                break;
            case SPLIT_PONR:
                errorMsg = onRegionSplitPONR(current, hri, serverName, transition);
                break;
            case SPLIT:
                errorMsg = onRegionSplit(current, hri, serverName, transition);
                break;
            case SPLIT_REVERTED:
                errorMsg = onRegionSplitReverted(current, hri, serverName, transition);
                if (org.apache.commons.lang.StringUtils.isEmpty(errorMsg)) {
                    try {
                        regionStateListener.onRegionSplitReverted(hri);
                    } catch (IOException exp) {
                        LOG.warn(StringUtils.stringifyException(exp));
                    }
                }
                break;
            case READY_TO_MERGE:
                errorMsg = onRegionReadyToMerge(current, hri, serverName, transition);
                break;
            case MERGE_PONR:
                errorMsg = onRegionMergePONR(current, hri, serverName, transition);
                break;
            case MERGED:
                try {
                    errorMsg = onRegionMerged(current, hri, serverName, transition);
                    regionStateListener.onRegionMerged(hri);
                } catch (IOException exp) {
                    errorMsg = StringUtils.stringifyException(exp);
                }
                break;
            case MERGE_REVERTED:
                errorMsg = onRegionMergeReverted(current, hri, serverName, transition);
                break;
            default:
                errorMsg = "Unexpected transition code " + code;
        }
        if (errorMsg != null) {
            LOG.info("Could not transition region from " + current + " on " + code + " by " + serverName + ": " + errorMsg);
        }
        return errorMsg;
    } finally {
        lock.unlock();
    }
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) QuotaExceededException(org.apache.hadoop.hbase.quotas.QuotaExceededException) TransitionCode(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode) HBaseIOException(org.apache.hadoop.hbase.HBaseIOException) IOException(java.io.IOException) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock)

Example 23 with HRegionInfo

use of org.apache.hadoop.hbase.HRegionInfo in project hbase by apache.

the class AssignmentManager method onRegionSplitPONR.

private String onRegionSplitPONR(final RegionState current, final HRegionInfo hri, final ServerName serverName, final RegionStateTransition transition) {
    // splitting_new state. To check RPC retry, we use server holding info.
    if (current == null || !current.isSplittingOnServer(serverName)) {
        return hri.getShortNameToLog() + " is not splitting on " + serverName;
    }
    final HRegionInfo a = HRegionInfo.convert(transition.getRegionInfo(1));
    final HRegionInfo b = HRegionInfo.convert(transition.getRegionInfo(2));
    RegionState rs_a = regionStates.getRegionState(a);
    RegionState rs_b = regionStates.getRegionState(b);
    // states, if so, they must be lost together
    if (rs_a == null && rs_b == null) {
        rs_a = regionStates.createRegionState(a, State.SPLITTING_NEW, serverName, null);
        rs_b = regionStates.createRegionState(b, State.SPLITTING_NEW, serverName, null);
    }
    if (rs_a == null || !rs_a.isSplittingNewOnServer(serverName) || rs_b == null || !rs_b.isSplittingNewOnServer(serverName)) {
        return "Some daughter is not known to be splitting on " + serverName + ", a=" + rs_a + ", b=" + rs_b;
    }
    // Just return in case of retrying
    if (!regionStates.isRegionOnServer(hri, serverName)) {
        return null;
    }
    try {
        regionStates.splitRegion(hri, a, b, serverName);
        processFavoredNodesForDaughters(hri, a, b);
    } catch (IOException ioe) {
        LOG.info("Failed to record split region " + hri.getShortNameToLog());
        return "Failed to record the splitting in meta";
    }
    return null;
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) HBaseIOException(org.apache.hadoop.hbase.HBaseIOException) IOException(java.io.IOException)

Example 24 with HRegionInfo

use of org.apache.hadoop.hbase.HRegionInfo in project hbase by apache.

the class AssignmentManager method cleanOutCrashedServerReferences.

/**
   * Clean out crashed server removing any assignments.
   * @param sn Server that went down.
   * @return list of regions in transition on this server
   */
public List<HRegionInfo> cleanOutCrashedServerReferences(final ServerName sn) {
    // Clean out any existing assignment plans for this server
    synchronized (this.regionPlans) {
        for (Iterator<Map.Entry<String, RegionPlan>> i = this.regionPlans.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<String, RegionPlan> e = i.next();
            ServerName otherSn = e.getValue().getDestination();
            // The name will be null if the region is planned for a random assign.
            if (otherSn != null && otherSn.equals(sn)) {
                // Use iterator's remove else we'll get CME
                i.remove();
            }
        }
    }
    List<HRegionInfo> rits = regionStates.serverOffline(sn);
    for (Iterator<HRegionInfo> it = rits.iterator(); it.hasNext(); ) {
        HRegionInfo hri = it.next();
        String encodedName = hri.getEncodedName();
        // We need a lock on the region as we could update it
        Lock lock = locker.acquireLock(encodedName);
        try {
            RegionState regionState = regionStates.getRegionTransitionState(encodedName);
            if (regionState == null || (regionState.getServerName() != null && !regionState.isOnServer(sn)) || !RegionStates.isOneOfStates(regionState, State.PENDING_OPEN, State.OPENING, State.FAILED_OPEN, State.FAILED_CLOSE, State.OFFLINE)) {
                LOG.info("Skip " + regionState + " since it is not opening/failed_close" + " on the dead server any more: " + sn);
                it.remove();
            } else {
                if (tableStateManager.isTableState(hri.getTable(), TableState.State.DISABLED, TableState.State.DISABLING)) {
                    regionStates.regionOffline(hri);
                    it.remove();
                    continue;
                }
                // Mark the region offline and assign it again by SSH
                regionStates.updateRegionState(hri, State.OFFLINE);
            }
        } finally {
            lock.unlock();
        }
    }
    return rits;
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) ServerName(org.apache.hadoop.hbase.ServerName) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NavigableMap(java.util.NavigableMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock)

Example 25 with HRegionInfo

use of org.apache.hadoop.hbase.HRegionInfo in project hbase by apache.

the class AssignmentManager method onRegionReadyToMerge.

private String onRegionReadyToMerge(final RegionState current, final HRegionInfo hri, final ServerName serverName, final RegionStateTransition transition) {
    // If the region is in merge_new state, it could be an RPC retry.
    if (current != null && !current.isMergingNewOnServer(serverName)) {
        return "Merging daughter region already exists, p=" + current;
    }
    if (!((HMaster) server).getSplitOrMergeTracker().isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {
        return "merge switch is off!";
    }
    // Just return in case of retrying
    if (current != null) {
        return null;
    }
    final HRegionInfo a = HRegionInfo.convert(transition.getRegionInfo(1));
    final HRegionInfo b = HRegionInfo.convert(transition.getRegionInfo(2));
    Set<String> encodedNames = new HashSet<>(2);
    encodedNames.add(a.getEncodedName());
    encodedNames.add(b.getEncodedName());
    Map<String, Lock> locks = locker.acquireLocks(encodedNames);
    try {
        RegionState rs_a = regionStates.getRegionState(a);
        RegionState rs_b = regionStates.getRegionState(b);
        if (rs_a == null || !rs_a.isOpenedOnServer(serverName) || rs_b == null || !rs_b.isOpenedOnServer(serverName)) {
            return "Some daughter is not in a state to merge on " + serverName + ", a=" + rs_a + ", b=" + rs_b;
        }
        regionStates.updateRegionState(a, State.MERGING);
        regionStates.updateRegionState(b, State.MERGING);
        regionStates.createRegionState(hri, State.MERGING_NEW, serverName, null);
        return null;
    } finally {
        for (Lock lock : locks.values()) {
            lock.unlock();
        }
    }
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) HashSet(java.util.HashSet) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock)

Aggregations

HRegionInfo (org.apache.hadoop.hbase.HRegionInfo)408 ServerName (org.apache.hadoop.hbase.ServerName)153 Test (org.junit.Test)141 TableName (org.apache.hadoop.hbase.TableName)118 ArrayList (java.util.ArrayList)86 IOException (java.io.IOException)83 HTableDescriptor (org.apache.hadoop.hbase.HTableDescriptor)75 Path (org.apache.hadoop.fs.Path)63 List (java.util.List)59 HashMap (java.util.HashMap)57 HColumnDescriptor (org.apache.hadoop.hbase.HColumnDescriptor)49 Table (org.apache.hadoop.hbase.client.Table)47 Map (java.util.Map)43 HRegionServer (org.apache.hadoop.hbase.regionserver.HRegionServer)41 FileSystem (org.apache.hadoop.fs.FileSystem)40 Configuration (org.apache.hadoop.conf.Configuration)38 HRegionLocation (org.apache.hadoop.hbase.HRegionLocation)35 TreeMap (java.util.TreeMap)26 HashSet (java.util.HashSet)23 HBaseIOException (org.apache.hadoop.hbase.HBaseIOException)22