更新时间:2019年07月29日 15时43分48秒 来源:黑马程序员论坛
1 Region拆分一个Region代表一个表的一段Rowkey的数据集合,当Region太大,Master会将其拆分。Region太大会导致读取效率太低,遍历时间太长,通过将大数据拆分到不同机器上,分别查询再聚合,Hbase也被人称为“一个会自动分片的数据库”。 Region可以手动和自动拆分。 1.1 Region自动拆分 1.1.1 ConstantSizeRegionSplitPolicy 固定大小拆分策略,0.94版本之前的唯一拆分方法,如果单个Region大小超过了阀值那么就拆分为两个Region,这种策略使得急群众的Region大小很平均。唯一的参数是(hbase-site.xml): ![]() 1.1.2 IncreasingToUpperBoundRegionSplitPolicy 动态限制拆分策略,是新版本的默认策略。有的数据库文件增长是翻倍的数据量,128M,256M,512M……,该策略与之类似,限制是动态的,计算公式为: ![]()
![]() 1.1.3 KeyPrefixRegionSplitPolicy 固定长度前缀拆分策略,是IncreasingToUpperBoundRegionSplitPolicy的子类,在其基础上增加了对拆分点(splitPoint,拆分点就是Region被拆分出的RwoKey)的定义,保证了有相同前缀的key不会被拆分到两个不同的Region中。该策略会根据KeyPrefixRegionSplitPolicy.prefix_lenth所定义的长度来截取rowkey作为分组的依据。 当所有数据只有一两个前缀那么keyPrefixRegionSplitPolicy就不太有效,采用默认比较好,但是前缀如果划分比较细,查询容易发生跨Region查询的情况,这时候就比较实用。所以适合实用的场景有:
![]() 1.1.4 DelimitedKeyPrefixRegionSplitPolicy 分隔符前缀拆分策略,也是IncreasingToUpperBoundRegionSplitPolicy的子类,按照分隔符来判断是否进行拆分,比如定义了前缀分隔符为_,那么rowkey为host1_aaaaabbbb,host2_sjfijts,这两个数据会被拆分到不同的Region中。涉及到的配置参数有: ![]() 1.1.5 BusyRegionSplitPolicy 热点拆分策略,这是唯一考虑到热点数据的拆分策略,如果数据库中的Region某些短时间内被访问很频繁,承载了很大压力,就是热点Region,涉及到的配置参数有: ![]()
1.1.6 DisabledRegionSplitPolicy 手动拆分策略,其实就是上诉所有的策略都失效,不管如何判断,都会返回不拆分。 自动拆分策略都是数据最开始写入一个Region,之后可能会发生数据大量写入的同时还进行拆分,如果我们知道如果拆分Region,我们就可以提前定义拆分点,数据就会直接分配到各自所需的Region,手动拆分有如下良两种: 1.2 手动拆分 1.2.1 pre-splitting Region预拆分就是在建表的时候就定义好拆分点的算法,使用org.apache.hadoop.hbase.util.RegionSplitter类来创建表,并传入拆分点算法,就可以在建表同事定义拆分点算法。比如; ![]() 具体的拆分点算法有: 1.2.1.1 HexStringSplit ASCII码预拆分策略,只需要传入一个要拆分的Region的数量,HexStringSplit会将数据从“00000000”到“FFFFFFFF”之间的数据长度按照n等分之后算出每一段的其实rowkey和结束rowkey,以此作为拆分点。 1.2.1.2 UniformSplit 字节码预拆分策略,与ASCII码预拆分不同的是,起始结束不是Sting而是byte[]
默认预拆分算法只有这两个,我们也可以通过实现SplitAlgorithm接口实现自己的拆分算法,或者干脆手动定出拆分点。 1.2.2 手动制定拆分点(属于预拆分) 只需要在建表的时候跟上SPLITS参数: ![]() 1.2.3 强制拆分 其实这个才是实际意义上的手动拆分,通过运行命令强制手动拆分(forced splits),调用hbase shell的split方法。 ![]() 建议开始的时候定义预拆分,导入初始数据,之后使用自动拆分来让HBase自动管理Region。不要关闭自动拆分。这样科比避免因为直接使用预拆分导致的热点Region问题。 尽量使用适合业务的拆分策略,比如不要在时间戳为rowley前缀的情况下还是iyongKeyPrefixRegionSplitPolicy来作为拆分策略,这会导致严重的热点问题。 2 Region合并(Merge) 首先,Region的合并(merge)并不是为了性能考虑而是处于维护的目的被创造出来的。比如删了大量的数据,导致每个Region都变小了,这个时候合并Region就比较合适了。 2.1 通过Merge类冷合并Region 通过org.apache.hadoop.hbase.util.Merge类来实现,不需要进入hbase shell,直接执行: ![]() 就可以实现两个Region的合并,但是有一个前提,必须保证这两个Region已经下线,保证HMaster和所有的HRegionServer都停掉,否则会报错,但是这样太麻烦了,而且不适合生产使用。 2.2 通过online_merge热合并Region 与冷合并不同的是,online_merge的传参是Region的hash值,而Region的hash值就是Region名称的最后那段在两个.之间的字符串部分,需要进入hbase shell: ![]() 3 HFile合并(Compact) MemStore每次刷写都会生成一个HFile,当HFile变多,回到值读取数据磁头寻址缓慢,因为HFile都分散在不同的位置,为了防止寻址动作过多,适当的减少碎片文件,就需要合并HFile。 3.1 HFile的合并策略 合并操作主要是在一个Store里边找到需要合并的HFile,然后把它们合并起来,合并在大体意义上有两大类Minor Compation和Major Compaction:
3.1.1 老版本的合并策略(0.96之前) RationBasedCompactionPolicy 基于固定因子的合并策略,从旧到新扫描HFile文件,当扫描到某个文件满足条件: ![]() 就把该HFile和比它更新的所有HFile合并为一个HFile。 但是实际上,Memstore很多情况下会有不同的刷写情况,所以每次的HFile不一定一样大,比如最后一次导入数据需要关闭Region,强制刷写导致数据非常少。实际情况下RatioBasedCompactionPolicy算法效果很差,经常应发大面积合并,合并就不能写入数据,影响IO。 3.1.2 新版本合并策略 ExploringCompactionPolicy 是新版本的默认算法,不再是强顺序遍历,而是整体遍历一遍然后综合考虑,算法模型是: ![]() 如果HFile小于minCompactionSize,则不需要套用公式,直接进入待合并列表,如果没有配置该项,那么使用hbase.hregion.memstore.flush.size。 ![]() 所以一个HFile是否进行参与合并:
先进先出合并策略,最简单的合并算法,甚至可以说是一种删除策略。minor、major合并一定会发生但是频率不同,但是有时候没必要执行合并:
3.1.4 DateTieredCompactionPolicy 日期迭代合并删除策略,主要考虑了一个比较重要的点,最新的数据可能被读取的次数是最多的,比如电商中用户总是会查看最近的订单;随着时间的推移,用户会逐渐减缓对老数据的点击;非常古老的记录鲜有人问津。 电商订单这种数据作为历史记录一定没有TTL,那么FIFO合并策略不合适;单纯的看大小进行合并也不太有效,如果把新数据和老数据合并了,反而不好,所以Exploring也不友好。Ratio就更别考虑了,每次合并都卷入最新的HFile。 所以DateTieredCompactionPolicy的特点是:
![]() 有一个确定就是,如果Store中的某个HFile太老了,但是有没有超过TTL,且大于了最老层次时间,那么这个HFile在超时被删除之前都不会被删除,不会发生Major合并,用户手动删除数据也不会真正被删除,而是一直占用着空间。 其实归根到底,合并的最终策略是每个时间涌口中的HFile数量达到了最小合并数量,那么就回进行合并。另外,当一个HFile跨了时间线的时候,将其定义为下一个时间窗口(更老的更长的)。 适用场景:
简单来说就是将一个Store里边的数据分为多层,数据从Memstore刷写到HFile先落到level 0,当level 0大小超过一定的阀值时候会引发一次合并,会将level 0读取出来插入到level 1的HFile中去,而level 1的块是根据建委范围划分的,最早是分为多层的,后来感觉太复杂,将level 0改名为L0,而level 1-N合并成一个层叫做strips层。依旧是按照键位来划分块。 这种策略的好处是:
在使用过程中,如果突然发生IO降低,十有八九是发生compaction了,但是compaction又是不可获取的,所以就可以通过限制compaction的吞吐量来限制其占用的性能。 由于HBase是分布式系统,吞吐量的概念是磁盘IO+网络IO的笼统概念,因为没办法具体判断哪一个的IO的限制更大,HBase的吞吐量是通过要合并的HFile的文件大小/处理时间得出的。未发生合并之前就没法测了,只能通过上一次的合并信息进行简单预测。具体的设置参数有; ![]() hbase.hstore.blockingStoreFile的设置比较讲究,如果设置不合理,当HFile数量达到该值之后,会导致Memstore占用的内存急剧上升,很快就达到了Memstore写入上限,导致memstore阻塞,一点都写不进去。所以Memstore达到阻塞值的时候,先不要急着调大Memstore的阻塞阀值,要综合考虑HFile的合并阻塞值,可以适当调大,20、30、50都不算多,HFile多,只是读取性能下降而已,但是达到阻塞值不只是慢的问题了,是直接写不进去了。 3.2.1 合并/刷写吞吐量限制机制HBase会将合并和刷写总的吞吐量做计算,如果总吞吐量太大,那么进行适当休眠,因为这两个参数会限制合并时候占用的吞吐量,也会限制刷写时候占用的吞吐量。保证业务的响应流畅、保障系统的稳定性。限制会区分高峰时段和非高峰时段,通过如下两个参数: ![]() 通过设置非高峰,其他时段就是高峰时段了。在非高峰期是不会进行限速,只有在高峰期占用了太大的吞吐量才会休眠,主要看一个阀值: ![]() 3.2.2 压力比压力比(pressureRatio)越大,代表HFile堆积的越多,或者即将产生越多的HFile,一旦达到HFile的阻塞阀值,那么久无法写入数据了,所以合并压力比越大,合并的需求变得迫在眉睫。压力比越大,吞吐量的阀值越高,意味着合并线程可以占用更多的吞吐量来进行合并。 压力比有两种: 合并压力(compactionPressure): ![]() 当前的StoreFile越大,或者阻塞上限越小,合并压力越大,更可能发生阻塞 刷写压力(flusthPressure): ![]() 如果当前的Memstore占用内存越大,或者触发条件越小,越有可能引发刷写,刷写后HFile增多,就有可能发生HFile过多阻塞。 3.3合并的具体过程具体步骤为:
获取列表的时候需要排除掉带锁的HFile,分为写锁(write lock)和读锁(read lock),当HFile正在进行如下操作时候会进行上锁:
HRegion会创建出一个Scanner,用Scanner读取所有需要合并的HFile上的数据 第三步:把数据从这些HFile中读出,并放到tmp(临时目录) HBase会在临时目录中创建新的HFile,并把Scanner读取到的数据放入新的HFile,数据过期(达到了TTL时间)不会被读出: 第四步:用合并后的HFile来替换合并前的那些HFile 最后用哪个临时文件夹合并后的新HFile来替换掉之前那些HFile文件,过期的数据由于没有被读取出来,所以就永远消失了。 3.2.2 Major CompactionHBase中并没有一种合并策略叫做Major Compaction,Major Compaction目的是增加读性能,在Minor Compaction的基础上可以实现删除掉带墓碑标记的数据。因为有时候,用户删除的数据,墓碑标记和原始数据这两个KeyValue在不同的HFile上。在Scanner阶段,会将所有HFile数据查看一遍,如果数据有墓碑标记,那么就直接不Scan这条数据。 所以之前介绍的每一种合并策略,都有可能升级变为majorCompaction,如果本次Minor Compaction包含了当前Store所有的HFile,并且达到了足够的时间间隔,则会被升级为Major Compaction。这两个阀值的配置项为:
3.4 总结详细查看各种策略的合适场景,根据场景做策略选择
本文转载自: 链接:https://www.jianshu.com/p/7359a1789d24 |
推荐了解热门学科
java培训 | Python人工智能 | Web前端培训 | PHP培训 |
区块链培训 | 影视制作培训 | C++培训 | 产品经理培训 |
UI设计培训 | 新媒体培训 | 软件测试培训 | Linux运维 |
大数据培训 | 智能机器人软件开发 |
传智播客是一家致力于培养高素质软件开发人才的科技公司,“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。
传智播客从未停止思考
传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”
中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。
何为中高级程序员课程?
传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展。“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。
黑马程序员热门视频教程
Python入门教程完整版(懂中文就能学会) | 零起点打开Java世界的大门 |
C++| 匠心之作 从0到1入门学编程 | PHP|零基础入门开发者编程核心技术 |
Web前端入门教程_Web前端html+css+JavaScript | 软件测试入门到精通 |