【问题标题】:HBase scans are slowHBase 扫描很慢
【发布时间】:2015-07-16 14:10:43
【问题描述】:

问题

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

  • 我可能需要 2 小时来扫描表,而其他开发人员报告说扫描较大的表(1 亿行)需要几分钟。
  • HBase shell 能够以大约 .每秒 10.000 的速率,这意味着需要 3800 秒(>1 小时!)来计算此表的所有行。

都带有 HBase shell 和 Java 扫描器。

注意:GET(by rowkey) 操作具有良好的性能(大约 0.5 秒)。


上下文

  • 3800 万行/1000 列/单列族/96Go,GZ 压缩。
  • 集群有 6 个节点(126Go RAM,24 个核心)和 5 个区域服务器。
  • Hortonworks 数据平台 2.2.0

疑难解答

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

1) 硬件

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

2) 虚拟机

  • GC 暂停正常(每分钟左右暂停几毫秒)
  • 堆看起来没问题(接近极限的峰值没有太长)
  • 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 站点对 Phoenix 的设置很少
  • 一些对我来说看起来不错的参数

    • hbase.hregion.memstore.block.multiplier
    • hbase.hregion.memstore.flush.size : 134217728 字节 (134Go)
    • Xmx 的 Xmn 比率:0.2 Xmn 最大值:512 Mb Xms:6144m
    • hbase.regionserver.global.memstore.lowerLimit : 0.38
    • hbase.hstore.compactionTreshold : 3
    • hfile.block.cache.size : 0.4(块缓存大小占堆的百分比)
    • 最大 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 阻塞存储文件: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.*错误"

什么都不打印

打印警告显示不相关的错误

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:配置选项“hbase.regionserver.lease.period”已弃用。相反,使用“hbase.client.scanner.timeout.period”

【问题讨论】:

    标签: hbase phoenix


    【解决方案1】:
    • 在扫描时关闭块缓存(它正在搅动你的堆内存)

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

    • scan.setCaching(x) x * 记录大小短时间获取的内容,确保它接近 1 MB。

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

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

    【讨论】:

    • 谢谢。我已经尝试了您的建议而没有影响(关闭块缓存,将缓存设置为 10.000.000,已验证的记录由带有小字符串(
    【解决方案2】:

    知道了:关键是将“热”内容与“冷”内容分离到单独的列族中。列族用于将列存储在单独的 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,但可以单独生成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
    

    【讨论】:

      猜你喜欢
      • 2018-05-11
      • 2014-04-27
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多