Search in sources :

Example 1 with RegionMovedException

use of org.apache.hadoop.hbase.exceptions.RegionMovedException in project hbase by apache.

the class AsyncRegionLocator method updateCachedLoation.

static void updateCachedLoation(HRegionLocation loc, Throwable exception, Function<HRegionLocation, HRegionLocation> cachedLocationSupplier, Consumer<HRegionLocation> addToCache, Consumer<HRegionLocation> removeFromCache) {
    HRegionLocation oldLoc = cachedLocationSupplier.apply(loc);
    if (LOG.isDebugEnabled()) {
        LOG.debug("Try updating " + loc + ", the old value is " + oldLoc, exception);
    }
    if (!canUpdate(loc, oldLoc)) {
        return;
    }
    Throwable cause = findException(exception);
    if (LOG.isDebugEnabled()) {
        LOG.debug("The actual exception when updating " + loc, cause);
    }
    if (cause == null || !isMetaClearingException(cause)) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Will not update " + loc + " because the exception is null or not the one we care about");
        }
        return;
    }
    if (cause instanceof RegionMovedException) {
        RegionMovedException rme = (RegionMovedException) cause;
        HRegionLocation newLoc = new HRegionLocation(loc.getRegionInfo(), rme.getServerName(), rme.getLocationSeqNum());
        if (LOG.isDebugEnabled()) {
            LOG.debug("Try updating " + loc + " with the new location " + newLoc + " constructed by " + rme);
        }
        addToCache.accept(newLoc);
    } else {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Try removing " + loc + " from cache");
        }
        removeFromCache.accept(loc);
    }
}
Also used : HRegionLocation(org.apache.hadoop.hbase.HRegionLocation) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException)

Example 2 with RegionMovedException

use of org.apache.hadoop.hbase.exceptions.RegionMovedException in project hbase by apache.

the class HRegionServer method getRegionByEncodedName.

private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName) throws NotServingRegionException {
    HRegion region = this.onlineRegions.get(encodedRegionName);
    if (region == null) {
        MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);
        if (moveInfo != null) {
            throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());
        }
        Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));
        String regionNameStr = regionName == null ? encodedRegionName : Bytes.toStringBinary(regionName);
        if (isOpening != null && isOpening) {
            throw new RegionOpeningException("Region " + regionNameStr + " is opening on " + this.serverName);
        }
        throw new NotServingRegionException("" + regionNameStr + " is not online on " + this.serverName);
    }
    return region;
}
Also used : RegionOpeningException(org.apache.hadoop.hbase.exceptions.RegionOpeningException) NotServingRegionException(org.apache.hadoop.hbase.NotServingRegionException) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 3 with RegionMovedException

use of org.apache.hadoop.hbase.exceptions.RegionMovedException in project hbase by apache.

the class AsyncRegionLocatorHelper method updateCachedLocationOnError.

static void updateCachedLocationOnError(HRegionLocation loc, Throwable exception, Function<HRegionLocation, HRegionLocation> cachedLocationSupplier, Consumer<HRegionLocation> addToCache, Consumer<HRegionLocation> removeFromCache, MetricsConnection metrics) {
    HRegionLocation oldLoc = cachedLocationSupplier.apply(loc);
    if (LOG.isDebugEnabled()) {
        LOG.debug("Try updating {} , the old value is {}, error={}", loc, oldLoc, exception != null ? exception.toString() : "none");
    }
    if (!canUpdateOnError(loc, oldLoc)) {
        return;
    }
    Throwable cause = findException(exception);
    if (LOG.isDebugEnabled()) {
        LOG.debug("The actual exception when updating {} is {}", loc, cause != null ? cause.toString() : "none");
    }
    if (cause == null || !isMetaClearingException(cause)) {
        LOG.debug("Will not update {} because the exception is null or not the one we care about", loc);
        return;
    }
    if (cause instanceof RegionMovedException) {
        RegionMovedException rme = (RegionMovedException) cause;
        HRegionLocation newLoc = new HRegionLocation(loc.getRegion(), rme.getServerName(), rme.getLocationSeqNum());
        LOG.debug("Try updating {} with the new location {} constructed by {}", loc, newLoc, rme.toString());
        addToCache.accept(newLoc);
    } else {
        LOG.debug("Try removing {} from cache", loc);
        if (metrics != null) {
            metrics.incrCacheDroppingExceptions(exception);
        }
        removeFromCache.accept(loc);
    }
}
Also used : HRegionLocation(org.apache.hadoop.hbase.HRegionLocation) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException)

Example 4 with RegionMovedException

use of org.apache.hadoop.hbase.exceptions.RegionMovedException in project hbase by apache.

the class ConnectionImplementation method updateCachedLocations.

/**
   * Update the location with the new value (if the exception is a RegionMovedException)
   * or delete it from the cache. Does nothing if we can be sure from the exception that
   * the location is still accurate, or if the cache has already been updated.
   * @param exception an object (to simplify user code) on which we will try to find a nested
   *   or wrapped or both RegionMovedException
   * @param source server that is the source of the location update.
   */
@Override
public void updateCachedLocations(final TableName tableName, byte[] regionName, byte[] rowkey, final Object exception, final ServerName source) {
    if (rowkey == null || tableName == null) {
        LOG.warn("Coding error, see method javadoc. row=" + (rowkey == null ? "null" : rowkey) + ", tableName=" + (tableName == null ? "null" : tableName));
        return;
    }
    if (source == null) {
        // This should not happen, but let's secure ourselves.
        return;
    }
    if (regionName == null) {
        // we do not know which region, so just remove the cache entry for the row and server
        if (metrics != null) {
            metrics.incrCacheDroppingExceptions(exception);
        }
        metaCache.clearCache(tableName, rowkey, source);
        return;
    }
    // Is it something we have already updated?
    final RegionLocations oldLocations = getCachedLocation(tableName, rowkey);
    HRegionLocation oldLocation = null;
    if (oldLocations != null) {
        oldLocation = oldLocations.getRegionLocationByRegionName(regionName);
    }
    if (oldLocation == null || !source.equals(oldLocation.getServerName())) {
        // the cache has already been refreshed with a different location.  => nothing to do
        return;
    }
    HRegionInfo regionInfo = oldLocation.getRegionInfo();
    Throwable cause = ClientExceptionsUtil.findException(exception);
    if (cause != null) {
        if (!ClientExceptionsUtil.isMetaClearingException(cause)) {
            // We know that the region is still on this region server
            return;
        }
        if (cause instanceof RegionMovedException) {
            RegionMovedException rme = (RegionMovedException) cause;
            if (LOG.isTraceEnabled()) {
                LOG.trace("Region " + regionInfo.getRegionNameAsString() + " moved to " + rme.getHostname() + ":" + rme.getPort() + " according to " + source.getHostAndPort());
            }
            // We know that the region is not anymore on this region server, but we know
            //  the new location.
            updateCachedLocation(regionInfo, source, rme.getServerName(), rme.getLocationSeqNum());
            return;
        }
    }
    if (metrics != null) {
        metrics.incrCacheDroppingExceptions(exception);
    }
    // If we're here, it means that can cannot be sure about the location, so we remove it from
    // the cache. Do not send the source because source can be a new server in the same host:port
    metaCache.clearCache(regionInfo);
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) RegionLocations(org.apache.hadoop.hbase.RegionLocations) HRegionLocation(org.apache.hadoop.hbase.HRegionLocation) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException)

Example 5 with RegionMovedException

use of org.apache.hadoop.hbase.exceptions.RegionMovedException in project hbase by apache.

the class TestHCM method testRegionCaching.

/**
   * Test that when we delete a location using the first row of a region
   * that we really delete it.
   * @throws Exception
   */
@Test
public void testRegionCaching() throws Exception {
    TEST_UTIL.createMultiRegionTable(TABLE_NAME, FAM_NAM).close();
    Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
    // test with no retry, or client cache will get updated after the first failure
    conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 0);
    Connection connection = ConnectionFactory.createConnection(conf);
    final Table table = connection.getTable(TABLE_NAME);
    TEST_UTIL.waitUntilAllRegionsAssigned(table.getName());
    Put put = new Put(ROW);
    put.addColumn(FAM_NAM, ROW, ROW);
    table.put(put);
    ConnectionImplementation conn = (ConnectionImplementation) connection;
    assertNotNull(conn.getCachedLocation(TABLE_NAME, ROW));
    final int nextPort = conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort() + 1;
    HRegionLocation loc = conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation();
    conn.updateCachedLocation(loc.getRegionInfo(), loc.getServerName(), ServerName.valueOf("127.0.0.1", nextPort, HConstants.LATEST_TIMESTAMP), HConstants.LATEST_TIMESTAMP);
    Assert.assertEquals(conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort(), nextPort);
    conn.clearRegionCache(TABLE_NAME, ROW.clone());
    RegionLocations rl = conn.getCachedLocation(TABLE_NAME, ROW);
    assertNull("What is this location?? " + rl, rl);
    // We're now going to move the region and check that it works for the client
    // First a new put to add the location in the cache
    conn.clearRegionCache(TABLE_NAME);
    Assert.assertEquals(0, conn.getNumberOfCachedRegionLocations(TABLE_NAME));
    Put put2 = new Put(ROW);
    put2.addColumn(FAM_NAM, ROW, ROW);
    table.put(put2);
    assertNotNull(conn.getCachedLocation(TABLE_NAME, ROW));
    assertNotNull(conn.getCachedLocation(TableName.valueOf(TABLE_NAME.getName()), ROW.clone()));
    TEST_UTIL.getAdmin().setBalancerRunning(false, false);
    HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
    // We can wait for all regions to be online, that makes log reading easier when debugging
    TEST_UTIL.waitUntilNoRegionsInTransition();
    // Now moving the region to the second server
    HRegionLocation toMove = conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation();
    byte[] regionName = toMove.getRegionInfo().getRegionName();
    byte[] encodedRegionNameBytes = toMove.getRegionInfo().getEncodedNameAsBytes();
    // Choose the other server.
    int curServerId = TEST_UTIL.getHBaseCluster().getServerWith(regionName);
    int destServerId = (curServerId == 0 ? 1 : 0);
    HRegionServer curServer = TEST_UTIL.getHBaseCluster().getRegionServer(curServerId);
    HRegionServer destServer = TEST_UTIL.getHBaseCluster().getRegionServer(destServerId);
    ServerName destServerName = destServer.getServerName();
    // Check that we are in the expected state
    Assert.assertTrue(curServer != destServer);
    Assert.assertFalse(curServer.getServerName().equals(destServer.getServerName()));
    Assert.assertFalse(toMove.getPort() == destServerName.getPort());
    Assert.assertNotNull(curServer.getOnlineRegion(regionName));
    Assert.assertNull(destServer.getOnlineRegion(regionName));
    Assert.assertFalse(TEST_UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().getRegionStates().isRegionsInTransition());
    // Moving. It's possible that we don't have all the regions online at this point, so
    //  the test must depends only on the region we're looking at.
    LOG.info("Move starting region=" + toMove.getRegionInfo().getRegionNameAsString());
    TEST_UTIL.getAdmin().move(toMove.getRegionInfo().getEncodedNameAsBytes(), destServerName.getServerName().getBytes());
    while (destServer.getOnlineRegion(regionName) == null || destServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes) || curServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes) || master.getAssignmentManager().getRegionStates().isRegionsInTransition()) {
        // wait for the move to be finished
        Thread.sleep(1);
    }
    LOG.info("Move finished for region=" + toMove.getRegionInfo().getRegionNameAsString());
    // Check our new state.
    Assert.assertNull(curServer.getOnlineRegion(regionName));
    Assert.assertNotNull(destServer.getOnlineRegion(regionName));
    Assert.assertFalse(destServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));
    Assert.assertFalse(curServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));
    // Cache was NOT updated and points to the wrong server
    Assert.assertFalse(conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort() == destServerName.getPort());
    // This part relies on a number of tries equals to 1.
    // We do a put and expect the cache to be updated, even if we don't retry
    LOG.info("Put starting");
    Put put3 = new Put(ROW);
    put3.addColumn(FAM_NAM, ROW, ROW);
    try {
        table.put(put3);
        Assert.fail("Unreachable point");
    } catch (RetriesExhaustedWithDetailsException e) {
        LOG.info("Put done, exception caught: " + e.getClass());
        Assert.assertEquals(1, e.getNumExceptions());
        Assert.assertEquals(1, e.getCauses().size());
        Assert.assertArrayEquals(e.getRow(0).getRow(), ROW);
        // Check that we unserialized the exception as expected
        Throwable cause = ClientExceptionsUtil.findException(e.getCause(0));
        Assert.assertNotNull(cause);
        Assert.assertTrue(cause instanceof RegionMovedException);
    }
    Assert.assertNotNull("Cached connection is null", conn.getCachedLocation(TABLE_NAME, ROW));
    Assert.assertEquals("Previous server was " + curServer.getServerName().getHostAndPort(), destServerName.getPort(), conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort());
    Assert.assertFalse(destServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));
    Assert.assertFalse(curServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));
    // We move it back to do another test with a scan
    LOG.info("Move starting region=" + toMove.getRegionInfo().getRegionNameAsString());
    TEST_UTIL.getAdmin().move(toMove.getRegionInfo().getEncodedNameAsBytes(), curServer.getServerName().getServerName().getBytes());
    while (curServer.getOnlineRegion(regionName) == null || destServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes) || curServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes) || master.getAssignmentManager().getRegionStates().isRegionsInTransition()) {
        // wait for the move to be finished
        Thread.sleep(1);
    }
    // Check our new state.
    Assert.assertNotNull(curServer.getOnlineRegion(regionName));
    Assert.assertNull(destServer.getOnlineRegion(regionName));
    LOG.info("Move finished for region=" + toMove.getRegionInfo().getRegionNameAsString());
    // Cache was NOT updated and points to the wrong server
    Assert.assertFalse(conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort() == curServer.getServerName().getPort());
    Scan sc = new Scan();
    sc.setStopRow(ROW);
    sc.setStartRow(ROW);
    // The scanner takes the max retries from the connection configuration, not the table as
    // the put.
    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
    try {
        ResultScanner rs = table.getScanner(sc);
        while (rs.next() != null) {
        }
        Assert.fail("Unreachable point");
    } catch (RetriesExhaustedException e) {
        LOG.info("Scan done, expected exception caught: " + e.getClass());
    }
    // Cache is updated with the right value.
    Assert.assertNotNull(conn.getCachedLocation(TABLE_NAME, ROW));
    Assert.assertEquals("Previous server was " + destServer.getServerName().getHostAndPort(), curServer.getServerName().getPort(), conn.getCachedLocation(TABLE_NAME, ROW).getRegionLocation().getPort());
    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, RPC_RETRY);
    table.close();
    connection.close();
}
Also used : RegionLocations(org.apache.hadoop.hbase.RegionLocations) Configuration(org.apache.hadoop.conf.Configuration) HRegionServer(org.apache.hadoop.hbase.regionserver.HRegionServer) HRegionLocation(org.apache.hadoop.hbase.HRegionLocation) ServerName(org.apache.hadoop.hbase.ServerName) HMaster(org.apache.hadoop.hbase.master.HMaster) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException) Test(org.junit.Test)

Aggregations

RegionMovedException (org.apache.hadoop.hbase.exceptions.RegionMovedException)7 HRegionLocation (org.apache.hadoop.hbase.HRegionLocation)4 NotServingRegionException (org.apache.hadoop.hbase.NotServingRegionException)2 RegionLocations (org.apache.hadoop.hbase.RegionLocations)2 Test (org.junit.Test)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Configuration (org.apache.hadoop.conf.Configuration)1 CallDroppedException (org.apache.hadoop.hbase.CallDroppedException)1 DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)1 HRegionInfo (org.apache.hadoop.hbase.HRegionInfo)1 RegionTooBusyException (org.apache.hadoop.hbase.RegionTooBusyException)1 ServerName (org.apache.hadoop.hbase.ServerName)1 OutOfOrderScannerNextException (org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException)1 RegionOpeningException (org.apache.hadoop.hbase.exceptions.RegionOpeningException)1 HMaster (org.apache.hadoop.hbase.master.HMaster)1 HRegionServer (org.apache.hadoop.hbase.regionserver.HRegionServer)1 ExceptionResponse (org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.ExceptionResponse)1