hbase 学习(十四)Facebook针对hbase的优化方案分析

使用hbase的目的是为了海量数据的随机读写,可是在实际使用中却发现针对随机读的优化和gc是一个很大的问题,并且hbase的数据是存储在Hdfs,而Hdfs是面向流失数据访问进行设计的,就不免带来效率的降低。下面介绍一下Facebook Message系统在HBase online storage场景下的一个案例(《Apache Hadoop Goes Realtime at Facebook》, SIGMOD 2011),最近他们在存储领域顶级会议FAST2014上发表了一篇论文《Analysis of HDFS Under HBase: A Facebook Messages Case Study》分析了他们在使用HBase中遇到的一些问题和解决方案。该论文首先讲了Facebook的分析方法包括tracing/analysis/simulation,FM系统的架构和文件与数据构成等,接下来开始分析FM系统在性能方面的一些问题,并提出了解决方案。 
FM系统的主要读写I/O负载 数据库

 

Figure 2描述了每一层的I/O构成,解释了在FM系统对外请求中读占主导,可是因为logging/compaction/replication/caching致使写被严重放大。apache

  • HBase的设计是分层结构的,依次是DB逻辑层、FS逻辑层、底层系统逻辑层。DB逻辑层提供的对外使用的接口主要操做是put()和get()请求,这两个操做的数据都要写到HDFS上,其中读写比99/1(Figure 2中第一条)。缓存

  • 因为DB逻辑层内部为了保证数据的持久性会作logging,为了读取的高效率会作compaction,并且这两个操做都是写占主导的,因此把这两个操做(overheads)加上以后读写比为79/21(Figure 2中第二条)。网络

  • 至关于调用put()操做向HBase写入的数据都是写入了两份:一份写入内存Memstore而后flush到HFile/HDFS,另外一份经过logging直接写HLog/HDFS。Memstore中积累必定量的数据才会写HFile,这使得压缩比会比较高,而写HLog要求实时append record致使压缩比(HBASE-8155)相对较低,致使写被放大4倍以上。    Compaction操做就是读取小的HFile到内存merge-sorting成大的HFile而后输出,加速HBase读操做。Compaction操做致使写被放大17倍以上,说明每部分数据平均被重复读写了17次,因此对于内容不变的大附件是不适合存储在HBase中的。因为读操做在FM业务中占主要比例,因此加速读操做对业务很是有帮助,因此compaction策略会比较激进。 
    HBase的数据reliable是靠HDFS层保证的,即HDFS的三备份策略。那么也就是上述对HDFS的写操做都会被转化成三倍的local file I/O和两倍的网络I/O。这样使得在本地磁盘I/O中衡量读写比变成了55/45。架构

  • 然而因为对本地磁盘的读操做请求的数据会被本地OS的cache缓存,那么真正的读操做是因为cache miss引发的读操做的I/O量,这样使得读写比变成了36/64,写被进一步放大。    另外Figure 3从I/O数据传输中真正业务需求的数据大小来看各个层次、各个操做引发的I/O变化。除了上面说的,还发现了整个系统最终存储在磁盘上有大量的cold data(占2/3),因此须要支持hot/cold数据分开存储。app

 

总的来讲,HBase stack的logging/compaction/replication/caching会放大写I/O,致使业务逻辑上读为主导的HBase系统在地层实际磁盘I/O中写占据了主导。 
FM系统的主要文件类型和大小 
分布式

FM系统的几种文件类型如Table 2所示,这个是纯业务的逻辑描述。在HBase的每一个RegionServer上的每一个column family对应一个或者多个HFile文件。FM系统中有8个column family,因为每一个column family存储的数据的类型和大小不同,使得每一个column family的读写比是不同的。并且不多数据是读写都会请求的,因此cache all writes可能做用不大(Figure 4)。 
oop

 

对于每一个column family的文件,90%是小于15M的。可是少许的特别大的文件会拉高column family的平均文件大小。例如MessageMeta这个column family的平均文件大小是293M。从这些文件的生命周期来看,大部分FM的数据存储在large,long-lived files,然而大部分文件倒是small, short-lived。这对HDFS的NameNode提出了很大的挑战,由于HDFS设计的初衷是为了存储少许、大文件准备的,全部的文件的元数据是存储在NameNode的内存中的,还有有NameNode federation。 
FM系统的主要I/O访问类型下面从temporal locality, spatial locality, sequentiality的角度来看。 
73.7%的数据只被读取了一次,可是1.1%的数据被读取了至少64次。也就是说只有少部分的数据被重复读取了。可是从触发I/O的角度,只有19%的读操做读取的是只被读取一次的数据,而大部分I/O是读取那些热数据。 
在HDFS这一层,FM读取数据没有表现出sequentiality,也就是说明high-bandwidth, high-latency的机械磁盘不是服务读请求的理想存储介质。并且对数据的读取也没有表现出spatial locality,也就是说I/O预读取也没啥做用。 
解决方案1. Flash/SSD做为cache使用。 
性能

下面就考虑怎么架构可以加速这个系统了。目前Facebook的HBase系统每一个Node挂15块100MB/s带宽、10ms寻址时间的磁盘。Figure 9代表:a)增长磁盘块数有点用;b)增长磁盘带宽没啥大用;c)下降寻址时间很是有用。 
因为少部分一样的数据会被常常读取,因此一个大的cache可以把80%左右的读取操做拦截而不用触发磁盘I/O,并且只有这少部分的hot data须要被cache。那么拿什么样的存储介质作cache呢?Figure 11说明若是拿足够大的Flash作二级缓存,cache命中率会明显提升,同时cache命中率跟内存大小关系并不大。 
注:关于拿Flash/SSD作cache,能够参考HBase BucketBlockCache(HBASE-7404
优化

咱们知道你们比较关心Flash/SSD寿命的问题,在内存和Flash中shuffling数据可以使得最热的数据被交换到内存中,从而提高读性能,可是会下降Flash的寿命,可是随着技术的发展这个问题带来的影响可能愈来愈小。 
说完加速读的cache,接着讨论了Flash做为写buffer是否会带来性能上的提高。因为HDFS写操做只要数据被DataNode成功接收到内存中就保证了持久性(由于三台DataNode同时存储,因此认为从DataNode的内存flush到磁盘的操做不会三个DataNode都失败),因此拿Flash作写buffer不会提升性能。虽然加写buffer会使后台的compaction操做下降他与前台服务的I/O争用,可是会增长很大复杂度,因此仍是不用了。最后他们给出告终论就是拿Flash作写buffer没用。 
而后他们还计算了,在这个存储栈中加入Flash作二级缓存不但能提高性能达3倍之多,并且只须要增长5%的成本,比加内存性价比高不少。 
2.分层架构的缺点和改进方案 

 

如Figure 16所示,通常分布式数据库系统分为三个层次:db layer/replication layer/local layer。这种分层架构的最大优势是简洁清晰,每层各司其职。例如db layer只须要处理DB相关的逻辑,底层的存储认为是available和reliable的。 
HBase是图中a)的架构,数据的冗余replication由HDFS来负责。可是这个带来一个问题就是例如compaction操做会读取多个三备份的小文件到内存merge-sorting成一个三备份的大文件,这个操做只能在其中的一个RS/DN上完成,那么从其余RS/DN上的数据读写都会带来网络传输I/O。 
图中b)的架构就是把replication层放到了DB层的上面,Facebook举的例子是Salus,不过我对这个东西不太熟悉。我认为Cassandra就是这个架构的。这个架构的缺点就是DB层须要处理底层文件系统的问题,还要保证和其余节点的DB层协调一致,太复杂了。 
图中c)的架构是在a的基础上的一种改进,Spark使用的就是这个架构。HBase的compaction操做就能够简化成join和sort这样两个RDD变换。 

Figure 17展现了local compaction的原理,原来的网络I/O的一半转化成了本地磁盘读I/O,并且能够利用读cache加速。咱们都知道在数据密集型计算系统中网络交换机的I/O瓶颈很是大,例如MapReduce Job中Data Shuffle操做就是最耗时的操做,须要强大的网络I/O带宽。加州大学圣迭戈分校(UCSD)微软亚洲研究院(MSRA)都曾经设计专门的数据中心网络拓扑来优化网络I/O负载,相关研究成果在计算机网络顶级会议SIGCOMM上发表了多篇论文,可是因为其对网络路由器的改动伤筋动骨,最后都没有成功推广开来。 

 

Figure 19展现了combined logging的原理。如今HBase的多个RS会向同一个DataNode发送写log请求,而目前DataNode端会把来自这三个RS的log分别写到不一样的文件/块中,会致使该DataNode磁盘seek操做较多(再也不是磁盘顺序I/O,而是随机I/O)。Combined logging就是把来自不一样RS的log写到同一个文件中,这样就把DataNode的随机I/O转化成了顺序I/O。

相关文章
相关标签/搜索