From 13eeae2b550e32e73857352940d6a93affcaab21 Mon Sep 17 00:00:00 2001 From: Guangxu Cheng Date: Fri, 1 Dec 2017 00:43:16 +0800 Subject: [PATCH] HBASE-19000 Group multiple block cache clear requests per server --- .../org/apache/hadoop/hbase/client/HBaseAdmin.java | 35 +++++++++++++++------- .../hbase/shaded/protobuf/RequestConverter.java | 12 +++++--- .../src/main/protobuf/Admin.proto | 2 ++ .../hadoop/hbase/regionserver/RSRpcServices.java | 21 ++++++++----- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 1a00efe134..a68f815dbb 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -111,6 +111,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearCompactionQueuesRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearRegionBlockCacheRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearRegionBlockCacheResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CompactRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.FlushRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoRequest; @@ -1460,32 +1461,44 @@ public class HBaseAdmin implements Admin { CacheEvictionStatsBuilder cacheEvictionStats = CacheEvictionStats.builder(); List> pairs = MetaTableAccessor.getTableRegionsAndLocations(connection, tableName); - for (Pair pair: pairs) { - if (pair.getFirst().isOffline() || pair.getSecond() == null) { - continue; - } + Map> regionInfoByServerName = + pairs.stream() + .filter(pair -> !(pair.getFirst().isOffline())) + .filter(pair -> pair.getSecond() != null) + .collect(Collectors.groupingBy(pair -> pair.getSecond(), + Collectors.mapping(pair -> pair.getFirst(), Collectors.toList()))); + for (Map.Entry> entry : regionInfoByServerName.entrySet()) { try { cacheEvictionStats = cacheEvictionStats.append( - clearBlockCache(pair.getSecond(), pair.getFirst())); + clearBlockCache(entry.getKey(), entry.getValue())); } catch (NotServingRegionException e) { if (LOG.isDebugEnabled()) { - LOG.debug("Failed to clear block cache for " + pair.getFirst() + " on " + - pair.getSecond() + ": " + StringUtils.stringifyException(e)); + LOG.debug("Failed to clear block cache for " + entry.getValue() + " on " + + entry.getKey() + ": " + StringUtils.stringifyException(e)); } } } return cacheEvictionStats.build(); } - private CacheEvictionStats clearBlockCache(final ServerName sn, final RegionInfo hri) + private CacheEvictionStats clearBlockCache(final ServerName sn, final List hris) throws IOException { HBaseRpcController controller = rpcControllerFactory.newController(); AdminService.BlockingInterface admin = this.connection.getAdmin(sn); ClearRegionBlockCacheRequest request = - RequestConverter.buildClearRegionBlockCacheRequest(hri.getRegionName()); + RequestConverter.buildClearRegionBlockCacheRequest(hris); + ClearRegionBlockCacheResponse response; try { - return ProtobufUtil.toCacheEvictionStats( - admin.clearRegionBlockCache(controller, request).getStats()); + response = admin.clearRegionBlockCache(controller, request); + if (LOG.isDebugEnabled()) { + for (int i = 0; i< response.getExceptionCount();i++) { + LOG.debug("Failed to clear block cache for " + + Bytes.toStringBinary(response.getRegion(i).getValue().toByteArray()) + + " on " + sn + ": " + + Bytes.toStringBinary(response.getException(i).getValue().toByteArray())); + } + } + return ProtobufUtil.toCacheEvictionStats(response.getStats()); } catch (ServiceException se) { throw ProtobufUtil.getRemoteException(se); } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java index 039a5b2fc7..913f1109ac 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java @@ -1507,10 +1507,14 @@ public final class RequestConverter { * * @return a ClearRegionBlockCacheRequest */ - public static ClearRegionBlockCacheRequest buildClearRegionBlockCacheRequest(final byte[] - regionName) { - RegionSpecifier region = buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName); - return ClearRegionBlockCacheRequest.newBuilder().addAllRegion(Lists.newArrayList(region)).build(); + public static ClearRegionBlockCacheRequest + buildClearRegionBlockCacheRequest(List hris) { + ClearRegionBlockCacheRequest.Builder builder = ClearRegionBlockCacheRequest.newBuilder(); + hris.forEach( + hri -> builder.addRegion( + buildRegionSpecifier(RegionSpecifierType.REGION_NAME, hri.getRegionName()) + )); + return builder.build(); } /** diff --git a/hbase-protocol-shaded/src/main/protobuf/Admin.proto b/hbase-protocol-shaded/src/main/protobuf/Admin.proto index 118c79b48b..533b82d756 100644 --- a/hbase-protocol-shaded/src/main/protobuf/Admin.proto +++ b/hbase-protocol-shaded/src/main/protobuf/Admin.proto @@ -254,6 +254,8 @@ message ClearRegionBlockCacheRequest { message ClearRegionBlockCacheResponse { required CacheEvictionStats stats = 1; + repeated RegionSpecifier region = 2; + repeated NameBytesPair exception = 3; } message ExecuteProceduresRequest { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java index 3f2dd271ad..c68f54cbbd 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java @@ -1347,11 +1347,16 @@ public class RSRpcServices implements HBaseRPCErrorHandler, * @throws IOException if any of the specifiers is not null, * but failed to find the region */ - private List getRegions( - final List regionSpecifiers) throws IOException { + private List getRegions(final List regionSpecifiers, + final ClearRegionBlockCacheResponse.Builder builder) throws IOException { List regions = Lists.newArrayListWithCapacity(regionSpecifiers.size()); for (RegionSpecifier regionSpecifier: regionSpecifiers) { - regions.add(regionServer.getRegion(regionSpecifier.getValue().toByteArray())); + try { + regions.add(regionServer.getRegion(regionSpecifier.getValue().toByteArray())); + } catch (NotServingRegionException e) { + builder.addRegion(regionSpecifier) + .addException(ResponseConverter.buildException(e)); + } } return regions; } @@ -3430,19 +3435,19 @@ public class RSRpcServices implements HBaseRPCErrorHandler, @Override public ClearRegionBlockCacheResponse clearRegionBlockCache(RpcController controller, - ClearRegionBlockCacheRequest request) + ClearRegionBlockCacheRequest request) throws ServiceException { + ClearRegionBlockCacheResponse.Builder builder = + ClearRegionBlockCacheResponse.newBuilder(); CacheEvictionStatsBuilder stats = CacheEvictionStats.builder(); try { - List regions = getRegions(request.getRegionList()); + List regions = getRegions(request.getRegionList(), builder); for (HRegion region : regions) { stats = stats.append(this.regionServer.clearRegionBlockCache(region)); } } catch (Exception e) { throw new ServiceException(e); } - return ClearRegionBlockCacheResponse.newBuilder() - .setStats(ProtobufUtil.toCacheEvictionStats(stats.build())) - .build(); + return builder.setStats(ProtobufUtil.toCacheEvictionStats(stats.build())).build(); } } -- 2.13.0.windows.1