Search in sources :

Example 1 with OutOfOrderScannerNextException

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

the class RSRpcServices method scan.

/**
 * Scan data in a table.
 *
 * @param controller the RPC controller
 * @param request the scan request
 * @throws ServiceException
 */
@Override
public ScanResponse scan(final RpcController controller, final ScanRequest request) throws ServiceException {
    if (controller != null && !(controller instanceof HBaseRpcController)) {
        throw new UnsupportedOperationException("We only do " + "HBaseRpcControllers! FIX IF A PROBLEM: " + controller);
    }
    if (!request.hasScannerId() && !request.hasScan()) {
        throw new ServiceException(new DoNotRetryIOException("Missing required input: scannerId or scan"));
    }
    try {
        checkOpen();
    } catch (IOException e) {
        if (request.hasScannerId()) {
            String scannerName = toScannerName(request.getScannerId());
            if (LOG.isDebugEnabled()) {
                LOG.debug("Server shutting down and client tried to access missing scanner " + scannerName);
            }
            final LeaseManager leaseManager = server.getLeaseManager();
            if (leaseManager != null) {
                try {
                    leaseManager.cancelLease(scannerName);
                } catch (LeaseException le) {
                    // No problem, ignore
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Un-able to cancel lease of scanner. It could already be closed.");
                    }
                }
            }
        }
        throw new ServiceException(e);
    }
    requestCount.increment();
    rpcScanRequestCount.increment();
    RegionScannerHolder rsh;
    ScanResponse.Builder builder = ScanResponse.newBuilder();
    String scannerName;
    try {
        if (request.hasScannerId()) {
            // The downstream projects such as AsyncHBase in OpenTSDB need this value. See HBASE-18000
            // for more details.
            long scannerId = request.getScannerId();
            builder.setScannerId(scannerId);
            scannerName = toScannerName(scannerId);
            rsh = getRegionScanner(request);
        } else {
            Pair<String, RegionScannerHolder> scannerNameAndRSH = newRegionScanner(request, builder);
            scannerName = scannerNameAndRSH.getFirst();
            rsh = scannerNameAndRSH.getSecond();
        }
    } catch (IOException e) {
        if (e == SCANNER_ALREADY_CLOSED) {
            // the old client will still send a close request to us. Just ignore it and return.
            return builder.build();
        }
        throw new ServiceException(e);
    }
    if (rsh.fullRegionScan) {
        rpcFullScanRequestCount.increment();
    }
    HRegion region = rsh.r;
    LeaseManager.Lease lease;
    try {
        // Remove lease while its being processed in server; protects against case
        // where processing of request takes > lease expiration time. or null if none found.
        lease = server.getLeaseManager().removeLease(scannerName);
    } catch (LeaseException e) {
        throw new ServiceException(e);
    }
    if (request.hasRenew() && request.getRenew()) {
        // add back and return
        addScannerLeaseBack(lease);
        try {
            checkScanNextCallSeq(request, rsh);
        } catch (OutOfOrderScannerNextException e) {
            throw new ServiceException(e);
        }
        return builder.build();
    }
    OperationQuota quota;
    try {
        quota = getRpcQuotaManager().checkQuota(region, OperationQuota.OperationType.SCAN);
    } catch (IOException e) {
        addScannerLeaseBack(lease);
        throw new ServiceException(e);
    }
    try {
        checkScanNextCallSeq(request, rsh);
    } catch (OutOfOrderScannerNextException e) {
        addScannerLeaseBack(lease);
        throw new ServiceException(e);
    }
    // Now we have increased the next call sequence. If we give client an error, the retry will
    // never success. So we'd better close the scanner and return a DoNotRetryIOException to client
    // and then client will try to open a new scanner.
    boolean closeScanner = request.hasCloseScanner() ? request.getCloseScanner() : false;
    // this is scan.getCaching
    int rows;
    if (request.hasNumberOfRows()) {
        rows = request.getNumberOfRows();
    } else {
        rows = closeScanner ? 0 : 1;
    }
    RpcCallContext context = RpcServer.getCurrentCall().orElse(null);
    // now let's do the real scan.
    long maxQuotaResultSize = Math.min(maxScannerResultSize, quota.getReadAvailable());
    RegionScanner scanner = rsh.s;
    // this is the limit of rows for this scan, if we the number of rows reach this value, we will
    // close the scanner.
    int limitOfRows;
    if (request.hasLimitOfRows()) {
        limitOfRows = request.getLimitOfRows();
    } else {
        limitOfRows = -1;
    }
    MutableObject<Object> lastBlock = new MutableObject<>();
    boolean scannerClosed = false;
    try {
        List<Result> results = new ArrayList<>(Math.min(rows, 512));
        if (rows > 0) {
            boolean done = false;
            // Call coprocessor. Get region info from scanner.
            if (region.getCoprocessorHost() != null) {
                Boolean bypass = region.getCoprocessorHost().preScannerNext(scanner, results, rows);
                if (!results.isEmpty()) {
                    for (Result r : results) {
                        lastBlock.setValue(addSize(context, r, lastBlock.getValue()));
                    }
                }
                if (bypass != null && bypass.booleanValue()) {
                    done = true;
                }
            }
            if (!done) {
                scan((HBaseRpcController) controller, request, rsh, maxQuotaResultSize, rows, limitOfRows, results, builder, lastBlock, context);
            } else {
                builder.setMoreResultsInRegion(!results.isEmpty());
            }
        } else {
            // This is a open scanner call with numberOfRow = 0, so set more results in region to true.
            builder.setMoreResultsInRegion(true);
        }
        quota.addScanResult(results);
        addResults(builder, results, (HBaseRpcController) controller, RegionReplicaUtil.isDefaultReplica(region.getRegionInfo()), isClientCellBlockSupport(context));
        if (scanner.isFilterDone() && results.isEmpty()) {
            // If the scanner's filter - if any - is done with the scan
            // only set moreResults to false if the results is empty. This is used to keep compatible
            // with the old scan implementation where we just ignore the returned results if moreResults
            // is false. Can remove the isEmpty check after we get rid of the old implementation.
            builder.setMoreResults(false);
        }
        // have already set this flag.
        assert builder.hasMoreResultsInRegion();
        // yet.
        if (!builder.hasMoreResults()) {
            builder.setMoreResults(true);
        }
        if (builder.getMoreResults() && builder.getMoreResultsInRegion() && !results.isEmpty()) {
            // Record the last cell of the last result if it is a partial result
            // We need this to calculate the complete rows we have returned to client as the
            // mayHaveMoreCellsInRow is true does not mean that there will be extra cells for the
            // current row. We may filter out all the remaining cells for the current row and just
            // return the cells of the nextRow when calling RegionScanner.nextRaw. So here we need to
            // check for row change.
            Result lastResult = results.get(results.size() - 1);
            if (lastResult.mayHaveMoreCellsInRow()) {
                rsh.rowOfLastPartialResult = lastResult.getRow();
            } else {
                rsh.rowOfLastPartialResult = null;
            }
        }
        if (!builder.getMoreResults() || !builder.getMoreResultsInRegion() || closeScanner) {
            scannerClosed = true;
            closeScanner(region, scanner, scannerName, context);
        }
        return builder.build();
    } catch (IOException e) {
        try {
            // scanner is closed here
            scannerClosed = true;
            // The scanner state might be left in a dirty state, so we will tell the Client to
            // fail this RPC and close the scanner while opening up another one from the start of
            // row that the client has last seen.
            closeScanner(region, scanner, scannerName, context);
            // the client. See ClientScanner code to see how it deals with these special exceptions.
            if (e instanceof DoNotRetryIOException) {
                throw e;
            }
            // DoNotRetryIOException. This can avoid the retry in ClientScanner.
            if (e instanceof FileNotFoundException) {
                throw new DoNotRetryIOException(e);
            }
            // a special exception to save an RPC.
            if (VersionInfoUtil.hasMinimumVersion(context.getClientVersionInfo(), 1, 4)) {
                // 1.4.0+ clients know how to handle
                throw new ScannerResetException("Scanner is closed on the server-side", e);
            } else {
                // older clients do not know about SRE. Just throw USE, which they will handle
                throw new UnknownScannerException("Throwing UnknownScannerException to reset the client" + " scanner state for clients older than 1.3.", e);
            }
        } catch (IOException ioe) {
            throw new ServiceException(ioe);
        }
    } finally {
        if (!scannerClosed) {
            // the closeCallBack will be set in closeScanner so here we only care about shippedCallback
            if (context != null) {
                context.setCallBack(rsh.shippedCallback);
            } else {
                // When context != null, adding back the lease will be done in callback set above.
                addScannerLeaseBack(lease);
            }
        }
        quota.close();
    }
}
Also used : DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) ScannerResetException(org.apache.hadoop.hbase.exceptions.ScannerResetException) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) ByteString(org.apache.hbase.thirdparty.com.google.protobuf.ByteString) RegionActionResult(org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.RegionActionResult) Result(org.apache.hadoop.hbase.client.Result) CheckAndMutateResult(org.apache.hadoop.hbase.client.CheckAndMutateResult) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) OutOfOrderScannerNextException(org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException) MutableObject(org.apache.commons.lang3.mutable.MutableObject) RpcCallContext(org.apache.hadoop.hbase.ipc.RpcCallContext) Lease(org.apache.hadoop.hbase.regionserver.LeaseManager.Lease) ScanResponse(org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanResponse) OperationQuota(org.apache.hadoop.hbase.quotas.OperationQuota) IOException(java.io.IOException) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) HBaseIOException(org.apache.hadoop.hbase.HBaseIOException) UncheckedIOException(java.io.UncheckedIOException) UnknownScannerException(org.apache.hadoop.hbase.UnknownScannerException) HBaseRpcController(org.apache.hadoop.hbase.ipc.HBaseRpcController) ServiceException(org.apache.hbase.thirdparty.com.google.protobuf.ServiceException) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 2 with OutOfOrderScannerNextException

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

the class TestRpcMetrics method testSourceMethods.

/**
 * Test to make sure that all the actively called method on MetricsHBaseServer work.
 */
@Test
public void testSourceMethods() {
    MetricsHBaseServer mrpc = new MetricsHBaseServer("HMaster", new MetricsHBaseServerWrapperStub());
    MetricsHBaseServerSource serverSource = mrpc.getMetricsSource();
    for (int i = 0; i < 12; i++) {
        mrpc.authenticationFailure();
    }
    for (int i = 0; i < 13; i++) {
        mrpc.authenticationSuccess();
    }
    HELPER.assertCounter("authenticationFailures", 12, serverSource);
    HELPER.assertCounter("authenticationSuccesses", 13, serverSource);
    for (int i = 0; i < 14; i++) {
        mrpc.authorizationSuccess();
    }
    for (int i = 0; i < 15; i++) {
        mrpc.authorizationFailure();
    }
    HELPER.assertCounter("authorizationSuccesses", 14, serverSource);
    HELPER.assertCounter("authorizationFailures", 15, serverSource);
    mrpc.dequeuedCall(100);
    mrpc.processedCall(101);
    mrpc.totalCall(102);
    HELPER.assertCounter("queueCallTime_NumOps", 1, serverSource);
    HELPER.assertCounter("processCallTime_NumOps", 1, serverSource);
    HELPER.assertCounter("totalCallTime_NumOps", 1, serverSource);
    mrpc.sentBytes(103);
    mrpc.sentBytes(103);
    mrpc.sentBytes(103);
    mrpc.receivedBytes(104);
    mrpc.receivedBytes(104);
    HELPER.assertCounter("sentBytes", 309, serverSource);
    HELPER.assertCounter("receivedBytes", 208, serverSource);
    mrpc.receivedRequest(105);
    mrpc.sentResponse(106);
    HELPER.assertCounter("requestSize_NumOps", 1, serverSource);
    HELPER.assertCounter("responseSize_NumOps", 1, serverSource);
    mrpc.exception(null);
    HELPER.assertCounter("exceptions", 1, serverSource);
    mrpc.exception(new RegionMovedException(ServerName.parseServerName("localhost:60020"), 100));
    mrpc.exception(new RegionTooBusyException("Some region"));
    mrpc.exception(new OutOfOrderScannerNextException());
    mrpc.exception(new NotServingRegionException());
    mrpc.exception(new CallDroppedException());
    HELPER.assertCounter("exceptions.RegionMovedException", 1, serverSource);
    HELPER.assertCounter("exceptions.RegionTooBusyException", 1, serverSource);
    HELPER.assertCounter("exceptions.OutOfOrderScannerNextException", 1, serverSource);
    HELPER.assertCounter("exceptions.NotServingRegionException", 1, serverSource);
    HELPER.assertCounter("exceptions.callDropped", 1, serverSource);
    HELPER.assertCounter("exceptions", 6, serverSource);
}
Also used : RegionTooBusyException(org.apache.hadoop.hbase.RegionTooBusyException) NotServingRegionException(org.apache.hadoop.hbase.NotServingRegionException) RegionMovedException(org.apache.hadoop.hbase.exceptions.RegionMovedException) CallDroppedException(org.apache.hadoop.hbase.CallDroppedException) OutOfOrderScannerNextException(org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException) Test(org.junit.Test)

Aggregations

OutOfOrderScannerNextException (org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException)2 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 UncheckedIOException (java.io.UncheckedIOException)1 ArrayList (java.util.ArrayList)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 MutableObject (org.apache.commons.lang3.mutable.MutableObject)1 CallDroppedException (org.apache.hadoop.hbase.CallDroppedException)1 DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)1 HBaseIOException (org.apache.hadoop.hbase.HBaseIOException)1 NotServingRegionException (org.apache.hadoop.hbase.NotServingRegionException)1 RegionTooBusyException (org.apache.hadoop.hbase.RegionTooBusyException)1 UnknownScannerException (org.apache.hadoop.hbase.UnknownScannerException)1 CheckAndMutateResult (org.apache.hadoop.hbase.client.CheckAndMutateResult)1 Result (org.apache.hadoop.hbase.client.Result)1 RegionMovedException (org.apache.hadoop.hbase.exceptions.RegionMovedException)1 ScannerResetException (org.apache.hadoop.hbase.exceptions.ScannerResetException)1 HBaseRpcController (org.apache.hadoop.hbase.ipc.HBaseRpcController)1 RpcCallContext (org.apache.hadoop.hbase.ipc.RpcCallContext)1 OperationQuota (org.apache.hadoop.hbase.quotas.OperationQuota)1