在双十一促销期间,业务发开反馈线上的一个集群的scan性能很差。打开Ambari Grafana监控看了一下rpc性能数据,确实有几个节点的RPC max.process.time响应时间稳定在1s以上。
从开发哪里得知scan请求是按照prefix条件进行的,而该集群是1.1.2老版本集群,没有用到2.x以上的prefix Bloom filter特性。
一、Scan性能异常和排查过程
1)通过开发提供的信息,可以排除热点问题,因为rowkey进过hash,请求也不是相同的。
2)开发按照prefix查询,每次返回100条,我手动手动hbase shell验证,请求时间在3s左右。
scan 't1', { ROWPREFIXFILTER => 'row2', LIMIT => 10 }
3)因为hbase 1.1的slowlog日志很粗糙,没法看具体的执行状态,无法直接定位原因。
4)于是决定去看看数据的分布和locality信息,发布rpc响应时间较长的节点该表region的locality比较低,(恰好该表在该节点只有这个region),怀疑远程读取(remote read)比较消耗性能,对改region手动执行了major compact操作,该节点的RPC max.process.time恢复到50ms一下。
5)但是另外的节点上,数据的locality是1,RPC max.process.time 指标仍然在1s以上,说明hdfs remote read不是问题的根本原因。(磁盘读取量很小,用的SSD存储性能也比较好)
7)这时候想到另外一个东西,major comapct不仅可以提高locality,而且可以合并文件和删除过期和标记为删除状态的数据。之前和开发沟通过程中也了解大盘,数据scan出去之后,会从表中删除该行操作,该表可能会存在大量的删除数据。
8) 手动对整表做了major comapct,磁盘空间从10GB下降到不到800M。之后,业务scan操作恢复正常,没有任何的scan请求超时。
二、关于prefix scan性能思考
在2.0版本之前,prefix scan仅仅是在client scan发送请求时设置一下startRow和stopRow参数,在server端没有任何的更多的处理。
client端的实现比较简单,先按照row的有序性,把prefix scan转化成范围扫描(range scan,[startRow,endRow)闭开区间),减少数据扫描的范围。
转化后startRowkey为prefix,而endRowkey为紧邻prefix的一个字符串。比如prefix为abc,那么stop rowkey为abd;
计算算法如下: