Skip to content

Commit 2e41436

Browse files
committed
HBASE-22547 Align the config keys and add document for offheap read in HBase Book. (#301)
1 parent 686847c commit 2e41436

File tree

10 files changed

+219
-59
lines changed

10 files changed

+219
-59
lines changed

hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,21 @@ public class ByteBuffAllocator {
6868
// default heap allocator, it will just allocate ByteBuffers from heap but wrapped by an ByteBuff.
6969
public static final ByteBuffAllocator HEAP = ByteBuffAllocator.createOnHeap();
7070

71+
public static final String ALLOCATOR_POOL_ENABLED_KEY = "hbase.server.allocator.pool.enabled";
72+
7173
public static final String MAX_BUFFER_COUNT_KEY = "hbase.server.allocator.max.buffer.count";
7274

7375
public static final String BUFFER_SIZE_KEY = "hbase.server.allocator.buffer.size";
7476

77+
public static final String MIN_ALLOCATE_SIZE_KEY = "hbase.server.allocator.minimal.allocate.size";
78+
79+
/**
80+
* @deprecated use {@link ByteBuffAllocator#ALLOCATOR_POOL_ENABLED_KEY} instead.
81+
*/
82+
@Deprecated
83+
public static final String DEPRECATED_ALLOCATOR_POOL_ENABLED_KEY =
84+
"hbase.ipc.server.reservoir.enabled";
85+
7586
/**
7687
* @deprecated use {@link ByteBuffAllocator#MAX_BUFFER_COUNT_KEY} instead.
7788
*/
@@ -88,9 +99,12 @@ public class ByteBuffAllocator {
8899
* The hbase.ipc.server.reservoir.initial.max and hbase.ipc.server.reservoir.initial.buffer.size
89100
* were introduced in HBase2.0.0, while in HBase3.0.0 the two config keys will be replaced by
90101
* {@link ByteBuffAllocator#MAX_BUFFER_COUNT_KEY} and {@link ByteBuffAllocator#BUFFER_SIZE_KEY}.
91-
* Keep the two old config keys here for HBase2.x compatibility.
102+
* Also the hbase.ipc.server.reservoir.enabled will be replaced by
103+
* hbase.server.allocator.pool.enabled. Keep the three old config keys here for HBase2.x
104+
* compatibility.
92105
*/
93106
static {
107+
Configuration.addDeprecation(DEPRECATED_ALLOCATOR_POOL_ENABLED_KEY, ALLOCATOR_POOL_ENABLED_KEY);
94108
Configuration.addDeprecation(DEPRECATED_MAX_BUFFER_COUNT_KEY, MAX_BUFFER_COUNT_KEY);
95109
Configuration.addDeprecation(DEPRECATED_BUFFER_SIZE_KEY, BUFFER_SIZE_KEY);
96110
}
@@ -113,9 +127,6 @@ public class ByteBuffAllocator {
113127
*/
114128
public static final int DEFAULT_BUFFER_SIZE = 65 * 1024;
115129

116-
public static final String MIN_ALLOCATE_SIZE_KEY =
117-
"hbase.ipc.server.reservoir.minimal.allocating.size";
118-
119130
public static final Recycler NONE = () -> {
120131
};
121132

hbase-common/src/test/java/org/apache/hadoop/hbase/io/TestByteBuffAllocator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,5 +356,15 @@ public void testDeprecatedConfigs() {
356356
allocator = ByteBuffAllocator.create(conf, true);
357357
Assert.assertEquals(2048, allocator.getBufferSize());
358358
Assert.assertEquals(11, allocator.getTotalBufferCount());
359+
360+
conf = new Configuration();
361+
conf.setBoolean(ByteBuffAllocator.DEPRECATED_ALLOCATOR_POOL_ENABLED_KEY, false);
362+
Assert.assertFalse(conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, true));
363+
conf.setBoolean(ByteBuffAllocator.DEPRECATED_ALLOCATOR_POOL_ENABLED_KEY, true);
364+
Assert.assertTrue(conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, false));
365+
conf.setBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, true);
366+
Assert.assertTrue(conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, false));
367+
conf.setBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, false);
368+
Assert.assertFalse(conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, true));
359369
}
360370
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
6161
import org.apache.hadoop.hbase.errorhandling.ForeignException;
6262
import org.apache.hadoop.hbase.exceptions.UnknownProtocolException;
63+
import org.apache.hadoop.hbase.io.ByteBuffAllocator;
6364
import org.apache.hadoop.hbase.io.hfile.HFile;
6465
import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils;
6566
import org.apache.hadoop.hbase.ipc.PriorityFunction;
@@ -391,8 +392,8 @@ protected RpcServerInterface createRpcServer(Server server, Configuration conf,
391392
RpcSchedulerFactory rpcSchedulerFactory, InetSocketAddress bindAddress, String name)
392393
throws IOException {
393394
// RpcServer at HM by default enable ByteBufferPool iff HM having user table region in it
394-
boolean reservoirEnabled = conf.getBoolean(RESERVOIR_ENABLED_KEY,
395-
LoadBalancer.isMasterCanHostUserRegions(conf));
395+
boolean reservoirEnabled = conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY,
396+
LoadBalancer.isMasterCanHostUserRegions(conf));
396397
try {
397398
return RpcServerFactory.createRpcServer(server, name, getServices(),
398399
bindAddress, // use final bindAddress for this server.

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
import org.apache.hadoop.hbase.exceptions.ScannerResetException;
8989
import org.apache.hadoop.hbase.exceptions.UnknownProtocolException;
9090
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
91+
import org.apache.hadoop.hbase.io.ByteBuffAllocator;
9192
import org.apache.hadoop.hbase.io.TimeRange;
9293
import org.apache.hadoop.hbase.io.hfile.BlockCache;
9394
import org.apache.hadoop.hbase.ipc.HBaseRPCErrorHandler;
@@ -291,8 +292,6 @@ public class RSRpcServices implements HBaseRPCErrorHandler,
291292
*/
292293
static final int BATCH_ROWS_THRESHOLD_DEFAULT = 5000;
293294

294-
public static final String RESERVOIR_ENABLED_KEY = "hbase.ipc.server.reservoir.enabled";
295-
296295
// Request counter. (Includes requests that are not serviced by regions.)
297296
// Count only once for requests with multiple actions like multi/caching-scan/replayBatch
298297
final LongAdder requestCount = new LongAdder();
@@ -1278,7 +1277,7 @@ public RSRpcServices(HRegionServer rs) throws IOException {
12781277
protected RpcServerInterface createRpcServer(Server server, Configuration conf,
12791278
RpcSchedulerFactory rpcSchedulerFactory, InetSocketAddress bindAddress, String name)
12801279
throws IOException {
1281-
boolean reservoirEnabled = conf.getBoolean(RESERVOIR_ENABLED_KEY, true);
1280+
boolean reservoirEnabled = conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, true);
12821281
try {
12831282
return RpcServerFactory.createRpcServer(server, name, getServices(),
12841283
bindAddress, // use final bindAddress for this server.

hbase-server/src/test/java/org/apache/hadoop/hbase/mob/TestMobWithByteBuffAllocator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.apache.hadoop.hbase.client.ResultScanner;
3131
import org.apache.hadoop.hbase.client.Scan;
3232
import org.apache.hadoop.hbase.client.Table;
33-
import org.apache.hadoop.hbase.regionserver.RSRpcServices;
33+
import org.apache.hadoop.hbase.io.ByteBuffAllocator;
3434
import org.apache.hadoop.hbase.snapshot.MobSnapshotTestingUtils;
3535
import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
3636
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -64,7 +64,7 @@ public class TestMobWithByteBuffAllocator {
6464
@BeforeClass
6565
public static void setUp() throws Exception {
6666
// Must use the ByteBuffAllocator here
67-
CONF.setBoolean(RSRpcServices.RESERVOIR_ENABLED_KEY, true);
67+
CONF.setBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, true);
6868
// Must use OFF-HEAP BucketCache here.
6969
CONF.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.1f);
7070
CONF.set(HConstants.BUCKET_CACHE_IOENGINE_KEY, "offheap");

src/main/asciidoc/_chapters/architecture.adoc

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,54 +1005,6 @@ For a RegionServer hosting data that can comfortably fit into cache, or if your
10051005

10061006
The compressed BlockCache is disabled by default. To enable it, set `hbase.block.data.cachecompressed` to `true` in _hbase-site.xml_ on all RegionServers.
10071007

1008-
[[regionserver.offheap]]
1009-
=== RegionServer Offheap Read/Write Path
1010-
1011-
[[regionserver.offheap.readpath]]
1012-
==== Offheap read-path
1013-
In hbase-2.0.0, link:https://issues.apache.org/jira/browse/HBASE-11425[HBASE-11425] changed the HBase read path so it
1014-
could hold the read-data off-heap avoiding copying of cached data on to the java heap.
1015-
This reduces GC pauses given there is less garbage made and so less to clear. The off-heap read path has a performance
1016-
that is similar/better to that of the on-heap LRU cache. This feature is available since HBase 2.0.0.
1017-
If the BucketCache is in `file` mode, fetching will always be slower compared to the native on-heap LruBlockCache.
1018-
Refer to below blogs for more details and test results on off heaped read path
1019-
link:https://blogs.apache.org/hbase/entry/offheaping_the_read_path_in[Offheaping the Read Path in Apache HBase: Part 1 of 2]
1020-
and link:https://blogs.apache.org/hbase/entry/offheap-read-path-in-production[Offheap Read-Path in Production - The Alibaba story]
1021-
1022-
For an end-to-end off-heaped read-path, first of all there should be an off-heap backed <<offheap.blockcache>>(BC). Configure 'hbase.bucketcache.ioengine' to off-heap in
1023-
_hbase-site.xml_. Also specify the total capacity of the BC using `hbase.bucketcache.size` config. Please remember to adjust value of 'HBASE_OFFHEAPSIZE' in
1024-
_hbase-env.sh_. This is how we specify the max possible off-heap memory allocation for the
1025-
RegionServer java process. This should be bigger than the off-heap BC size. Please keep in mind that there is no default for `hbase.bucketcache.ioengine`
1026-
which means the BC is turned OFF by default (See <<direct.memory>>).
1027-
1028-
Next thing to tune is the ByteBuffer pool on the RPC server side.
1029-
The buffers from this pool will be used to accumulate the cell bytes and create a result cell block to send back to the client side.
1030-
`hbase.ipc.server.reservoir.enabled` can be used to turn this pool ON or OFF. By default this pool is ON and available. HBase will create off heap ByteBuffers
1031-
and pool them. Please make sure not to turn this OFF if you want end-to-end off-heaping in read path.
1032-
If this pool is turned off, the server will create temp buffers on heap to accumulate the cell bytes and make a result cell block. This can impact the GC on a highly read loaded server.
1033-
The user can tune this pool with respect to how many buffers are in the pool and what should be the size of each ByteBuffer.
1034-
Use the config `hbase.ipc.server.reservoir.initial.buffer.size` to tune each of the buffer sizes. Default is 64 KB.
1035-
1036-
When the read pattern is a random row read load and each of the rows are smaller in size compared to this 64 KB, try reducing this.
1037-
When the result size is larger than one ByteBuffer size, the server will try to grab more than one buffer and make a result cell block out of these. When the pool is running out of buffers, the server will end up creating temporary on-heap buffers.
1038-
1039-
The maximum number of ByteBuffers in the pool can be tuned using the config 'hbase.ipc.server.reservoir.initial.max'. Its value defaults to 64 * region server handlers configured (See the config 'hbase.regionserver.handler.count'). The math is such that by default we consider 2 MB as the result cell block size per read result and each handler will be handling a read. For 2 MB size, we need 32 buffers each of size 64 KB (See default buffer size in pool). So per handler 32 ByteBuffers(BB). We allocate twice this size as the max BBs count such that one handler can be creating the response and handing it to the RPC Responder thread and then handling a new request creating a new response cell block (using pooled buffers). Even if the responder could not send back the first TCP reply immediately, our count should allow that we should still have enough buffers in our pool without having to make temporary buffers on the heap. Again for smaller sized random row reads, tune this max count. There are lazily created buffers and the count is the max count to be pooled.
1040-
1041-
If you still see GC issues even after making end-to-end read path off-heap, look for issues in the appropriate buffer pool. Check the below RegionServer log with INFO level:
1042-
[source]
1043-
----
1044-
Pool already reached its max capacity : XXX and no free buffers now. Consider increasing the value for 'hbase.ipc.server.reservoir.initial.max' ?
1045-
----
1046-
1047-
The setting for _HBASE_OFFHEAPSIZE_ in _hbase-env.sh_ should consider this off heap buffer pool at the RPC side also. We need to config this max off heap size for the RegionServer as a bit higher than the sum of this max pool size and the off heap cache size. The TCP layer will also need to create direct bytebuffers for TCP communication. Also the DFS client will need some off-heap to do its workings especially if short-circuit reads are configured. Allocating an extra of 1 - 2 GB for the max direct memory size has worked in tests.
1048-
1049-
If you are using co processors and refer the Cells in the read results, DO NOT store reference to these Cells out of the scope of the CP hook methods. Some times the CPs need store info about the cell (Like its row key) for considering in the next CP hook call etc. For such cases, pls clone the required fields of the entire Cell as per the use cases. [ See CellUtil#cloneXXX(Cell) APIs ]
1050-
1051-
[[regionserver.offheap.writepath]]
1052-
==== Offheap write-path
1053-
1054-
TODO
1055-
10561008
[[regionserver_splitting_implementation]]
10571009
=== RegionServer Splitting Implementation
10581010

0 commit comments

Comments
 (0)