Hbase的读写流程、快照管理以及RegionServer,Region,StoreFile,Hfile,ColumFamily的关系
下面是hbase的架构图:1.hbase的写操作首先client端写操作会先访问zookeeper获取hmaster的地址,然后访问hmasterhmaster会将处理这次操作的HRegionServer服务的地址给client,然后client会去请求对应的HRegionServer如果设置了AWL(Write-Ahead-Log)预写日志,那么HRegionServer会先进行预写日志操作,并
- 下面是hbase的架构图:
- .META.表和-ROOT-表
ROOT表和META表都是相当于hbase的元数据表,在zookeeper中记录的了ROOT表所在的RegionService的地址,你可以通过这个地址找到ROOT表,ROOT表里面又记录了你操作的这个表所有ROWKEY的分区详细记录的META表的地址,然后路由到那个记录详细信息的且管理META这部分表的RegionServer,然后定位到META表,在META表唯一定位到一个指定的RegionServer,三段式路由:zookeeper、ROOT、META。
META表上面存储的就是Hbase上面所有Region的分布和详细信息,如果META表过大那么META的region也会分裂,那么就引进了ROOT表存储META表的Region的分布和详细信息,不过现在新版本好像已经没有ROOT表了,因为Hbase中数据个数一般不会使META的Region分裂。
那么读写操作client都不会和hmaster打交道,client会直接通过zookeeper的root表和META表定位到HRegionServer,先根据ROOT表定位META表的Region,在根据META的信息定位到你需要操作的那个值的Region,所以hbase的读写操作不会和hmaster打交道,并且会将这些信息cache到client端口。
而HMaster的作用主要是:
为HRegionServer分配region
负责HRegionServer的负载均衡
复制处理HRegionServer挂掉的情况,并且为这些Region分配新HRegionServer
维护.META.和-ROOT-表的信息,比如在Region分裂的时候hmaster就会去维护
- 1.hbase的写操作
首先client端写操作会先访问zookeeper,然后根据zk里面的-ROOT-中的信息和.META.中的信息直接映射到对应的HRegionServer
client会去请求对应的HRegionServer
如果设置了WAL(Write-Ahead-Log)预写日志,那么HRegionServer会先进行预写日志操作,并且是多线程写入一个队列里面,然后另外一个单线程的真正写日志的操作从队列里面取数据(保证数据的全局一致性)一个HRegionServer的预写日志操作只会写到一个Hlog里面,也就是说一个HRegionServer管理的不同的Region的预写日志都是公用一个Hlog,写到Hlog中(sequence file文件格式),据网友测试在操作hbase开启和关闭预写日志,性能相差大概10到20倍左右
然后写入数据到HRegion的MemStore(内存)中,如果MemStore达到了一定的大小,MemStore会被flush到StoreFile,flush之后还会记录一个flag,到时候用Hlog恢复的时候就知道哪些数据在HRegionServer挂了之后就丢失了,哪些数据已经持久化到磁盘了。
当StoreFile数量达到一定值后会进行Compact(合并)操作,合并最后StoreFile大小达到一定值之后会进行分裂split操作,在split操作的时候会和hmaster打交道,hmaster会去维护META表和ROOT的数据(META表分裂的时候 同理)。
Region会分裂成两个相等的Region,之前的Region就会下线,然后后面的两个新Region会被Hmaster分配到其他的HRegionServer上面
这里有2个注意事项就是:
1.在创建表的时候我们应该先预估数据量,然后在创建表的时候就先预先创建适量的Region个数,不然所有数据都放一个Region,当数据量很大的时候,就会造成Region的分裂会很平常,就特别影响性能;
2.最好在建表的时候指定比较少的ColumnFamily,因为如果ColumnFamily比较多,一个StoreFile对应一个ColumnFamily,如果有多个ColumnFamily那么就有多个StoreFile,当有的ColumnFamily数据量很大有的很小,但是当Region达到一定数据量会分裂,那么会我们查询就可能会夸多个Region,导致性能不高
- 2.hbase读数据
Client会先访问zookeeper并且根据zk里面的-ROOT-中的信息和.META.中的信息(我的理解是ROOT存储一段一段的数据,你查询的数据能直接定位到在那一段中,然后在去META表中查询具体的信息)直接映射到对应的HRegionServer
client请求对应的HRegionServer,首先会去MemStore(内存)中查询数据,如果有数据就返回
MemStore没有查询到数据,就会去Block缓存块中查询,缓存块中查询到数据就直接返回
Block缓存块没有查询到数据,就会去硬盘读取StoreFile的信息,并且也放到Block缓存块中,Block缓存块旧的东西就会被删除,直到查询到数据为止并返回,或者没有查询到数据就返回空
- 3. Hbase中RegionServer,Region,StoreFile,Hfile,ColumFamily等等的关系
Region是hbase最小的逻辑存储单元,但是物理的还有StoreFile,Hfile,一个Region包含一个或者多个StoreFile,一个StoreFile包含一个或者多个Hfile,其中RegionServer是为Region服务的。
一个Region包含一个或者多个StoreFile,而一个StoreFile对应一个ColumnFamily,所以一个Region会包含一个或者多个ColumnFamily
一个Region只能由一个RegionServer服务,但是一个RegionServer可以服务多个Region
- 4.hbase的快照管理
快照就是一份元信息的合集,允许管理员恢复到表的先前状态。快照不是表的复制而是一个文件名称列表,因而不会复制数据。
hbase的快照是依赖于hdfs提供的快照功能,可以对之前的数据进行快照拍摄,当误操作删除了数据,可以恢复到以前快照版本的数据,但是之后的数据就没有了(还有一个方法,如果误操作删除了表,可以在hdfs的/hbase/archive文件夹里面找到对应的表信息,默认删除了表,会将Region的数据先转移到这个文件夹,但是当达到设置的时间后这个文件下的数据也会被删除,配置项目:hbase.master.hfilecleaner.ttl,默认是600000 ms,可以在这时间之类把数据拷贝到data目录下,然后使用hbase的修复元数据功能进行数据恢复)。
hbase的快照管理提供了shell脚本的方式,也提供了javaAPI的方式
前提是hbase-site.xml中的hbase.snapshot.enabled 是否是true (默认为true)
shell方式:
一.创建快照:
hbase(main):005:0> snapshot 'lijie001','lijie001snapshot'
0 row(s) in 8.6660 seconds
二.快照列表:
hbase(main):008:0> list_snapshots
SNAPSHOT TABLE + CREATION TIME
lijie001snapshot lijie001 (Thu Feb 23 09:40:23 -0500 2017)
1 row(s) in 3.1330 seconds
=> ["lijie001snapshot"]
三.克隆快照(从快照中克隆一个新表):
hbase(main):009:0> clone_snapshot 'lijie001snapshot','clone_lijie001'
0 row(s) in 5.9920 seconds
四.删除快照:
hbase(main):011:0> delete_snapshot 'lijie001snapshot'
0 row(s) in 3.8050 seconds
五.快照恢复
必须首先disable表,不然会报错
hbase(main):019:0> disable 'lijie001'
0 row(s) in 1.2740 seconds
hbase(main):020:0> restore_snapshot 'lijie001snapshot'
0 row(s) in 8.5710 seconds
hbase(main):021:0> enable 'lijie001'
0 row(s) in 4.8730 seconds
javaAPI方式(方法在org.apache.hadoop.hbase.client 的Admin类中)
一.创建快照:
void snapshot(final String snapshotName, final TableName tableName) throws IOException, SnapshotCreationException, IllegalArgumentException;
二.获取快照:
List<HBaseProtos.SnapshotDescription> listSnapshots() throws IOException;
List<HBaseProtos.SnapshotDescription> listSnapshots(String regex) throws IOException;
List<HBaseProtos.SnapshotDescription> listSnapshots(Pattern pattern) throws IOException;
三.删除快照(单个或者多个):
void deleteSnapshot(final byte[] snapshotName) throws IOException;
void deleteSnapshot(final String snapshotName) throws IOException;
void deleteSnapshots(final String regex) throws IOException;
void deleteSnapshots(final Pattern pattern) throws IOException;
更多推荐
所有评论(0)