我试图将行放入HBase(0.90.0)中,批量大小为1000(行)我有多个生产者线程将数据写入队列,并且每隔几分钟唤醒一个消费者线程,将队列中的所有内容写入HBase作为批处理。但是,我得到以下异常,我不确定这意味着什么。
Caused by: java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1760)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatch(HConnectionManager.java:1135)
非常感谢任何帮助!
答案 0 :(得分:5)
如果可以,请避免对过去曾Put
d的HTable执行close()
或其他操作。
通常没有充分理由在代码中间执行htable.close()
,htable.flushCommits()
可能就足够了。当您的代码不再使用HBase时,请尝试保留htable.close()
作为最终确定步骤。
本Jira详细介绍了这个错误:https://issues.apache.org/jira/browse/HBASE-3692
请检查您的代码,搜索对close()
的来电,然后将其删除或在需要时将其替换为flushCommits()
。我遇到了你遇到的同样问题,删除不必要的htable.close()
电话就足以避免这个问题了。
答案 1 :(得分:1)
我在我们的代码中使用HBH 0.94.15在CDH 4.7中追踪了一个非常类似的bug,今晚我终于找到了这个bug的原因。它似乎已在最新的HBase中修复,因此快速解决方法是升级。
问题是HTablePool.PooledHTable.close()
的执行不当。 Java的Closeable
界面说多次调用close()
没有任何影响。但是,如果您遵循代码,您将看到池化的表接口不遵循此规则,并且第二次关闭它们实际上会将包装的表重新放回池中。在第二次关闭时,实际的包装表可能正在另一个线程中使用。这可能导致在使用时关闭连接,甚至是访问同一个包装表的另一个线程。
HTablePool.PooledHTable.close()
并未抱怨)我们的解决方法是删除合并表上的第二个close()
。不再RejectedExecutionException
!
最新HBase checks如果池表接口已经关闭,如果是,则不会再次关闭包装表。它还抛出了一个异常,它仍然不符合Java Closeable
接口,但那是另一个故事。