HBase 扫描很慢

HBase scans are slow

问题

我正在尝试使用 Phoenix 构建二级索引。索引创建需要几个小时。这似乎是由于 HBase 扫描速度慢,因为我注意到以下性能:

同时使用 HBase shell 和 Java 扫描器。

注意:GET(by rowkey) 操作以良好的性能实现(大约 0.5s)。


上下文


疑难解答

基于 HBase 书籍 (http://hbase.apache.org/book.html#performance),这是我已经检查过的内容:

1) 硬件

2) JVM

3) 数据

4) HBase 配置

5) log say nothing usefull

cat hbase-hbase-master-cox.log | grep "2015-05-11.*错误"

cat hbase-hbase-regionserver-*.log | grep "2015-05-11.*错误"

什么都不打印

打印 WARN 显示不相关的错误

2015-05-11 17:11:10,544 警告 [B.DefaultRpcServer.handler=8,queue=2,port=60020] shortcircuit.ShortCircuitCache: ShortCircuitCache(0x2aca5fca): 无法加载 1074749724_BP-2077371184-184.10.17.65-1423758745093 由于 InvalidToken 异常。

2015-05-11 17:09:12,848 警告 [regionserver60020-smallCompactions-1430754386533] hbase.HBaseConfiguration: 配置选项 "hbase.regionserver.lease.period" 已弃用。相反,使用 "hbase.client.scanner.timeout.period"

  • 在扫描时关闭块缓存(它正在搅动你的堆内存)

  • 找出你的记录的大小,如果它 > 1 MB,请增加 hbase.scanner.timeout 句点 scan.setCacheBlocks(false);

  • scan.setCaching(x) x * 记录大小在一个短片中获取的内容,确保它接近 1 MB。

  • 一些必要的检查:确保被扫描的 Tabled 区域在各个区域之间均匀分布。

(如果你已经完成批量加载 运行 一次主要压实)

明白了:关键是要将 "hot" 内容与 "cold" 内容分开到单独的列族中。列族用于将列存储在单独的 HFile 中,因此我们可以将一个列族用于索引(或经常读取)列,将另一个列族(即文件)用于所有其他列。

第一步:了解较小的列族扫描速度更快

我们只是丢弃冷内容来构建一个较小的列族(1655 列 -> 7 列)。

中等规模 table 扫描的表现:

  • [37.876.602 行,1655 列] 扫描 1000 行耗时 39.4750
  • [76.611.463行,7列]扫描1000行耗时1.8620

备注:

  • 我们扫描前 1000 行时可以忽略总行数
  • 从 Hbase 扫描时大行会产生开销 shell 在控制台中打印内容

第二步:生成多族HTable

我们通过从 Hive 生成​​ HFile 来进行批量加载。虽然文档说 we can't generate one multi family table,但可以单独生成 HFiles:

create table mytable_f1 (UUID string, source_col1, source_col2)
...
TBLPROPERTIES('hfile.family.path' = 'tmp/mytable/**f1**');

create table mytable_f1 (UUID string, source_col3, source_col4)
...
TBLPROPERTIES('hfile.family.path' = 'tmp/mytable/f2');

然后像往常一样简单地调用导入命令:

hadoop jar [hbase-server-jar] completebulkload /tmp/mytable mytable