HBase扫描很慢

时间:2015-05-06 12:28:10

标签: hbase phoenix

问题

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

  • 我可能需要2个小时来扫描表格,而其他开发人员报告了几分钟更大的表格(1亿行)。
  • HBase shell能够计算大约的行数。速率为每秒10.000,即3800s(> 1小时!)来计算该表的所有行。

使用HBase shell和Java扫描程序。

注意:GET(通过rowkey)操作实现了良好的性能(约0.5秒)。

上下文

  • 38百万行/ 1000列/单列系列/ 96Go,带GZ压缩。
  • 群集有6个节点(126个RAM,24个核心)和5个区域服务器。
  • Hortonworks Data Platform 2.2.0

疑难解答

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

1)硬件

  • IO(磁盘)的
    • NMon表示磁盘永远不会超过80%,最常见的是0到20%
    • Top说HBase JVM没有交换(检查5个RS中的2个)
  • IO(网络):每个节点活动接口站在同一个交换机上(所有第二个被动接口都插在不同的交换机上)

2)JVM

  • GC暂停OK(每分钟左右暂停几毫秒)
  • 堆看起来不错(在极限附近没有达到峰值)
  • CPU令人惊讶地低:从不超过10%
  • 主题:
    • 活动线程(10" RpServe.reader = N" +其他几个)显示没有争用
    • 许多停放的线程什么都不做(60" DefaultRpcServer.handler = n",大约15个其他)
    • 没有任何线程状态的巨大IPC客户端列表

3)数据

  • 使用Hive + completebulkload进行批量加载。
  • 地区数量:
    • 13个区域意味着每个RS有2到3个大区域,这是预期的。
    • 强制进行重大压缩后,扫描性能保持不变。
    • 区域大小相当同质:11个区域为4,5Go(+/- 0.5),2个区域为2,5Go

4)HBase配置

  • 大多数配置保持不变。

    • HBase env仅指示JMX控制台的端口
    • HBase-site的Phoenix设置很少
  • 对我来说看起来不错的一些参数

    • hbase.hregion.memstore.block.multiplier
    • hbase.hregion.memstore.flush.size:134217728 bytes(134Go)
    • Xmx的Xmn比率:.2 Xmn最大值:512 Mb Xms:6144m
    • hbase.regionserver.global.memstore.lowerLimit:0.38
    • hbase.hstore.compactionTreshold:3
    • hfile.block.cache.size:0.4(阻止缓存大小占堆的AS%)
    • 最大HStoreFile(hbase.hregion.max.filesize):10 go(10737418240)
    • 客户端扫描程序缓存:100行zookeeper超时:30秒
    • 客户端最大键值大小:10mo
    • hbase.regionserver.global.memstore.lowerLimit:0.38
    • hbase.regionserver.global.memstore.upperLimit:0.40
    • hstore blocking storefiles:10
    • hbase.hregion.memstore.mslab.enabled:
    • 启用hbase.hregion.majorcompaction.jitter:0.5
  • 尝试了以下配置更改而不会对性能产生任何影响

    • hbase-env.sh:尝试增加HBASE_HEAPSIZE = 6144(因为它默认为1000)
    • hbase-site.xml:
      • hbase.ipc.server.callqueue.read.ratio:0.9
      • hbase.ipc.server.callqueue.scan.ratio:0.9

5)日志没有任何用处

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 WARN [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 WARN [regionserver60020-smallCompactions-1430754386533] hbase.HBaseConfiguration:Config option" hbase.regionserver.lease.period"已弃用。相反,请使用" hbase.client.scanner.timeout.period"

2 个答案:

答案 0 :(得分:3)

知道了:关键是将“热门”内容与“冷”内容分成不同的列族。列族用于在不同的HFile中存储列,因此我们可以将一个列族用于索引(或频繁读取)列,并将另一列列族(因此文件)用于所有其他列。

第一步:查看较小的列系列扫描速度更快

我们只是丢弃冷含量来构建一个较小的列系列(1655列 - > 7列)。

中型桌面扫描的表现:

  • [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,但可以单独生成HFile:

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');

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

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

答案 1 :(得分:2)

  • 扫描时的TurnOff blockcache(它正在搅拌你的堆内存)

  • 弄清楚你的记录大小是什么,如果它的> 1 MB,请增加hbase.scanner.timeout期间scan.setCacheBlocks(false);

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

  • 进行一些必要的检查:确保正在扫描的Tabled的区域在各个区域中均匀分布。

(如果你已完成批量加载,则运行一次主要压缩)