1 是否需要写WAL,WAL是否需要同步写入
优化原理:数据写入流程可以理解为一次顺序写WAL
(HLog
)加上一次写缓存(MemStore
),通常情况下写缓存延迟很低,因此提升写性能就只能从WAL
入手。WAL
机制一方面是为了确保数据即使写入缓存丢失也可以恢复,另一方面是为了集群之间异步复制。默认WAL
机制开启且使用同步机制写入WAL
。首先考虑业务是否需要写WAL
,通常情况下大多数业务都会开启WAL
机制(默认),但是对于部分业务可能并不特别关心异常情况下部分数据的丢失,而更关心数据写入吞吐量,比如某些推荐业务,这类业务即使丢失一部分用户行为数据可能对推荐结果并不构成很大影响,但是对于写入吞吐量要求很高,不能造成数据队列阻塞。这种场景下可以考虑关闭WAL
写入,写入吞吐量可以提升2x~3x
。退而求其次,有些业务不能接受不写WAL
,但可以接受WAL
异步写入,也是可以考虑优化的,通常也会带来1x~2x
的性能提升。
优化推荐:根据业务关注点在WAL
机制与写入吞吐量之间做出选择
2 批量Put提交
优化原理:HBase
分别提供了单条put
以及批量put
的API
接口,使用批量put
接口可以减少客户端到RegionServer
之间的RPC
连接数,提高写入性能。另外需要注意的是,批量put
请求要么全部成功返回,要么抛出异常。
优化建议:使用批量put
进行写入请求
3. 异步批量Put提交
优化原理:业务如果可以接受异常情况下少量数据丢失的话,还可以使用异步批量提交的方式提交请求。提交分为两阶段执行,用户提交写请求之后,数据会写入客户端缓存,并返回用户写入成功;当客户端缓存达到阈值(默认2M
)之后批量提交给RegionServer
。需要注意的是,在某些情况下客户端异常的情况下缓存数据有可能丢失。
优化建议:在业务可以接受的情况下开启异步批量提交
使用方式:setAutoFlush(false)
4. Region个数调整
优化原理:当前集群中表的Region
个数如果小于RegionServer
个数,即Num(Region of Table) < Num(RegionServer)
,可以考虑切分Region
并尽可能分布到不同RegionServer
来提高系统请求并发度,如果Num(Region of Table) > Num(RegionServer)
,再增加Region
个数效果并不明显。
优化建议:在Num(Region of Table) < Num(RegionServer)
的场景下切分部分请求负载高的Region
并迁移到其他RegionServer
;
5. 写请求均衡
优化原理:另一个需要考虑的问题是写入请求是否均衡,如果不均衡,一方面会导致系统并发度较低,另一方面也有可能造成部分节点负载很高,进而影响其他业务。分布式系统中特别害怕一个节点负载很高的情况,一个节点负载很高可能会拖慢整个集群,这是因为很多业务会使用Mutli批量提交读写请求,一旦其中一部分请求落到该节点无法得到及时响应,就会导致整个批量请求超时。因此不怕节点宕掉,就怕节点奄奄一息!
优化建议:检查rowkey
设计以及预分区策略,保证写入请求均衡。
6. 写入KeyValue数据是否太大
KeyValue
大小对写入性能的影响巨大,一旦遇到写入性能比较差的情况,需要考虑是否由于写入KeyValue
数据太大导致。随着单行数据大小不断变大,写入吞吐量急剧下降,写入延迟在100K
之后会急剧增大。
7. Utilize Flash storage for WAL(HBASE-12848)
这个特性意味着可以将WAL
单独置于SSD
上,这样即使在默认情况下(WALSync
),写性能也会有很大的提升。需要注意的是,该特性建立在HDFS 2.6.0+
的基础上,HDFS
以前版本不支持该特性。具体可以参考官方HBASE-12848。
8. Multiple WALs(HBASE-14457)
该特性也是对WAL
进行改造,当前WAL
设计为一个RegionServer
上所有Region
共享一个WAL
,可以想象在写入吞吐量较高的时候必然存在资源竞争,降低整体性能。针对这个问题,社区小伙伴提出Multiple WALs
机制,管理员可以为每个Namespace
下的所有表设置一个共享WAL
,通过这种方式,写性能大约可以提升20%~40%
左右。具体可以参考官方HBASE-14457。