天天看点

提高HBase WAL写入性能

问题描述:

      HBase在集成其它组件,作为存储引擎完成组合服务时,往往是数据先写入HBase,然后对数据进行检索,之后数据通过网络传输给目标服务。HBase与组件之间的数据一致性使用WAL来保证。WAL是一种常用的保证数据可靠写入的一种技术,全称为Write-Ahead-Log,就是在向客户端返回写成功前,先将写操作在WAL中记录下来。这样即便系统在数据写入的过程中出现宕机等情况,也可以通过WAL来恢复数据。

      WAL虽然保证了数据的写入安全,但是同样引入了问题即:系统写入性能,可以看出WAL是系统写入性能的一个瓶颈。如何解决该问题以提高写入性能呢?下面是个人的两个想法,实践证明可明显提高写入性能。

问题分析与解决

       我们知道WAL是对HBase的每一次数据变更操作进行记录(只记录变更行的键值),该操作涉及到HDFS的flush操作,HDFS的flush操作会确保数据被写入对应的DataNode中,这个操作需要进行2次网络连接(第一次连接NameNode确定要写入的DataNode队列,第二次连接DataNode发送数据),比较耗时,会严重影响HBase的写入性能。

       通过分析HBase的写入过程,可以发现,HBase本身的WAL已经记录了最近写入而没有持久化的数据,只要保证HBase将数据刷入(flush)磁盘时,将HBase与其它组件的WAL写入HDFS,就可以保证HBase与组件之间的一致性。因此,可以考虑异步提交HBase-组件操作,如下所示:

  • 后台线程异步定时将WAL从内存刷入到HDFS中 ,防止日志过多;
  • 当Region进行flush时,在flush之前(此时已经确定了flush的记录集),将WAL全部输入HDFS(刷入失败,Region Flush操作终止) ;
  • Region WAL回放时,重做所有callback行的记录。

      通过异步策略是可以提高WAL的写入效率的,但是,当并发较大时,性能明显下降,这是因为对于同一台RegionServer,所有的WAL记录在flush之前都放在同一个队列中,队列的并发性能对WAL的写性能会有较大影响,因此,参照MapReduce分区思路,使用Hash值将写入的WAL记录进行分区,Hash%N(N为队列数)相同的记录被写入同一个队列中,不同队列之间没有竞争关系,从而降低了竞争的强度。

总结

      通过异步提交策略和Hash分区队列的方式降低了HBase WAL对HBase写入性能的影响。

继续阅读