Hbase compaction 源码分析二:详细 compaction 过程

因为major compact很影响hbase的读写性能,所以在不同版本是否major compact其实社区一直都在寻求优化,可根据需要选择不同的实现类RatioBasedCompactionPolicy、ExploringCompactionPolicy和StripeCompactionPolicy,选择了不同的policy(实现类)后,也选择了相应的选择算法从对应store中选择合适的hfile文件进行合并。有关不同Policy的算法性能影响及适合场景可参考文章:

http://hbasefly.com/2016/07/25/hbase-compaction-2/

hbase1.1.3版本使用的实现类是RatioBasedCompactionPolicy:

下面,从chore方法中开始分析 compactor的过程,从chore方法中可以看到minor compact将调用compactSplitThread的requestSystemCompaction方,major compact将调用ompactSplitThread的requestCompaction方法,但这两个方法都会调用CompactSplitThread的requestCompactionInternal方法:

这个是requestCompactionInternal方法原型:

从源码中可以看到,minor和major的区别再于参数CompactionRequest和selectNow。

这个方法很简单:根据请求compact的文件大小以及selectNow判断使用long或者short线程池,然后封装成CompactionRunner放到对应线程池中执行。

placeholder:selectCompaction方法有点长。

doCompaction方法是真正实现方法,在为了完成compact一共分为以下步骤:

1.选择需要Compaction的问题(只有Minor compaction)

2.执行前置listener

3.在region中以store为单位执行compaction

4.是否需要split

5.执行后置listerner

选择文件的方法是利用滑动窗口把最多的小文件进行合并,可参考http://www.cnblogs.com/cenyuhai/p/3746473.html:,本文档将着重分析在region中以store为单位进行compaction:

在保证当前store并没有在compaction后:

1.首先对region的lock锁加上读锁;

2.创建一个status用于监控和跟踪compaction的过程

3.调用doRegionCompactionPrep()方法进行compaction的准备,当前实现为空

4.调用对应store的compact方法

5.status标记成功

在store的compact方法中:

1.检查compactRequest参数

2.通过compaction(DefaultStoreEngine,查看类图)的compaction方法,并返回compaction后的新hfile文件

3.根据hbase.hstore.compaction.complete判断是否做一些compaction的complete工作:

a,把compact生成的文件移动到正确的位置

b.记录WALEdit日志

c.更新HStore相关的数据结构

d.归档旧的文件,关闭reader,重新计算file的大小

执行结束之后会生成临时文件,临时文件的意义在于,在Compaction执行期间,对于原数据访问没有影响。Compaction执行合并操作生成的文件生效过程,需要对Store的写操作加锁,阻塞Store内的更新操作,直到更新Store的storeFiles完成为止。

compact生成新文件的方法很简单,给源文件创建一个StoreScanner,之前说过StoreScanner能从多个Scanner当中每次都取出最小的kv,然后用StoreFile.Append的方法不停地追加写入即可:

PS,compaction对hbase的读写性能均有一定影响,有关对性能影响以及相关调优可参考:

http://hbasefly.com/2016/07/13/hbase-compaction-1/

http://hbasefly.com/2016/07/25/hbase-compaction-2/

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CDN及云技术分享

GDB实现原理和使用范例

这篇文章为了让你深入了解gdb的工作原理,以及如何在linux环境下使用强大的gdb调试程序功能。

2911
来自专栏美团技术团队

Node.js Stream - 实战篇

背景 前面两篇(基础篇和进阶篇)主要介绍流的基本用法和原理,本篇从应用的角度,介绍如何使用管道进行程序设计,主要内容包括: 管道的概念 Browserify的...

3445
来自专栏Android群英传

Android Native Crash 收集

本文是『张涛的NDK之旅』,本来很早以前就有很多读者希望我能写一些关于MDK的文章,但是由于我本身对NDK不熟悉,所以找来了同事张涛的文章。欢迎大家关注他的博客...

1151
来自专栏Android 研究

Android系统启动——3init.rc解析

init.rc文件是以“块”(section)为单位服务的,,一个“块”(section)可以包含多行。“块”(section)分成两大类:一类称为"动作(ac...

1392
来自专栏逸鹏说道

C# 温故而知新:Stream篇(四)上

FileStream 目录: 如何去理解FileStream? FileStream的重要性 FileStream常用构造函数(重要) 非托管参数SafeFil...

2725
来自专栏同步博客

浅谈PHP异常处理

  PHP中的异常的独特性,即PHP中的异常不同于主流语言C++、java中的异常。在Java中,异常是唯一的错误报告方式,而在PHP中却不是这样,而是把所有不...

753
来自专栏搜云库

《深入理解Java虚拟机》(五)JVM调优 - 工具

JVM调优 - 工具 JConsole:Java监视与管理控制台 JConsole是一个机遇JMX(Java Management Extensions,即Ja...

2379
来自专栏逆向技术

C语言第十二讲,文件操作.

在操作系统中,我们的文档都称为文件.操作系统也为我们提供了接口进行操作.不同语言都是使用的相同的接口,只不过封装的上层接口不一样

880
来自专栏皮振伟的专栏

[linux][statethread]协程库ST技术分析

前言: 在IO密集型的场景下,尤其是互联网后台,经常会使用epoll等IO复用技术。鉴于直接使用epoll的代码阅读性和开发效率等原因,就抽象出来了各种高级模型...

2798
来自专栏青玉伏案

iOS开发之线程间的MachPort通信与子线程中的Notification转发

如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification。简单的说,M...

2528

扫码关注云+社区