对HBase表执行批处理PUT时拒绝执行Exception

对HBase表执行批处理PUT时拒绝执行Exception,hbase,Hbase,我试图将行以1000(行)的大小批量放入HBase(0.90.0)。我有多个生产者线程将数据写入队列,一个消费者线程每隔几分钟唤醒一次,并将队列中的所有内容作为批写入HBase。然而,我得到了以下例外,我不确定这意味着什么 Caused by: java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Th

我试图将行以1000(行)的大小批量放入HBase(0.90.0)。我有多个生产者线程将数据写入队列,一个消费者线程每隔几分钟唤醒一次,并将队列中的所有内容作为批写入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)

非常感谢您的帮助

如果可以,请避免对过去已关闭的表执行
Put
或其他操作。

<>通常,在代码的中间没有什么很强的理由来做<代码> HTTe.Cuffe()/Case>,一个<代码> Htut.FrHuffStices()可能已经足够了。当您的代码不再使用HBase时,请尝试保留
htable.close()
作为结束步骤

本Jira更详细地介绍了此错误:


因此,请检查您的代码,搜索对
close()
的调用,如果需要,可以删除它们或将其替换为
flushCommits()
。我遇到了与您相同的问题,删除不必要的
htable.close()
调用就足以避免该问题。

几个月来,我一直在使用CDH 4.7中的HBase 0.94.15在代码中跟踪一个非常类似的错误,今晚我终于找到了该错误的原因。它在最新的HBase中似乎已经修复,所以一个快速的解决方法就是升级

问题是执行程序不当。Java的接口说多次调用
close()
没有影响。但是,如果您遵循代码,您将看到池表接口不遵循此规则,第二次关闭它们实际上会将包装的表重新放入池中。在第二次关闭时,实际包装的表可能正在另一个线程中使用。这可能导致连接在使用时关闭,甚至另一个线程访问同一包装表

  • 线程A从池中获取表T
  • 线程A关闭表T
  • 线程B从池中获取表T
  • 线程A再次关闭表T(并且
    HTablePool.PooledHTable.close()
    没有抱怨)
  • 线程B开始使用表T
  • 表T标记为未使用,并且:
    • 池决定表T使用的时间不够长,可以真正关闭
    • 线程C从池中获取表T并开始使用它
  • 我们的解决方案是删除池表上的第二个
    close()
    。不再有
    拒绝执行异常


    如果池表接口已关闭,则为最新HBase,如果已关闭,则不会再次关闭包装的表。它还抛出了一个异常,它仍然不符合Java
    Closeable
    接口,但这是另一回事。

    我建议升级到0.90.3+(+表示HBase的Cloudera风格),看看它是否持续存在。否则,看起来好像您正在尝试在关闭/停止的ExecutorThreadPool中执行线程。查看创建到HBase的Puts的代码会很有帮助。