HBase 手动 flush 机制梳理
对应 HBase 版本0.94.1,对照了开源的版本和工作使用的某发行版
问题:在 HBase shell 里面输入 flush 'table_or_region_name'
之后,发生了什么?具体的实现是怎么样的?对于现有的某个表,我如何在做操作之前估算 flush 执行的时间?
1. HBase shell 入口
HBase shell 使用 ruby 实现,在 putty 敲hbase shell
,调用的是${HBASE_HOME}/bin/hbase
这个 bash 脚本,根据shell
这个参数,触发调用 ruby 代码,相关的部分如下:
if [ "$COMMAND" = "shell" ] ; then
if [ "$JRUBY_HOME" != "" ] ; then
CLASSPATH="$JRUBY_HOME/lib/jruby.jar:$CLASSPATH"
HBASE_OPTS="$HBASE_OPTS -Djruby.home=$JRUBY_HOME -Djruby.lib=$JRUBY_HOME/lib"
fi
CLASS="org.jruby.Main -X+O ${JRUBY_OPTS} ${HBASE_HOME}/bin/hirb.rb"
在 hirb.rb 里面,引入相关的包(${HBASE_HOME}/lib/ruby
目录下),然后启动一个运行的 CLI 环境。
进入正题了。
在 hbase shell 里面,所有执行的命令,都在${HBASE_HOME}/lib/ruby/shell/commands
目录下,有对应的${COMMAND}.rb
的对应文件。
找到 flush.rb,核心代码如下:
def command(table_or_region_name)
format_simple_command do
admin.flush(table_or_region_name)
end
end
这里调用了 admin.rb 这个文件里面的方法:
@admin = org.apache.hadoop.hbase.client.HBaseAdmin.new(configuration)
def flush(table_or_region_name)
@admin.flush(table_or_region_name)
end
到这里,就找到了 Java 程序的入口,调用了 HBaseAdmin.flush(table_or_region_name)
这个方法。
后续几部分的类图如下:
2. HBaseAdmin 包装
HBaseAdmin 类下面包含了三个 flush 方法:
public void flush(String tableNameOrRegionName) throws IOException, InterruptedException {}
public void flush(byte[] tableNameOrRegionName) throws IOException, InterruptedException {}
private void flush(ServerName sn, HRegionInfo hri) throws IOException {}
- 第一个,作为入口,将 String 参数转化为 byte[],交给第二个
- 第二个,主要的工作方法,按输入参数是 region 名、分区表、不分区表,分别进行处理
- 第三个,单独针对 region 进行 flush
第一个略过。
第二个,逻辑清晰:
- 如果是参数为 Region,就调用第三个 flush 处理
- 如果不是分区表,就获取该表包含的所有 Region,挨个调用第三个 flush 处理,
- 如果地分区表,处理方式与其他的不同,调用了一个分区表公共处理方法 execPartitionTableAction 订制实现了匿名类 PartitionTableActionCallableFactory,进行单独处理。
注意
- 对于没有预分区的表,简单地在一个 for 循环里面,串行处理
- 对于分区表,execPartitionTableAction中使用了并发数据结构 Future,对分区是并行处理
第三个,对每个 Region 进行 flush,实际上是第二个 flush 中所有 case 最终的归宿。
在第三个 flush 中,实现代码如下:
HRegionInterface rs = this.connection.getHRegionConnection(sn.getHostname(), sn.getPort());
rs.flushRegion(hri);
HRegionInterface 是一个抽象接口,flushRegion 是一个抽象方法。在0.94.1这个版本下,只有 HRegionServer 实现了 HRegionInterface 接口,所以要在 HRegionServer 里面找到具体的代码实现。
3. HRegionServer 包装
在 HRegionServer 类里面,包含了三个 flush 的实现:
public void flushRegion(byte[] regionName) throws IllegalArgumentException, IOException {}
public void flushRegion(byte[] regionName, long ifOlderThanTS) throws IllegalArgumentException, IOException {}
@QosPriority (priority=100)
public void flushRegion(HRegionInfo regionInfo) throws NotServingRegionException, IOException {}
- 第一个,简单地传入 regionName,确定 Region 在线,然后调用
region.flushcache()
- 第二个,传入 regionName 和 超时时间戳 ifOlderThanTS ,确定 Region 在线,且未超时的情况下,将数据 flush 出去
- 第三个,@QosPriority (priority=100)标记,使用了自定义声明,给该方法赋值 rpc 调用的优先级;方法体
checkOpen()
检查 RegionServer 在线后,调用region.flushcache()
接下来,查看看下 HRegion 类下面flushcache()
的实现。
4. HRegion 实现
flushcache只是个入口方法,会做一些 flush 之前的准备工作,包括:建立任务状态监控、判断 Coprocessor、处理未 WAL 的 put 、写加锁等。之后,调用内部方法internalFlushcache
开始flush。
在 internalFlushcache 方法实现中,做了 MVCC 的一些工作,最终,调用了StoreFlusher的flushCache方法实现。
internalFlushcache 为了保证数据一致性做了很多的检查、校验、加锁,目前功力不够,先标记下,进入下一层。
看下 StoreFlusher 的实现。
5. StoreFlusher 实现
StoreFlusher 是个接口,在0.94.1这个版本里面,只有 Store.StoreFlusherImpl 一个实现类。
在 StoreFlusher 接口里面可以看到,flush 操作执行的过程中包含3个部分:
- prepare,这是个短操作,创建 snapshot,这个过程中会暂停写操作
- flushCache,flush 执行的过程中,是不会阻塞该 store 上的任何操作(读写)
- commit,将 flush 出的文件添加到 store 目录下,清除 memstore 快照,短操作,会足暂停 scan
6. StoreFlusherImpl 实现
StoreFlusherImpl 是 Store 类的内部私有类,前面提到的 StoreFlusher 的3个方法,由 StoreFlusherImpl实现后,prepare 是自己实现,flushCache和 commit 都是调用外部 Store类的方法来完成。
6.1 prepare
public void prepare() {
memstore.snapshot();
this.snapshot = memstore.getSnapshot();
this.snapshotTimeRangeTracker = memstore.getSnapshotTimeRangeTracker();
}
调用了 MemStore 的方法,做快照。
6.2 flushCache
从 StoreFlusherImpl 调用 Store 类的flushCache方法,包装了internalFlushCache
方法来实现。
逻辑比较清晰:
- 启动一个 StoreScanner,根据时间戳和ScanType 参数,找出需要被 Flush 的行
- 启动一个StoreFile Writer,把读出来的数据,写入到一个 StoreFile 中,并将该 StoreFile 的路径返回,供后续 commit 阶段使用
6.3 commit
StoreFlusherImpl 类的 commit 方法首先调用外部 Store类的commitFile
方法,主要做的事情有两件:
- 将 flushCache 生成的 StoreFile 移动到 Store所在目录下
- 更新 Store 的相关统计参数
然后会调用外部 Store类的updateStorefiles
更新 Store 类的 storefile,更新文件后,需要调用needsCompaction()
,查看下是否因为本次 flush 执行造成的文件变化会触发 Compaction。如果触发 Compaction,会启动 Compaction 相关的一套机制继续执行,后续再单独介绍。
至此,手动 flush 操作背后的实现,初步梳理完毕。前面只是一个调用路径的梳理,后面继续丰富和补充。
HBase 手动 flush 机制梳理的更多相关文章
- Hbase的flush机制
Hbase Flush机制最小Flush单元为HRegion,尽量减少CF数量以减少HStrore数量从而减少MemStore的数量,最终减少每次Flush的开销.1.Region级别触发条件: ...
- 从一次异常中浅谈Hibernate的flush机制
摘自http://www.niwozhi.net/demo_c70_i1482.html http://blog.itpub.net/1586/viewspace-829613/ 这是在一次事务提交时 ...
- HBase使用flush命令之后存储的位置
HBase使用flush命令之后存储的位置 根据系统安装位置的不一样而不一样,当前是在: hadoop fs -ls /apps/hbase/data/data/default/t1 下面: 使用ha ...
- hbase的TTL机制清除opentsdb的超时数据
我们发现用opentsdb向hbase写数据之后,磁盘占用率飙升得很快,我们存的业务数据只用保存一个月的即可,了解hbase的TTL机制可以清除相关表.相关行的超时数据,之前在数据备份时,我介绍了,o ...
- java反射机制梳理
java反射机制梳理 Java反射简介 反射简介 编译和运行 编译时刻加载类是静态加载类.运行时刻加载类是动态加载类 要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载.Java类如 ...
- 【Hibernate框架】flush机制
背景: 一个偶然的机会,我做了一个例子,中间我遇到了一个有意思的问题,就是在执行commit方法之前,做了两次save操作,如下: SessionFactory sf = new Configurat ...
- hbase中balance机制
HBase是一种支持自动负载均衡的分布式KV数据库,在开启balance的开关(balance_switch)后,HBase的HMaster进程会自动根据指定策略挑选出一些Region,并将这些Reg ...
- linux内存管理及手动释放机制
inux系统中查看内存状态一般都会用到free linux的free命令中,cached和buffers的区别 Free Mem:表示物理内存统计 -/+ buffers/cached:表示物理内存的 ...
- HBase并行写机制(mvcc)
HBase在保证高性能的同时,为用户提供了便于理解的一致性数据模型MVCC (Multiversion Concurrency Control),即多版本并发控制技术,把数据库的行锁与行的多个版本结合 ...
随机推荐
- iphone手机版降级
想减少移动版本号.你能下载下来你想要的版本在苹果开发者网站,或"信誉"或可以下载到其他网站的iPhone下载固件固件网站.然后打开iTunes,进入 然后按着(alt).同一时候用 ...
- Android-采用Matrix对Bitmap加工
1.Android正在使用Matrix放.旋转.平移.斜切等变换的. Matrix是一个3*3的矩阵,其值相应例如以下: 以下给出详细坐标相应变形的属性|scaleX, skewX, translat ...
- asp.net学习之GridView事件、GridViewRow对象
原文:asp.net学习之GridView事件.GridViewRow对象 1. GridView控件的事件 GridView有很多事件,事件可以定制控件的外观或者行为.事件分为三类 1.1 ...
- XStream 用法汇总
XStream是一家Java对象和XML转换工具,很好很强大.它提供了所有的基本型.排列.收集和其他类型的支持,直接转换.因此XML在数据交换经常使用.对象序列化(和Java对象的序列 ...
- hibernate 管理 Session(单独使用session,不spring)
Hibernate 本身提供了三个管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 Session 对象的生命周期与 JTA 事务绑定 Hibernate 托付程序管理 ...
- .Net 4.5中的HttpClient试用
.Net 4.5中增加了一个新的System.Net.Http.HttpClient名字空间(在 System.Net.Http.dll 中),用于发送 HTTP 请求和接收 HTTP 响应. 基本操 ...
- 【高德地图API】如何获得行政区域?如何制作行政规划图?
原文:[高德地图API]如何获得行政区域?如何制作行政规划图? 什么是行政规划图?如何获得每个行政区域的边界轮廓图?举例:重庆市 江北区.如图: 官方类参考:http://developer.amap ...
- CodeForces 14 E - Camels && D - Two Paths
D - Two paths 仅仅想到了一个o(n^2)的解法. 首先枚举删除一条边,必定得到两棵独立的树.计算两棵树的直径.保留最大乘积. 首先两条路不相交,则必定能够分到两棵子树中,由于要乘积最大, ...
- sql server 辅助工具
sql Prompt 智能感知, 也是需要注册机. 效果如图: 这里最好改下:
- Java导出页面数据或数据库数据至Excel文件并下载,采用JXL技术,小demo(servlet实现)
public class ExportExcelServlet extends HttpServlet { /** * */ private static final long serialVersi ...