本文总结了过去一段时间我们对HBase稳定性的建设工作,想要对服务进行全方位的了解,保证稳定性,对服务性能进行优化,势必要对服务中每个环节都了如指掌。并且当请求量大影响服务稳定的时候,对请求量能够进行控制。同时,稳定性建设的成果,如监控可视化、集群性能数据分析等,也大大提升了我们对业务优化,协助业务降低成本,提升服务使用率提供了极大的帮助。
HBase服务涉及到很多组件:HMaster、RegionServer、ThriftServer。使用Phoenix的话,还涉及到QueryServer。以及ThrfitServer和QueryServer上层的HAproxy。
下面将逐一阐述。
这里给出一个简单的HBase相关组件的说明图
1.HBase Audit Log(审计日志)
统计内容:
HBase原生Audit log记录了一些简单的Rpc信息,例如,客户端的版本,ip等基本信息
改进:
通过解析Rpc的信息,获取请求类型,大小,请求表信息,region信息等
解决问题:
以前用户反馈请求慢,经常找不到哪些表导致服务压力大,而后我们通过增加审计日志中的信息,
可以通过审计日志轻松了解到具体什么表,region,什么类型的操作导致
2.监控
HBase原生有很多监控项,但是页面上只有基本的每秒请求次数这样的信息,这种粒度和维度的统计对于我们来说比较粗犷。
其他监控信息需要通过jmx,sinker等方式获取。目前我们已经可以统计到region级别的请求量,P99等监控数据。
有了丰富的监控数据,我们可以对性能数据进行分析,及时找到需要资源紧张的业务,找到资源利用率低的业务,为业务优化提供数据支撑。
源码改造:
- 解决HBase metric信息统计导致死锁的问题,将社区patch合入滴滴内部HBase
- 解决了Scan语义的问题,将社区patch合入滴滴内部HBase
思考:
目前社区的metric语义根据版本升级在不断变化和新增的
其实HBase中有一些我们需要的统计维度还待开发,也是我们深入了解HBase的抓手之一
3.ThriftServer metric & audit log
例如,Python请求HBase表的请求链路如下
用户通过thrift api访问HAproxy将请求分发到具体的ThriftServer实例,
ThriftServer将请求的TPut、TScan等操作转为HBase的java api,进行HBase集群的实际访问
我们采集了ThriftServer的请求次数,请求P99等信息
改进:
之前经常遇到ThriftServer线程池满的情况
因此,我们调整了线程池大小,ThriftServer的JVM参数
随着HBase用户越来越多,使用一段时间之后,最近我们发现一些ThriftServer gc的问题,正在通过探针程序,和调整参数解决
新增特性:
在ThriftServer源码中,增加了线程池的统计信息
4.QueryServer metric
QueryServer的角色和ThriftServer类似,不同之处在于QueryServer是用来处理Phoenix表的请求的
改进:
增加请求量、请求p99的metric
后期计划:
增加类似audit log的统计功能
5.HAproxy session优化
HAproxy是一个做负载均衡的工具,当我们有多个ThriftServer、QueryServer实例的时候,多个实例上面需要假设HAproxy来处理用户的请求
将服务尽量均衡分布到后面的实例上。之前的情况是因为有些请求要请求两次,比如thriftServer的长scan操作,需要先获取scanid,然后再通过scanid获取数据
为了将一个请求每次的交互信息都打到同一个实例上,我们将HAproxy的映射策略,设置为按用户端ip映射到具体实例。
因此存在一个问题就是当用户只有一个ip有很大请求量,请求ThriftServer的时候,这个ip发出的请求量都落到同一个ThriftServer实例上面了。
改进:
将ThriftServer请求按session进行分配,这样一个客户端ip请求过来的时候,同一个ip不同session的请求会打到不同的实例上,分散请求压力。
后期计划:
将QueryServer请求也按session分配进行测试并上线,解决QueryServer请求热点的问题
6.Quota建设
首先,任何DB都是在有限资源上构建起来的。不能无尽的使用,前面内容阐述了各种对请求量统计的metric,
但是当请求量大的时候,没有有效的控制手段,统计再多信息也是没用的。需要有有效的手段对异常请求进行限制。
集群资源有限的情况下,如何保证业务之间的影响降为最小?如何保证服务不会被大的请求压垮?
Quota功能就是通过设置用户、表、NameSpace等维度每秒请求次数,请求大小,来对请求量进行限制的。
因此,我们将社区的Quota功能合并进了DIDI内部版HBase。
社区patch
https://issues.apache.org/jira/browse/HBASE-11598
在此patch基础上,我们进行了如下改进
- 按类型取消quota的限制
- 并修复Cell 为null的bug
并且,通过对社区版Quota功能的深度使用,我们发现Quota功能还有更多可以改进的地方
后续我们将增加更多Quota语义、类别处理的支持
7.探索OpenTSDB的优化空间
OpenTSDB是我们目前监控数据的存储引擎,可以通过http写入,与Grafana轻松对接实现可视化。
因此我们很关注OpenTSDB的写入和查询效率。
改进:
关闭了对TSDB的元数据的频繁更新,当元数据有变动时手动更新,使得OpenTSDB元数据表每秒十几万次请求降为每秒几次请求。
调整了OpenTSDB的compact参数,避免compact短时间将RegionServer压力拉至很高。
后期优化:
openTSDB compaction 通过HBase的compaction来做,而不是通过读出数据,再重新put数据,delete数据解决
openTSDB rowkey设计优化