问题
我正在尝试使用 Phoenix 构建二级索引。创建索引需要几个小时。这似乎是由于 HBase 扫描缓慢,因为我注意到以下性能:
我可能需要 2 个小时来扫描表,而其他开发人员报告说对于较大的表(1 亿行)需要几分钟。 HBase shell 能够以大约 1 的频率计算行数。每秒 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 没有交换(检查了 5 个 RS 中的 2 个) IO(network) : 每个节点的主动接口(interface)都站在同一个交换机上(所有第二个被动接口(interface)都插在不同的交换机上)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-site 对 Phoenix 的设置很少 一些对我来说还不错的参数
hbase.hregion.memstore.block.multiplier hbase.hregion.memstore.flush.size:134217728 字节(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(块缓存大小占堆的百分比)最大 HStoreFile (hbase.hregion.max.filesize) : 10 go (10737418240) 客户端扫描器缓存:100 行 zookeeper 超时:30 秒 客户端最大键值大小:10 个月 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.*ERROR"
cat hbase-hbase-regionserver-*.log | grep "2015-05-11.*ERROR"
什么都不打印
打印警告显示不相关的错误
2015-05-11 17:11:10,544 WARN [B.DefaultRpcServer.handler=8,queue=2,port=60020] 短路。ShortCircuitCache:ShortCircuitCache(0x2aca5fca):无法加载 1074749724_BP-71737375173781872到 InvalidToken 异常。
2015-05-11 17:09:12,848 警告 [regionserver60020-smallCompactions-1430754386533] hbase.HBaseConfiguration:配置选项“hbase.regionserver.lease.period”已弃用。相反,使用“hbase.client.scanner.timeout.period”
明白了:关键是将“热”内容与“冷”内容分开到单独的列族中。列族用于将列存储在单独的 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