From 391fa44c0d319cbb0d0885a7d139c67b2f50c7a8 Mon Sep 17 00:00:00 2001 From: Janardhan Hungund Date: Sun, 15 Sep 2024 18:43:07 +0530 Subject: [PATCH] HBASE-28840: Optimise memory utilization bucketcache retrieval from persistence. During the persistence of bucket-cache backing map to a file, the backing map is divided into multiple smaller chunks and persisted to the file. This chunking avoids the high memory utilisation of during persistence, since only a small subset of backing map entries need to persisted in one chunk. However, during the retrieval of the backing map during the server startup, we accumulate all these chunks into a list and then process each chunk to recreate the in-memory backing map. Since, all the chunks are fetched from the persistence file and then processed, the memory requirement is higher. With this change, the retrieval of bucket-cache from persistence file is optimised to enable the processing of one chunk at a time to avoid high memory utilisation. Change-Id: I12ed252d543be120183cbe5a3e769e5cda7998c1 --- .../hbase/io/hfile/bucket/BucketCache.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java index 11ec958b08a5..819b180d0fc5 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java @@ -1590,8 +1590,7 @@ private void verifyFileIntegrity(BucketCacheProtos.BucketCacheEntry proto) { } } - private void parsePB(BucketCacheProtos.BucketCacheEntry firstChunk, - List chunks) throws IOException { + private void parseFirstChunk(BucketCacheProtos.BucketCacheEntry firstChunk) throws IOException { fullyCachedFiles.clear(); Pair, NavigableSet> pair = BucketProtoUtils.fromPB(firstChunk.getDeserializersMap(), firstChunk.getBackingMap(), @@ -1599,22 +1598,14 @@ private void parsePB(BucketCacheProtos.BucketCacheEntry firstChunk, backingMap.putAll(pair.getFirst()); blocksByHFile.addAll(pair.getSecond()); fullyCachedFiles.putAll(BucketProtoUtils.fromPB(firstChunk.getCachedFilesMap())); + } - LOG.debug("Number of blocks after first chunk: {}, blocksByHFile: {}", backingMap.size(), - fullyCachedFiles.size()); - int i = 1; - for (BucketCacheProtos.BackingMap chunk : chunks) { - Pair, NavigableSet> pair2 = - BucketProtoUtils.fromPB(firstChunk.getDeserializersMap(), chunk, this::createRecycler); - backingMap.putAll(pair2.getFirst()); - blocksByHFile.addAll(pair2.getSecond()); - LOG.debug("Number of blocks after {} reading chunk: {}, blocksByHFile: {}", ++i, - backingMap.size(), fullyCachedFiles.size()); - } - verifyFileIntegrity(firstChunk); - verifyCapacityAndClasses(firstChunk.getCacheCapacity(), firstChunk.getIoClass(), - firstChunk.getMapClass()); - updateRegionSizeMapWhileRetrievingFromFile(); + private void parseChunkPB(BucketCacheProtos.BackingMap chunk, + java.util.Map deserializer) throws IOException { + Pair, NavigableSet> pair2 = + BucketProtoUtils.fromPB(deserializer, chunk, this::createRecycler); + backingMap.putAll(pair2.getFirst()); + blocksByHFile.addAll(pair2.getSecond()); } private void parsePB(BucketCacheProtos.BucketCacheEntry proto) throws IOException { @@ -1669,18 +1660,22 @@ private void retrieveChunkedBackingMap(FileInputStream in, int[] bucketSizes) th LOG.info("Number of chunks: {}, chunk size: {}", numChunks, batchSize); - ArrayList bucketCacheMaps = new ArrayList<>(); // Read the first chunk that has all the details. BucketCacheProtos.BucketCacheEntry firstChunk = BucketCacheProtos.BucketCacheEntry.parseDelimitedFrom(in); + parseFirstChunk(firstChunk); // Subsequent chunks have the backingMap entries. for (int i = 1; i < numChunks; i++) { LOG.info("Reading chunk no: {}", i + 1); - bucketCacheMaps.add(BucketCacheProtos.BackingMap.parseDelimitedFrom(in)); + parseChunkPB(BucketCacheProtos.BackingMap.parseDelimitedFrom(in), + firstChunk.getDeserializersMap()); LOG.info("Retrieved chunk: {}", i + 1); } - parsePB(firstChunk, bucketCacheMaps); + verifyFileIntegrity(firstChunk); + verifyCapacityAndClasses(firstChunk.getCacheCapacity(), firstChunk.getIoClass(), + firstChunk.getMapClass()); + updateRegionSizeMapWhileRetrievingFromFile(); } /**