protected Region getRegionByEncodedName(byte[] regionName, String encodedRegionName) throws NotServingRegionException { Region 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.booleanValue()) { throw new RegionOpeningException( "Region " + regionNameStr + " is opening on " + this.serverName); } throw new NotServingRegionException( "Region " + regionNameStr + " is not online on " + this.serverName); } return region; }
protected 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.booleanValue()) { throw new RegionOpeningException("Region " + regionNameStr + " is opening on " + this.serverName); } throw new NotServingRegionException("Region " + regionNameStr + " is not online on " + this.serverName); } return region; }
@Override public void throwable(Throwable t, boolean retrying) { if (t instanceof SocketTimeoutException || t instanceof ConnectException || t instanceof RetriesExhaustedException || (location != null && getConnection().isDeadServer(location.getServerName()))) { // if thrown these exceptions, we clear all the cache entries that // map to that slow/dead server; otherwise, let cache miss and ask // hbase:meta again to find the new location if (this.location != null) getConnection().clearCaches(location.getServerName()); } else if (t instanceof RegionMovedException) { getConnection().updateCachedLocations(tableName, row, t, location); } else if (t instanceof NotServingRegionException && !retrying) { // Purge cache entries for this specific region from hbase:meta cache // since we don't call connect(true) when number of retries is 1. getConnection().deleteCachedRegionLocation(location); } }
protected 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.booleanValue()) { throw new RegionOpeningException("Region " + regionNameStr + " is opening on " + this.serverNameFromMasterPOV); } throw new NotServingRegionException("Region " + regionNameStr + " is not online on " + this.serverNameFromMasterPOV); } return region; }
protected 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.booleanValue()) { throw new RegionOpeningException("Region " + regionNameStr + " is opening on " + this.serverName); } throw new NotServingRegionException("" + regionNameStr + " is not online on " + this.serverName); } return region; }
static void setExceptionResponse(Throwable t, String errorMsg, ResponseHeader.Builder headerBuilder) { ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder(); exceptionBuilder.setExceptionClassName(t.getClass().getName()); exceptionBuilder.setStackTrace(errorMsg); exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException); if (t instanceof RegionMovedException) { // Special casing for this exception. This is only one carrying a payload. // Do this instead of build a generic system for allowing exceptions carry // any kind of payload. RegionMovedException rme = (RegionMovedException)t; exceptionBuilder.setHostname(rme.getHostname()); exceptionBuilder.setPort(rme.getPort()); } // Set the exception as the result of the method invocation. headerBuilder.setException(exceptionBuilder.build()); }
protected 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.booleanValue()) { throw new RegionOpeningException("Region " + regionNameStr + " is opening on " + this.serverName); } throw new NotServingRegionException("Region " + regionNameStr + " is not online on " + this.serverName); } return region; }
@Override public void throwable(Throwable t, boolean retrying) { if (t instanceof SocketTimeoutException || t instanceof ConnectException || t instanceof RetriesExhaustedException || (location != null && getConnection().isDeadServer(location.getServerName()))) { // if thrown these exceptions, we clear all the cache entries that // map to that slow/dead server; otherwise, let cache miss and ask // hbase:meta again to find the new location if (this.location != null) getConnection().clearCaches(location.getServerName()); } else if (t instanceof RegionMovedException) { getConnection().updateCachedLocations(tableName, row, t, location.getServerName()); } else if (t instanceof NotServingRegionException && !retrying) { // Purge cache entries for this specific region from hbase:meta cache // since we don't call connect(true) when number of retries is 1. getConnection().deleteCachedRegionLocation(location); } }
protected 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.booleanValue()) { throw new RegionOpeningException("Region " + regionNameStr + " is opening"); } throw new NotServingRegionException("Region " + regionNameStr + " is not online"); } return region; }
public void exception(Throwable throwable) { source.exception(); /** * Keep some metrics for commonly seen exceptions * * Try and put the most common types first. * Place child types before the parent type that they extend. * * If this gets much larger we might have to go to a hashmap */ if (throwable != null) { if (throwable instanceof OutOfOrderScannerNextException) { source.outOfOrderException(); } else if (throwable instanceof RegionTooBusyException) { source.tooBusyException(); } else if (throwable instanceof UnknownScannerException) { source.unknownScannerException(); } else if (throwable instanceof RegionMovedException) { source.movedRegionException(); } else if (throwable instanceof NotServingRegionException) { source.notServingRegionException(); } else if (throwable instanceof FailedSanityCheckException) { source.failedSanityException(); } else if (throwable instanceof MultiActionResultTooLarge) { source.multiActionTooLargeException(); } } }
/** * Look for an exception we know in the remote exception: * - hadoop.ipc wrapped exceptions * - nested exceptions * <p/> * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException * * @return null if we didn't find the exception, the exception otherwise. */ public static Throwable findException(Object exception) { if (exception == null || !(exception instanceof Throwable)) { return null; } Throwable cur = (Throwable) exception; while (cur != null) { if (cur instanceof RegionMovedException || cur instanceof RegionOpeningException || cur instanceof RegionTooBusyException) { return cur; } if (cur instanceof RemoteException) { RemoteException re = (RemoteException) cur; cur = re.unwrapRemoteException( RegionOpeningException.class, RegionMovedException.class, RegionTooBusyException.class); if (cur == null) { cur = re.unwrapRemoteException(); } // unwrapRemoteException can return the exception given as a parameter when it cannot // unwrap it. In this case, there is no need to look further // noinspection ObjectEquality if (cur == re) { return null; } } else { cur = cur.getCause(); } } return null; }
/** * Look for an exception we know in the remote exception: * - hadoop.ipc wrapped exceptions * - nested exceptions * * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException * @return null if we didn't find the exception, the exception otherwise. */ public static Throwable findException(Object exception) { if (exception == null || !(exception instanceof Throwable)) { return null; } Throwable cur = (Throwable) exception; while (cur != null) { if (cur instanceof RegionMovedException || cur instanceof RegionOpeningException || cur instanceof RegionTooBusyException) { return cur; } if (cur instanceof RemoteException) { RemoteException re = (RemoteException) cur; cur = re.unwrapRemoteException( RegionOpeningException.class, RegionMovedException.class, RegionTooBusyException.class); if (cur == null) { cur = re.unwrapRemoteException(); } // unwrapRemoteException can return the exception given as a parameter when it cannot // unwrap it. In this case, there is no need to look further // noinspection ObjectEquality if (cur == re) { return null; } } else { cur = cur.getCause(); } } return null; }
/** * Increment the count for a specific exception type. This is called for each exception type * that is returned to the thrift handler. * @param rawThrowable type of exception */ public void exception(Throwable rawThrowable) { source.exception(); Throwable throwable = unwrap(rawThrowable); /** * Keep some metrics for commonly seen exceptions * * Try and put the most common types first. * Place child types before the parent type that they extend. * * If this gets much larger we might have to go to a hashmap */ if (throwable != null) { if (throwable instanceof OutOfOrderScannerNextException) { source.outOfOrderException(); } else if (throwable instanceof RegionTooBusyException) { source.tooBusyException(); } else if (throwable instanceof UnknownScannerException) { source.unknownScannerException(); } else if (throwable instanceof ScannerResetException) { source.scannerResetException(); } else if (throwable instanceof RegionMovedException) { source.movedRegionException(); } else if (throwable instanceof NotServingRegionException) { source.notServingRegionException(); } else if (throwable instanceof FailedSanityCheckException) { source.failedSanityException(); } else if (throwable instanceof MultiActionResultTooLarge) { source.multiActionTooLargeException(); } else if (throwable instanceof CallQueueTooBigException) { source.callQueueTooBigException(); } } }
@Override public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e, Get get, List<Cell> results) throws IOException { byte[] errorType = get.getAttribute(SHOULD_ERROR_ATTRIBUTE); if (errorType != null) { ErrorType type = ErrorType.valueOf(Bytes.toString(errorType)); switch (type) { case CALL_QUEUE_TOO_BIG: throw new CallQueueTooBigException("Failing for test"); case MULTI_ACTION_RESULT_TOO_LARGE: throw new MultiActionResultTooLarge("Failing for test"); case FAILED_SANITY_CHECK: throw new FailedSanityCheckException("Failing for test"); case NOT_SERVING_REGION: throw new NotServingRegionException("Failing for test"); case REGION_MOVED: throw new RegionMovedException(e.getEnvironment().getServerName(), 1); case SCANNER_RESET: throw new ScannerResetException("Failing for test"); case UNKNOWN_SCANNER: throw new UnknownScannerException("Failing for test"); case REGION_TOO_BUSY: throw new RegionTooBusyException("Failing for test"); case OUT_OF_ORDER_SCANNER_NEXT: throw new OutOfOrderScannerNextException("Failing for test"); default: throw new DoNotRetryIOException("Failing for test"); } } }
public void exception(Throwable throwable) { source.exception(); /** * Keep some metrics for commonly seen exceptions * * Try and put the most common types first. * Place child types before the parent type that they extend. * * If this gets much larger we might have to go to a hashmap */ if (throwable != null) { if (throwable instanceof OutOfOrderScannerNextException) { source.outOfOrderException(); } else if (throwable instanceof RegionTooBusyException) { source.tooBusyException(); } else if (throwable instanceof UnknownScannerException) { source.unknownScannerException(); } else if (throwable instanceof ScannerResetException) { source.scannerResetException(); } else if (throwable instanceof RegionMovedException) { source.movedRegionException(); } else if (throwable instanceof NotServingRegionException) { source.notServingRegionException(); } else if (throwable instanceof FailedSanityCheckException) { source.failedSanityException(); } else if (throwable instanceof MultiActionResultTooLarge) { source.multiActionTooLargeException(); } else if (throwable instanceof CallQueueTooBigException) { source.callQueueTooBigException(); } } }
static void updateCachedLocation(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); } }
protected synchronized void setResponse(Object m, final CellScanner cells, Throwable t, String errorMsg) { if (this.isError) return; if (t != null) this.isError = true; BufferChain bc = null; try { ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder(); // Presume it a pb Message. Could be null. Message result = (Message)m; // Call id. headerBuilder.setCallId(this.id); if (t != null) { ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder(); exceptionBuilder.setExceptionClassName(t.getClass().getName()); exceptionBuilder.setStackTrace(errorMsg); exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException || t instanceof NeedUnmanagedConnectionException); if (t instanceof RegionMovedException) { // Special casing for this exception. This is only one carrying a payload. // Do this instead of build a generic system for allowing exceptions carry // any kind of payload. RegionMovedException rme = (RegionMovedException)t; exceptionBuilder.setHostname(rme.getHostname()); exceptionBuilder.setPort(rme.getPort()); } // Set the exception as the result of the method invocation. headerBuilder.setException(exceptionBuilder.build()); } // Pass reservoir to buildCellBlock. Keep reference to returne so can add it back to the // reservoir when finished. This is hacky and the hack is not contained but benefits are // high when we can avoid a big buffer allocation on each rpc. this.cellBlock = ipcUtil.buildCellBlock(this.connection.codec, this.connection.compressionCodec, cells, reservoir); if (this.cellBlock != null) { CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder(); // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it. cellBlockBuilder.setLength(this.cellBlock.limit()); headerBuilder.setCellBlockMeta(cellBlockBuilder.build()); } Message header = headerBuilder.build(); // Organize the response as a set of bytebuffers rather than collect it all together inside // one big byte array; save on allocations. ByteBuffer bbHeader = IPCUtil.getDelimitedMessageAsByteBuffer(header); ByteBuffer bbResult = IPCUtil.getDelimitedMessageAsByteBuffer(result); int totalSize = bbHeader.capacity() + (bbResult == null? 0: bbResult.limit()) + (this.cellBlock == null? 0: this.cellBlock.limit()); ByteBuffer bbTotalSize = ByteBuffer.wrap(Bytes.toBytes(totalSize)); bc = new BufferChain(bbTotalSize, bbHeader, bbResult, this.cellBlock); if (connection.useWrap) { bc = wrapWithSasl(bc); } } catch (IOException e) { LOG.warn("Exception while creating response " + e); } this.response = bc; }
/** * 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()); mrpc.exception(new OutOfOrderScannerNextException()); mrpc.exception(new NotServingRegionException()); 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", 5, serverSource); }
/** * 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 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())) { // There is no such location in the cache (it's been removed already) or // 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 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); }
protected synchronized void setResponse(Object m, final CellScanner cells, Throwable t, String errorMsg) { if (this.isError) return; if (t != null) this.isError = true; BufferChain bc = null; try { ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder(); // Presume it a pb Message. Could be null. Message result = (Message)m; // Call id. headerBuilder.setCallId(this.id); if (t != null) { ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder(); exceptionBuilder.setExceptionClassName(t.getClass().getName()); exceptionBuilder.setStackTrace(errorMsg); exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException); if (t instanceof RegionMovedException) { // Special casing for this exception. This is only one carrying a payload. // Do this instead of build a generic system for allowing exceptions carry // any kind of payload. RegionMovedException rme = (RegionMovedException)t; exceptionBuilder.setHostname(rme.getHostname()); exceptionBuilder.setPort(rme.getPort()); } // Set the exception as the result of the method invocation. headerBuilder.setException(exceptionBuilder.build()); } ByteBuffer cellBlock = ipcUtil.buildCellBlock(this.connection.codec, this.connection.compressionCodec, cells); if (cellBlock != null) { CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder(); // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it. cellBlockBuilder.setLength(cellBlock.limit()); headerBuilder.setCellBlockMeta(cellBlockBuilder.build()); } Message header = headerBuilder.build(); // Organize the response as a set of bytebuffers rather than collect it all together inside // one big byte array; save on allocations. ByteBuffer bbHeader = IPCUtil.getDelimitedMessageAsByteBuffer(header); ByteBuffer bbResult = IPCUtil.getDelimitedMessageAsByteBuffer(result); int totalSize = bbHeader.capacity() + (bbResult == null? 0: bbResult.limit()) + (cellBlock == null? 0: cellBlock.limit()); ByteBuffer bbTotalSize = ByteBuffer.wrap(Bytes.toBytes(totalSize)); bc = new BufferChain(bbTotalSize, bbHeader, bbResult, cellBlock); if (connection.useWrap) { bc = wrapWithSasl(bc); } } catch (IOException e) { LOG.warn("Exception while creating response " + e); } this.response = bc; }
/** * 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 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())) { // There is no such location in the cache (it's been removed already) or // the cache has already been refreshed with a different location. => nothing to do return; } HRegionInfo regionInfo = oldLocation.getRegionInfo(); Throwable cause = findException(exception); if (cause != null) { if (cause instanceof RegionTooBusyException || cause instanceof RegionOpeningException) { // 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 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); }
/** * 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[] rowkey, final Object exception, final HRegionLocation 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 || source.getServerName() == null){ // This should not happen, but let's secure ourselves. return; } // Is it something we have already updated? final HRegionLocation oldLocation = getCachedLocation(tableName, rowkey); if (oldLocation == null || !source.getServerName().equals(oldLocation.getServerName())) { // There is no such location in the cache (it's been removed already) or // the cache has already been refreshed with a different location. => nothing to do return; } HRegionInfo regionInfo = oldLocation.getRegionInfo(); Throwable cause = findException(exception); if (cause != null) { if (cause instanceof RegionTooBusyException || cause instanceof RegionOpeningException) { // 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.getHostnamePort()); } // 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 we're here, it means that can cannot be sure about the location, so we remove it from // the cache. deleteCachedLocation(regionInfo, source); }
/** * 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()); 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", 5, serverSource); }
/** * 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())) { // There is no such location in the cache (it's been removed already) or // the cache has already been refreshed with a different location. => nothing to do return; } RegionInfo regionInfo = oldLocation.getRegion(); 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.getAddress()); } // 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); }
/** * 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[] 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; } // Is it something we have already updated? final HRegionLocation oldLocation = getCachedLocation(tableName, rowkey); if (oldLocation == null || !source.equals(oldLocation.getServerName())) { // There is no such location in the cache (it's been removed already) or // the cache has already been refreshed with a different location. => nothing to do return; } HRegionInfo regionInfo = oldLocation.getRegionInfo(); Throwable cause = findException(exception); if (cause != null) { if (cause instanceof RegionTooBusyException || cause instanceof RegionOpeningException) { // 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 we're here, it means that can cannot be sure about the location, so we remove it from // the cache. deleteCachedLocation(regionInfo, source); }