我正在使用 HBase 来存储一些时间序列数据。根据 O'Reilly HBase 书中的建议,我使用的行键是带有盐渍前缀的数据时间戳。为了查询此数据,我生成了多个线程,这些线程实现了对一系列时间戳的扫描,每个线程处理一个特定的前缀。然后将结果放入并发 HashMap 中。
当线程尝试执行扫描时出现问题。如果生成 6 个线程(对应于 6 个盐/区域服务器),串行完成时通常需要大约 5600 毫秒的查询需要 40000 到 80000 毫秒。
我尝试使用 HTablePools 来解决我认为 HTable 不是线程安全的问题,但这并没有带来任何更好的性能。
特别是当我点击我的这部分代码时,我注意到速度明显变慢:
for(Result res : rowScanner){
//add Result To HashMap
通过日志记录,我注意到每次通过循环的条件时,我都会经历许多秒的延迟。如果我强制线程串行执行,则不会发生这些延迟。
我假设资源锁定存在某种问题,但我看不到它。
最佳答案
确保您正在设置 BatchSize和 Caching在您的扫描对象(用于创建扫描仪的对象)上。这些控制一次通过网络传输多少行,以及将多少行保留在内存中以便在 RegionServer 本身上快速检索。默认情况下,它们都太低而效率不高。 BatchSize 尤其会显着提高您的性能。
编辑:根据评论,听起来您可能正在服务器或客户端上进行交换,或者 RegionServer 在 BlockCache 中可能没有足够的空间来满足您的扫描器。你给了 RegionServer 多少堆?您是否检查过它是否正在交换?参见 How to find out which processes are swapping in linux? .
此外,您可能希望减少并行扫描的数量,并使每个扫描器读取更多行。我发现在我的集群上,并行扫描几乎没有比串行扫描有任何改进,因为我受网络限制。 如果您正在最大化您的网络,并行扫描实际上会使事情变得更糟。
关于java - HBase多线程扫描真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8932885/