网易视频云:HBase最佳实践-列族设计优化
网易视频云是网易倾力打造的一款基于云计算的分布式多媒体处理集群和专业音视频技术,为客户提供稳定流畅、低时延、高并发的视频直播、录制、存储、转码及盼内溲铫点播等音视频的PaaS服务。在线教育、远程医疗、娱乐秀场、在线金融等各行业及企业用户只需经过简单的开发即可打造在线音视频平台。现在,网易视频云与大家分享一下HBase最佳实践-列族设计优化。
随着大数据的越来越普及,HBase也变得越来越流行。会用HBase现在已经变的并不困难,然而,怎么把它用的更好却并不简单。那怎么定义‘用的好’呢?很简单,在保证系统稳定性、可用性的基础上能够用最少的系统资源(CPU,IO等)获得最好的性能(吞吐量,读写延迟)就是’用的好’。HBase是一个庞大的体系,涉及到很多方面,很多因素都会影响到系统性能和系统资源使用率,根据场景对这些配置进行优化会很大程度上提升系统的性能。笔者总结至少有如下几个方面:HDFS相关配置优化,HBase服务器端优化(GC优化、Compaction优化、硬件配置优化),列族设计优化,客户端优化等,其中客户端优化在前面已经通过超时机制、重试机制讲过,后面笔者会继续分别介绍其他三个优化重点。
本节重点介绍列族设计优化,HBase中基本属性都是以列族为单位进行设置的,如下示例,用户创建了一张称为‘ NewsClickFeedback’的表,表中只有一个列族’Toutiao’,紧接着的属性都是对此列族进行的设置。这些属性基本都会或多或少地影响该表的读写性能,但有些属性用户只需要理解其意义就知道如何设置,而有些属性却需要根据场景、根据业务来设置,比如BLOCKSIZE属性在不同场景下应该如何设置?还有COMPRESSION属性和DATA_BLOCK_ENCODING属性,两者都可以提供压缩功能,那到底应该选择哪个,还是两个都需要进行设置?本文就重点介绍这三个属性的设计原则。
随着BlockSize的增大,系统随机读的吞吐量不断降低,延迟不断增大。64K大小比16K大小的吞吐量大约降低13%,延迟增大13%。同样的,128K大小比64K大小的吞吐量降低约22%,延迟增大27%。因此,对于以随机读为主的业务,可以适当调低BlockSize的大小,以获得更好的读性能。
从上面输出的信息可以看出,该HFile的平均键值对规模为62B + 93B = 155B,相对较小,在这种情况下可以适当将块大小调小(例如32KB)。这样可以使得一个block内不会有太多kv,kv太多会增大块内寻址的延迟时间,因为HBase在读数据时,一个block内部的查找是顺序查找。
注意:默认块大小适用于多种数据使用模式,调整块大小是比较高级的操作。配置错误将对性能产生负面影响。因此建议在调整之后进行测试,根据测试结果决定是否可以线上使用。
数据编码/压缩
Compress/DeCompress
数据压缩是HBase提供的另一个特性,HBase在写入数据块到HDFS之前会首先对数据块进行压缩,再落盘,从而可以减少磁盘空间使用量。而在读数据的时候首先从HDFS中加载出block块之后进行解压缩,然后再缓存到BlockCache,最后返回给用户。写路径和读路径分别如下:
综合来看,Snappy的压缩率最低,但是编解码速率最高,对CPU的消耗也最小,目前一般建议使用Snappy。
Encode/Decode
除了数据压缩之外,HBase还提供了数据编码功能。和压缩一样,数据在落盘之前首先会对KV数据进行编码;但又和压缩不同,数据块在缓存前并没有执行解码,因此即使后续命中缓存的查询也是编码的数据块,需要解码后才能获取到具体的KV数据。写路径和读路径分别如下:
可见,prefix_tree压缩算法在不同的block size下性能都比较稳定,而另外两种压缩算法的查找性能会随着blocksize直线下降。对于我们默认的64K的block大小,性能相差40+倍。另外,阿里天梧大牛之前在一篇博文里面做过测试证明了PREFIX_TREE算法的优越性,见《HBase-0.96中新BlockEncoding算法-PREFIX_TREE压缩的初步探究及测试》,因此一般建议使用PREFIX_TREE编码压缩。
选择哪一个?Why?
综上上面分析,数据压缩和数据编码使命基本相同:消耗CPU资源压缩数据大小,可以认为是一种时间换空间的做法。但,同时开启两个功能会不会更好?如果只需要开启一个,优先选择哪一个?
为了更加深刻地认识数据压缩编码,回答上面两个问题,本人在测试环境使用YCSB做了一个简单的测试,分别在四种场景下(无压缩无编码、仅压缩、仅编码、既压缩既编码)对随机读以及扫描读的操作延时、CPU使用率以及对应的压缩率进行了测试。
测试条件:
数据:6000w条记录,一个列族,每个列族10个列,单条记录总共1K大小;
硬件:单RegionServer,3G BlockCache,CPU:32 Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
测试结果:
结果分析:
1. 数据压缩率并没有理论上0.2那么高,只有0.7左右,这和数据结构有关系。其中压缩、编码、压缩+编码三种方式的压缩率基本相当。
2. 随机读场景:和默认配置相比,snappy压缩在性能上没有提升,CPU开销却上升了38%;prefix_tree性能上没有提升,CPU利用率也基本相当;snappy+prefix_tree性能没有提升,CPU开销上升了38%。
3. 区间扫描场景:和默认配置相比,snappy压缩在性能上略有10%的提升,但是CPU开销却上升了23%;prefix_tree性能上略有4%左右的下降,但是CPU开销也下降了5%;
snappy+prefix_tree在性能上基本没有提升,CPU开销却上升了23%;
设计原则:
1. 在任何场景下开启prefix_tree编码都是安全的
2. 在任何场景下都不要同时开启snappy压缩和prefix_tree编码
3. 通常情况下snappy压缩并不能比prefix_tree编码获得更好的优化结果,如果需要使用snappy需要针对业务数据进行实际测试
到此为止,本文主要介绍了HBase的一个优化方向:列族设计优化。其中重点介绍了BlockSize在不同场景下对读写性能的影响,以及Compress与Data_Block_Encoding的设计原则。希望看官能够根据上述对HBase的列族优化有一个更好的认识,并且能够更多地通过测试来巩固认知。需要说明的是,这里的设计原则对大多数应用业务都是有效的,也有可能对于某些特殊场景并不适用,因此对于比较敏感的业务,还是以实际测试为准。