本套系列博客从真实商业环境抽取案例进行总结和分享,并给出Spark商业应用实战指导,请持续关注本套博客。版权声明:本套Spark商业应用实战归做者(秦凯新)全部,禁止转载,欢迎学习。shell
Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的状况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正由于Hbase良好的扩展性,才为海量数据的存储提供了便利。根据Google的Chang等人发表的论文数据库
Bigtable:A Distributed Storage System for Strctured Data
复制代码
来设计的。整体架构以下:架构
2010年5月,Hbase从Hadoop子项目升级成Apache顶级项目。简而言之:HBase是一个经过大量廉价的机器解决海量数据的高速存储和读取的分布式数据库解决方案。一图归纳以下所示:并发
MemStore 实际上是一种内存结构,一个Column Family 对应一个MemStore 分布式
第1步:client请求ZK得到-ROOT-所在的RegionServer地址高并发
第2步:client请求-ROOT-所在的RS地址,获取.META.表的地址,client会将-ROOT-的相关信息cache下来,以便下一次快速访问oop
第3步:client请求 .META.表的RS地址,获取访问数据所在RegionServer的地址,client会将.META.的相关信息cache下来,以便下一次快速访问post
第4步:client请求访问数据所在RegionServer的地址,获取对应的数据性能
第1步:Client请求ZK获取.META.所在的RegionServer的地址。学习
第2步:Client请求.META.所在的RegionServer获取访问数据所在的RegionServer地址,client会将.META.的相关信息cache下来,以便下一次快速访问。
第3步:Client请求数据所在的RegionServer,获取所须要的数据。
其一:提升性能
其二:2层结构已经足以知足集群的需求
Compaction会从一个region的一个store中选择一些hfile文件进行合并。合并说来原理很简单,先从这些待合并的数据文件中读出KeyValues,再按照由小到大排列后写入一个新的文件中。以后,这个新生成的文件就会取代以前待合并的全部文件对外提供服务。HBase根据合并规模将Compaction分为了两类:MinorCompaction和MajorCompaction
Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程当中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少而且更大的StoreFile。
Major Compaction是指将全部的StoreFile合并成一个StoreFile,这个过程还会清理三类无心义数据:被删除的数据、TTL过时数据、版本号超过设定版本号的数据。另外,通常状况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。所以线上业务都会将关闭自动触发Major Compaction功能,改成手动在业务低峰期触发。
下列三个条件可能会触发compaction请求:
memstore flush以后触发;
客户端经过shell或者API触发;
后台线程CompactionChecker按期触发,周期为:
hbase.server.thread.wakefrequency*hbase.server.compactchecker.interval.multiplier。
复制代码
对于MajorCompact,触发了compaction请求后,真正的compaction操做可否执行,还要进行一系列的条件验证, 即由hbase.hregion.majorcompaction和hbase.hregion.majorcompaction.jitter控制的一组条件。
对于MiniCompact当文件大小小于hbase.hstore.compaction.min.size 则会当即被添加到合并队列,当storeFile数量超过hbase.hstore.compaction.min时,minor compaction才会启动。
hbase.hregion.memstore.flush.size:640M
hbase.hregion.max.filesize :100M 触发split
hbase.hstore.compaction.min : 知足条件 3 minor compaction才会启动
hbase.hstore.compaction.ratio :默认为1.2
hbase.hregion.majorcompaction : 0 关掉major compact
hbase.hstore.compaction.max : 默认值为10,表示一次minor compaction中最多选取10个store file
hbase.hstore.compaction.min : 默认值为 3
hbase.hstore.compaction.min.size :640M (未压缩?为memestoreFlushSize)
复制代码
hbase.hstore.compaction.ratio :默认为1.2 ,将store file 按照文件年龄排序(older to younger),minor compaction老是从older store file开始选择,若是该文件的size 小于它后面hbase.hstore.compaction.max 个store file size 之和乘以 该ratio,则该store file 也将加入到minor compaction 中。
hbase.hstore.blockingStoreFiles:HStore的storeFile的文件数大于配置值,则在flush memstore前先进行split或者compact,除非超过hbase.hstore.blockingWaitTime配置的时间,默认为7,可调大,好比:100,避免memstore不及时flush,当写入量大时,触发memstore的block,从而阻塞写操做。
hbase.hregion.max.filesize :默认值是256M 当hbase.hregion.max.filesize比较小时,触发split的机率更大,而split的时候会将region offline,所以在split结束的时间前,访问该region的请求将被block住,客户端自我block的时间默认为1s。当大量的region同时发生split时,系统的总体访问服务将大受影响。所以容易出现吞吐量及响应时间的不稳定现象
hbase.hregion.max.filesize : 当hbase.hregion.max.filesize比较大时,单个region中触发split的机率较小,大量region同时触发split的机率也较小,所以吞吐量较之小hfile尺寸更加稳定些。可是因为长期得不到split,所以同一个region内发生屡次compaction的机会增长了。compaction的原理是将原有数据读一遍并重写一遍到hdfs上,而后再删除原有数据。无疑这种行为会下降以io为瓶颈的系统的速度,所以平均吞吐量会受到一些影响而降低
hbase.hregion.max.filesize 这个值过大,读写hbase的速度会变慢,由于底层对hdfs的读写操做因为文件数量少,很难作到高并发,高吞吐,太小会发生频繁的文件split,split过程会使数据短暂离线,会对数据的访问有必定影响,不太稳定,因此这个值不能过小也不能太大,100-200MB基本能知足需求
基于文件大小进行合并
hbase.hstore.compaction.min.size 表示文件大小小于该值的store file 必定会加入到minor compaction的store file中
hbase.hstore.compaction.max.size Long.MAX_VALUE 表示文件大小大于该值的store file 必定会被minor compaction排除
复制代码
基于文件数量进行合并
hbase.hstore.compaction.min :默认值为 3,表示至少须要三个知足条件的store file时,minor compaction才会启动
hbase.hstore.compaction.max :默认值为10,表示一次minor compaction中最多选取10个store file
复制代码
hbase.hstore.blockingWaitTime block的等待时间 线上配置:90000(90s) 默认配置:90000(90s)
hbase.regionserver.global.memstore.upperLimit,默认为整个heap内存的40%。但这并不意味着全局内存触发的刷盘操做会将全部的MemStore都进行输盘,而是经过另一个参数hbase.regionserver.global.memstore.lowerLimit来控制,默认是整个heap内存的35%。当flush到全部memstore占整个heap内存的比率为35%的时候,就中止刷盘。这么作主要是为了减小刷盘对业务带来的影响,实现平滑系统负载的目的。
hbase.hregion.memstore.flush.size:当MemStore的大小达到hbase.hregion.memstore.flush.size大小的时候会触发刷盘,默认128M大小。
hase.regionserver.max.logs :前面说到Hlog为了保证Hbase数据的一致性,那么若是Hlog太多的话,会致使故障恢复的时间太长,所以Hbase会对Hlog的最大个数作限制。当达到Hlog的最大个数的时候,会强制刷盘。这个参数是hase.regionserver.max.logs,默认是32个。
为了本文的主题,此处参考了一篇很是好的博客,仅限该小节:https://blog.csdn.net/u014297175/article/details/50456147
复制代码
注意:后面会不断判断进行Older to younger 的合并,可是这个154M的文件会归入合并队列,由于当文件大小小于
hbase.hstore.compaction.min.size(为memestoreFlushSize) 则会当即被添加到合并队列。
复制代码
MajorCompact 条件:
一个reion达到必定的大小,他会自动split称两个region。若是咱们的Hbase版本是0.94 ,那么默认的有三种自动split的策略,ConstantSizeRegionSplitPolicy,IncreasingToUpperBoundRegionSplitPolicy还有 KeyPrefixRegionSplitPolicy.
目前Hbase仅支持行级事务,不支持跨行跨表事务要求。
提供一个基于行的独占锁来保证对同一行写的独立性,因此写的顺序是:
两阶段锁协议:不是一行一行的得到锁,批量写多行场景,防止死锁场景 两阶段锁协议,过程以下:
经过事务序列来控制顺序: 事务只有提交了才会出列,经过指针(Read Point)指到底部已提交事务号,指针之下的用户才能可见:
还须要进一步完善Major Compact的脚本控制逻辑
秦凯新 于深圳