You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "Bob Copeland (JIRA)" <ji...@apache.org> on 2012/05/03 23:04:49 UTC
[jira] [Commented] (HBASE-4956) Control direct memory buffer
consumption by HBaseClient
[ https://issues.apache.org/jira/browse/HBASE-4956?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13267797#comment-13267797 ]
Bob Copeland commented on HBASE-4956:
-------------------------------------
I have this bug on our servers (0.90.4-cdh3). I think Johnathan's analysis was spot on, but it matters much more for read path since readFully() allocates a direct buffer as large as the target read.
Here's an easy way to reproduce:
1) create a ~10 meg row in some table
2) edit bin/hbase script to have max direct memory size < 10m, e.g.:
{code}
+JAVA_HEAP_MAX="-Xmx1000m -XX:MaxDirectMemorySize=1m"
{code}
3) now have any client try to read this row. If read side were chunking with < 1m pieces, it should still be able to read.
Obviously this example is contrived, but we hit the problem with around 1-2000 threads (we have large rows in our DB). Here's what our stack trace looks like:
{code}
java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:633)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:98)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:288)
at sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:155)
at sun.nio.ch.IOUtil.read(IOUtil.java:174)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:243)
at org.apache.hadoop.net.SocketInputStream$Reader.performIO(SocketInputStream.java:55)
at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:142)
at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155)
at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at org.apache.hadoop.hbase.ipc.HBaseClient$Connection$PingInputStream.read(HBaseClient.java:299)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at java.io.DataInputStream.readFully(DataInputStream.java:178)
at org.apache.hadoop.hbase.client.Result.readFields(Result.java:504)
at org.apache.hadoop.hbase.io.HbaseObjectWritable.readObject(HbaseObjectWritable.java:521)
at org.apache.hadoop.hbase.io.HbaseObjectWritable.readFields(HbaseObjectWritable.java:259)
at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.receiveResponse(HBaseClient.java:554)
at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.run(HBaseClient.java:477)
{code}
The following works around the problem by only doing 8k allocations:
{code}
diff --git a/src/main/java/org/apache/hadoop/hbase/client/Result.java b/src/main/java/org/apache/hadoop/hbase/client/Result.java
index 8a0c1a9..378ca88 100644
--- a/src/main/java/org/apache/hadoop/hbase/client/Result.java
+++ b/src/main/java/org/apache/hadoop/hbase/client/Result.java
@@ -502,10 +502,18 @@ public class Result implements Writable, WritableWithSize {
return;
}
byte [] raw = new byte[totalBuffer];
- in.readFully(raw, 0, totalBuffer);
+ readChunked(in, raw, 0, totalBuffer);
bytes = new ImmutableBytesWritable(raw, 0, totalBuffer);
}
+ private void readChunked(final DataInput in, byte[] dest, int ofs, int len)
+ throws IOException {
+ int maxread = 8192;
+
+ for (; ofs < len; ofs += maxread)
+ in.readFully(dest, ofs, Math.min(len - ofs, maxread));
+ }
+
//Create KeyValue[] when needed
private void readFields() {
if (bytes == null) {
{code}
> Control direct memory buffer consumption by HBaseClient
> -------------------------------------------------------
>
> Key: HBASE-4956
> URL: https://issues.apache.org/jira/browse/HBASE-4956
> Project: HBase
> Issue Type: New Feature
> Reporter: Ted Yu
>
> As Jonathan explained here https://groups.google.com/group/asynchbase/browse_thread/thread/c45bc7ba788b2357?pli=1 , standard hbase client inadvertently consumes large amount of direct memory.
> We should consider using netty for NIO-related tasks.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira