HBase批量PUT操作出现ByteBuf内存泄漏问题求助
HBase Client 2.2.3 大量PUT操作引发Netty ByteBuf内存泄漏解决方案
问题场景
使用HBase Client 2.2.3执行大规模PUT写入操作时,运行一段时间后触发Netty资源泄漏报错,具体日志如下:
ERROR util.ResourceLeakDetector: LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information. Recent access records: #1: org.apache.hbase.thirdparty.io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:616) org.apache.hbase.thirdparty.io.netty.buffer.ByteBufOutputStream.write(ByteBufOutputStream.java:68) org.apache.hadoop.hbase.KeyValue.write(KeyValue.java:2313) org.apache.hadoop.hbase.KeyValueUtil.oswrite(KeyValueUtil.java:805) org.apache.hadoop.hbase.codec.KeyValueCodec$KeyValueEncoder.write(KeyValueCodec.java:63) org.apache.hadoop.hbase.ipc.CellBlockBuilder.encodeCellsTo(CellBlockBuilder.java:192) org.apache.hadoop.hbase.ipc.CellBlockBuilder.buildCellBlock(CellBlockBuilder.java:171) org.apache.hadoop.hbase.ipc.CellBlockBuilder.buildCellBlock(CellBlockBuilder.java:155) org.apache.hadoop.hbase.ipc.NettyRpcDuplexHandler.writeRequest(NettyRpcDuplexHandler.java:81) org.apache.hadoop.hbase.ipc.NettyRpcDuplexHandler.write(NettyRpcDuplexHandler.java:119) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:706) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:753) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:778) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:747) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:801) org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1036) org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:305) org.apache.hadoop.hbase.ipc.NettyRpcConnection.write(NettyRpcConnection.java:284) org.apache.hadoop.hbase.ipc.NettyRpcConnection.access$1100(NettyRpcConnection.java:71) org.apache.hadoop.hbase.ipc.NettyRpcConnection$6$1.run(NettyRpcConnection.java:344) org.apache.hbase.thirdparty.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) org.apache.hbase.thirdparty.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) org.apache.hbase.thirdparty.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:495) org.apache.hbase.thirdparty.io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905) org.apache.hbase.thirdparty.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:750)
已尝试调整HBASE-19320中推荐的参数,但问题未解决。
可行解决方案
1. 升级HBase Client到修复泄漏的版本
2.2.3版本存在多个Netty ByteBuf泄漏相关的未修复Bug,建议升级到:
- 2.2.x分支的最新补丁版本(如2.2.10),该版本修复了HBASE-21525、HBASE-20909等相关泄漏问题
- 或直接迁移到更稳定的2.4.x分支(如2.4.12),长期维护性更好
2. 补充调整RPC连接相关参数
在客户端配置文件hbase-site.xml中添加/修改以下参数:
<!-- 限制闲置连接的最大存活时间,避免闲置连接占用ByteBuf --> <property> <name>hbase.ipc.client.connection.maxidletime</name> <value>60000</value> <!-- 60秒 --> </property> <!-- 使用RoundRobin连接池,优化连接复用 --> <property> <name>hbase.client.ipc.pool.type</name> <value>RoundRobinPool</value> </property> <!-- 根据并发量设置连接池大小,避免频繁创建销毁连接 --> <property> <name>hbase.client.ipc.pool.size</name> <value>10</value> </property> <!-- 开启ByteBuf释放检查(部分2.2.x补丁版本支持) --> <property> <name>hbase.ipc.client.bytebuf.check.release</name> <value>true</value> </property>
3. 优化PUT操作的批量处理逻辑
- 避免循环执行单条
table.put(Put),改用批量提交:table.put(List<Put>),减少RPC请求次数,降低ByteBuf的创建频率 - 控制每个批量的大小,建议每个批量包含500-2000条PUT记录,避免单个CellBlock过大导致ByteBuf无法及时回收
4. 排查代码中的资源泄漏点
- 确保所有HBase资源(
Connection、Table、Put)都在finally块中关闭,尤其是异常场景下必须释放资源 - 如果自定义了Cell编解码器或RPC拦截器,检查是否正确处理了ByteBuf的引用计数,确保使用后调用
release()方法
内容的提问来源于stack exchange,提问作者Fabrissou
相关产品推荐
相关产品推荐

