• 下面是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;
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐