2019/3/7 星期四

深入探讨hbase写性能优化探讨(20190307)

HBase写数据流程倒是显得很简单:
数据先顺序写入HLog,再写入对应的缓存Memstore,当Memstore中数据大小达到一定阈值(128M)之后,系统会异步将Memstore中数据flush到HDFS形成小文件。

hbase IN_MEMORY hbase in_memory表写入性能有提升吗_数据

HBase数据写入通常会遇到两类问题,
:一类是写性能较差,
:另一类是数据根本写不进去。这两类问题的切入点也不尽相同,

写性能优化切入点(6点):

  1. 是否需要写WAL?WAL是否需要同步写入?
    小结:
    (1)其一,写wal 是为了提高数据的容灾,在写入缓存丢失也可以恢复;其二为了集群之间的异步复制
    (2)默认是开启wal机制并且使用同步机制写入 wal
    (3)对于一些业务场景来说,可以容许一些数据丢失的话,可以关闭wal写人,比如:某些推荐业务 写入吞吐量提高2~3倍
    (4)某些场景是可以考虑到wal异步写入,提高性能1~2倍
  2. Put是否可以同步批量提交?
    小结:
    (1)hbase提供了单个put和批量put的api接口,
    (2)推荐使用批量put 这样可以减少客户端到regionserver之间的prc连接数,提高写的性能
    (3)批量put 要么全部成功返回,要么抛出异常
  3. Put是否可以异步批量提交?
    (1)业务上可以考虑到丢失少量数据,用户提交的数据先在客户端缓存
    (2)当客户端缓存达到阈值(2M),就会批量的提交给rs,在某些情况下客户端异常的情况下缓存数据有可能丢失。
  4. Region是否太少?
    1、当前集群中表的Region个数如果小于RegionServer个数,比如 rs是3个 rg只有1个
    2、这样我们就可以切分rg 让他分不到不同认识中来提高系统的请求并发度
    3、如果Num(Region of Table) > Num(RegionServer),再增加Region个数效果并不明显。
    //这里就是我们所讲到的避免热点问题 详细见链接:
    深度研究hbase的热点问题,和hbase 表rk的设计 和手动分区region
    https://blog.51cto.com/12445535/2352410
  5. 写入请求是否不均衡?
    (1)分布式系统中特别害怕一个节点负载很高的情况,一个节点负载很高可能会拖慢整个集群
    (2)一旦其中一部分请求落到该节点无法得到及时响应,就会导致整个批量请求超时。因此不怕节点宕掉,就怕节点奄奄一息!
    (3)检查RowKey设计以及预分区策略,保证写入请求均衡。
    //其实就是讲到了 hbase的表设计和rowkey设计这块 去避免热点问题
    详细见:
    hbase表设计优化原则(rk设计三原则) ***** 生产环境中使用小结
    https://blog.51cto.com/12445535/2356221
  6. 写入KeyValue数据是否太大?
    (1)keyvalue大小对写入性能的影响很大,kv太大,hbase写入性能底下。
    //说到这里,有必要和大家分享两起在生产线环境因为业务KeyValue较大导致的严重问题,一起是因为大字段业务写入导致其他业务吞吐量急剧下降,另一起是因为大字段业务scan导致RegionServer宕机。

案件一:大字段写入导致其他业务吞吐量急剧下降
部分业务反馈集群写入忽然变慢、数据开始堆积的情况,查看集群表级别的数据读写QPS监控,发现问题的第一个关键点:业务A开始写入之后整个集群其他部分业务写入QPS都几乎断崖式下跌,初步怀疑黑手就是业务A。
//什么是QPS监控
QPS(Questions Per second:):每秒查询处理量,也就是Mysql每秒处理查询数,同时适用于InnoDB和MysqlSAM引擎
//TPS(Transactions Per Second)
每秒处理事务数,简单的来说就是数据库传输事务处理个数,这是指单台数据库服务器在单位时间内处理的事务的个数。 ,支持事务的存储引擎如InnoDB等特性指标
小结:
和业务方沟通之后确认该表主要存储语料库文档信息,都是平均100K左右的数据,是不是已经猜到了结果,没错,就是因为这个业务KeyValue太大导致。KeyValue太大会导致HLog文件写入频繁切换、flush以及compaction频繁触发,写入性能急剧下降。
目前针对这种较大KeyValue写入性能较差的问题还没有直接的解决方案,好在社区已经意识到这个问题,在接下来即将发布的下一个大版本HBase 2.0.0版本会针对该问题进行深入优化,详见HBase MOB,优化后用户使用HBase存储文档、图片等二进制数据都会有极佳的性能体验。

案件二:大字段scan导致RegionServer宕机
查看日志是由于”java.lang.OutOfMemoryError: Requested array size exceeds VM limit”
造成该异常的两种最常见原因分别是:
(1)表列太宽(几十万列或者上百万列),并且scan返回没有对列数量做任何限制,导致一行数据就可能因为包含大量列而数据超过array大小阈值
(2)KeyValue太大,并且scan返回没有对返回结果大小做任何限制,导致返回数据结果大小超过array大小阈值
解决方案:目前针对该异常有两种解决方案,其一是升级集群到1.0,问题都解决了。其二是要求客户端访问的时候对返回结果大小做限制(scan.setMaxResultSize(210241024))、并且对列数量做限制(scan.setBatch(100)),当然,0.98.13版本以后也可以对返回结果大小在服务器端进行限制,设置参数hbase.server.scanner.max.result.size即可

写异常问题检查点
1、Memstore设置是否会触发Region级别或者RegionServer级别flush操作?
问题检查点:
(1)Region规模与Memstore总大小设置是否合理?如果RegionServer上Region较多,而Memstore总大小设置的很小(JVM设置较小或者upper.limit设置较小),就会触发RegionServer级别flush。
(2)列族是否设置过多,通常情况下表列族建议设置在1~3个之间,最好一个。如果设置过多,会导致一个Region中包含很多Memstore,导致更容易触到高水位upperlimit
2、Store中HFile数量是否大于配置参数blockingStoreFile?
问题检查点:
(1)参数设置是否合理?hbase.hstore.compactionThreshold表示启动compaction的最低阈值,该值不能太大,否则会积累太多文件,一般建议设置为5~8左右。hbase.hstore.blockingStoreFiles默认设置为7,可以适当调大一些。
//这些参数在cdh中 hbase.hstore.compactionThreshold 3 hbase.hstore.blockingStoreFiles 10

写性能还能再提高么?
//针对hbase的版本的提升 对 wal进行了很大的优化,比如:
(1)wal单独在ssd上,
(2)当前WAL设计为一个RegionServer上所有Region共享一个WAL,可以想象在写入吞吐量较高的时候必然存在资源竞争,降低整体性能。针对这个问题,社区小伙伴(阿里巴巴大神)提出Multiple WALs机制,管理员可以为每个Namespace下的所有表设置一个共享WAL,通过这种方式,写性能大约可以提升20%~40%左右。

参考链接:
HBase最佳实践-写性能优化策略 http://hbasefly.com/2016/12/10/hbase-parctice-write/zabbix监控Mysql中的QPS/TPS


转载于:https://blog.51cto.com/12445535/2359746