2727import org .apache .hadoop .hbase .HConstants ;
2828import org .apache .hadoop .hbase .PrivateCellUtil ;
2929import org .apache .hadoop .hbase .client .metrics .ScanMetrics ;
30+ import org .apache .hadoop .hbase .io .hfile .BlockCache ;
3031import org .apache .hadoop .hbase .io .hfile .BlockCacheFactory ;
3132import org .apache .hadoop .hbase .mob .MobFileCache ;
3233import org .apache .hadoop .hbase .regionserver .HRegion ;
@@ -46,6 +47,8 @@ public class ClientSideRegionScanner extends AbstractClientScanner {
4647 private static final Logger LOG = LoggerFactory .getLogger (ClientSideRegionScanner .class );
4748
4849 private HRegion region ;
50+ private MobFileCache mobFileCache ;
51+ private BlockCache blockCache ;
4952 RegionScanner scanner ;
5053 List <Cell > values ;
5154 boolean hasMore = true ;
@@ -69,12 +72,14 @@ public ClientSideRegionScanner(Configuration conf, FileSystem fs, Path rootDir,
6972 String .valueOf (HConstants .HBASE_CLIENT_SCANNER_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT ));
7073 // don't allow L2 bucket cache for non RS process to avoid unexpected disk usage.
7174 conf .unset (HConstants .BUCKET_CACHE_IOENGINE_KEY );
72- region .setBlockCache (BlockCacheFactory .createBlockCache (conf ));
75+ blockCache = BlockCacheFactory .createBlockCache (conf );
76+ region .setBlockCache (blockCache );
7377 // we won't initialize the MobFileCache when not running in RS process. so provided an
7478 // initialized cache. Consider the case: an CF was set from an mob to non-mob. if we only
7579 // initialize cache for MOB region, NPE from HMobStore will still happen. So Initialize the
7680 // cache for every region although it may hasn't any mob CF, BTW the cache is very light-weight.
77- region .setMobFileCache (new MobFileCache (conf ));
81+ mobFileCache = new MobFileCache (conf );
82+ region .setMobFileCache (mobFileCache );
7883 region .initialize ();
7984
8085 // create an internal region scanner
@@ -131,6 +136,19 @@ public void close() {
131136 LOG .warn ("Exception while closing region" , ex );
132137 }
133138 }
139+
140+ // In typical region operation, RegionServerServices would handle the lifecycle of
141+ // the MobFileCache and BlockCache. In ClientSideRegionScanner, we need to handle
142+ // the lifecycle of these components ourselves to avoid resource leaks.
143+ if (mobFileCache != null ) {
144+ mobFileCache .shutdown ();
145+ mobFileCache = null ;
146+ }
147+
148+ if (blockCache != null ) {
149+ blockCache .shutdown ();
150+ blockCache = null ;
151+ }
134152 }
135153
136154 HRegion getRegion () {
0 commit comments