【编者按】HBase,Google BigTable的开源实现,也是Hadoop的原生组件之一。基于HDFS,HBase提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统。虽然有着高贵的血统,但是HBase中存在的问题也不容忽视,比如前文所说的一些工程问题。近日@DataScientist对HBase在2013年的发展进行了回顾,总结了其中最值得关注的几个方面,并分享了一些实践经验。以下为原文: 2013年马上就要过去了,总结下这一年HBase在这么一年中发生的主要变化。影响最大的事件就是HBase 0.96的发布,代码结构已经按照模块化发布了,而且提供了许多大家迫切需求的特点。这些特点大多在Yahoo!/Facebook/淘宝/小米等公司内 部的集群中跑了挺长时间了,可以算是比较稳定可用了。 1. Compaction优化HBase的Compaction是长期以来广受诟病的一个特性,很多人吐槽HBase也是因为这个特征。不过我们不能因为HBase有这样一个缺 点就把它一棒子打死,更多的还是希望能够驯服它,能够使得它适应自己的应用场景。根据业务负载类型调整Compaction的类型和参数,一般在业务高峰 时候禁掉Major Compaction。在0.96中HBase社区为了提供更多的Compaction的策略适用于不同的应用场景,采用了插件式的架构。同时改进了 HBase在RegionServer端的存储管理,原来是直接Region->Store->StoreFile,现在为了支持更加灵活多 样的管理StoreFile和Compact的策略,RS端采用了StoreEngine的结构。一个StoreEngine涉及到 StoreFlusher、CompactionPolicy、Compactor、StoreFileManager。不指定的话默认是 DefaultStoreEngine,四个组件分别是DefaultStoreFlusher, ExploringCompactionPolicy、DefaultCompactor、DefaultStoreFileManager。可以看出在 0.96版之后,默认的Compaction算法从RatioBasedCompactionPolicy改为了 ExploringCompactionPolicy。为什么要这么改,首先从Compaction的优化目标来看:compaction is about trading some disk IO now for fewer seeks later,也就是Compaction的优化目标是执行Compaction操作能合并越多的文件越好,如果合并同样多的文件产生的IO越小越好,这样 select出来的列表才是最优的。 主要不同在于:
关于这两个算法的逻辑可以在代码中参考对应的applyCompactionPolicy()函数。其他CompactionPolicy的研究和开发也非常活跃,例如Tier-based compaction(HBASE-6371,来自Facebook)和stripe compaction(HBASE-7667) 吐槽:HBase Compaction为什么会问题这么多,我感觉缺少了一个整体的IO负载的反馈和调度机制。因为Compaction是从HDFS读数据,然后再写到 HDFS中,和其他HDFS上的负载一样在抢占IO资源。如果能有个IO资源管理和调度的机制,在HDFS负载轻的时候执行Compaction,在负载 重的时候不要执行。而且这个问题在Hadoop/HDFS里同样存在,Hadoop的资源管理目前只针对CPU/Memory的资源管理,没有对IO的资 源管理,会导致有些Job受自己程序bug的影响可能会写大量的数据到HDFS,会严重影响其他正常Job的读写性能。 更多内容:HBase Compaction、HBase 2013 Compaction 提升。 2. Mean Time To Recovery/MTTR优化 目前HBase对外提供服务,Region Server是单点。如果某台RS挂掉,那么直到该RS上的所有Region被重新分配到其他RS上之前,这些Region是的数据是无法访问的。对这个过程的改进主要包括:
3. Bucket Cache (L2 cache on HBase)HBase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写;另外一部分作为BlockCache,主要用 于读。Block的cache命中率对HBase的读性能影响十分大。目前默认的是LruBlockCache,直接使用JVM的HashMap来管理 BlockCache,会有Heap碎片和Full GC的问题。 HBASE-7404引入Bucket Cache的概念可以放在内存中,也可以放在像SSD这样的适合高速随机读的外存储设备上,这样使得缓存的空间可以非常大,可以显著提高HBase读性能。Bucket Cache的本质是让HBase自己来管理内存资源而不是让Java的GC来管理,这个特点也是HBase自从诞生以来一直在激烈讨论的问题。 4. Java GC改进MemStore-Local Allocation Buffers通过预先分配内存块的方式解决了因为内存碎片造成的Full GC问题,但是对于频繁更新操作的时候,MemStore被flush到文件系统时没有reference的chunk还是会触发很多的Young GC。所以HBase-8163提出了MemStoreChunkPool的概念,也就是由HBase来管理一个ChunkPool用来存放chunk, 不再依赖JVM的GC。这个ticket的本质也是由HBase进程来管理内存分配和重分配,不再依赖于Java GC。 |