HBase提供了两张特殊的目录表-ROOT-和META表,-ROOT-表用来查询所有的META表中region位置。HBase设计中只有一个root region即root region从不进行切分,从而保证类似于B+树结构的三层查找结构:
目录表中的行健由region表名、起始行和ID(通常是以毫秒表示的当前时间)连接而成。HBase0.90.0版本开始,主键上有另一个散列值附加在后面,目前这个附加部分只用在用户表的region中。
4.client会将查询过的位置信息保存缓存起来,缓存不会主动失效,因此如果client上的缓存全部失效,则需要进行最多6次网络来回,才能定位到正确的region(其中三次用来发现缓存失效,另外三次用来获取位置信息)
ZK不适合保存大量数据,而META表主要是保存region和RS的映射信息,region的数量没有具体约束,只要在内存允许的范围内,region数量可以有很多,如果保存在ZK中,ZK的压力会很大。
但是如果访问的region在RS上发生了改变,比如被balancer迁移到其他RS上了,这个时候,通过缓存的地址访问会出现异常,在出现异常的情况下,client需要重新走一遍上面的流程来获取新的RS地址。
minor合并和major合并
上文提到storefile最终是存储在hdfs上的,那么storefile就具有只读特性,因此HBase的更新其实是不断追加的操作。
当一个store中的storefile达到一定的阈值后,就会进行一次合并,将对同一个key的修改合并到一起,形成一个大的storefile,当storefile的大小达到一定阈值后,又会对storefile进行split,划分为两个storefile。
由于对表的更新是不断追加的,合并时,需要访问store中全部的storefile和memstore,将它们按row key进行合并,由于storefile和memstore都是经过排序的,并且storefile带有内存中索引,合并的过程还是比较快的。
因为存储文件不可修改,HBase是无法通过移除某个键/值来简单的删除数据,而是对删除的数据做个删除标记,表明该数据已被删除,检索过程中,删除标记掩盖该数据,客户端读取不到该数据。
随着memstore中数据不断刷写到磁盘中,会产生越来越多的hfile小文件,HBase内部通过将多个文件合并成一个较大的文件解决这一小文件问题。
1.minor合并(minor compaction)
将多个小文件(通过参数配置决定是否满足合并的条件)重写为数量较少的大文件,减少存储文件数量(多路归并),因为hfile的每个文件都是经过归类的,所以合并速度很快,主要受磁盘IO性能影响
2)major合并(major compaction)
将一个region中的一个列簇的若干个hfile重写为一个新的hfile。而且major合并能扫描所有的键/值对,顺序重写全部数据,重写过程中会略过做了删除标记的数据(超过版本号限制、超过生存时间TTL、客户端API移除等数据)
region管理
region分配
任何时刻,一个region只能分配给一个RS。
HMaster记录了当前有哪些可用的RS。以及当前哪些region分配给了哪些RS,哪些region还没有分配。当需要分配的新的region,并且有一个RS上有可用空间时,HMaster就给这个RS发送一个加载请求,把region分配给这个RS。RS得到请求后,就开始对此region提供服务。
region server上线
HMaster使用ZK来跟踪RS状态。
当某个RS启动时,会首先在ZK上的server目录下建立代表自己的znode。由于HMaster订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,HMaster可以得到来自zookeeper的实时通知。因此一旦RS上线,HMaster能马上得到消息。
region server下线
当RS下线时,它和ZK的会话断开,ZK自动释放代表这台server的文件上的独占锁。HMaster就可以确定RS都无法继续为它的region提供服务了(比如RS和ZK之间的网络断开了或者RS挂了),此时HMaster会删除server目录下代表这台RS的znode数据,并将这台RS的region分配给集群中还活着的RS
HMaster工作机制
HMaster上线
master启动之后会做如下事情:
1.从ZK上获取唯一一个代表active master的锁,用来阻止其它master成为active master
2.扫描ZK上的server父节点,获得当前可用的RS列表
3.和每个RS通信,获得当前已分配的region和RS的对应关系
4.扫描.META.region的集合,得到当前还未分配的region,将它们放入待分配region列表
从上线过程可以看到,HMaster保存的信息全是可以从系统其它地方收集到或者计算出来的。
HMaster下线
由于HMaster只维护表和region的元数据,而不参与表数据IO的过程,HMaster下线仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的schema,无法进行region的负载均衡,无法处理region上下线,无法进行region的合并,唯一例外的是region的split可以正常进行,因为只有region server参与),表的数据读写还可以正常进行。因此HMaster下线短时间内对整个HBase集群没有影响。
HBASE容错性
HMaster容错
配置HA,当active master宕机时,通过ZK重新选择一个新的active master。
注意:
1.无HMaster过程中,数据读取仍照常进行
2.无HMaster过程中,region切分、负载均衡等无法进行
RegionServer容错
定时向ZK汇报心跳,如果一定时间内未出现心跳,比如RS宕机,HMaster将该RS上的region、预写日志重新分配到其他RS上
HBASE数据迁移和备份
1. distcp命令拷贝hdfs文件的方式
使用MapReduce实现文件分发,把文件和目录的列表当做map任务的输入,每个任务完成部分文件的拷贝和传输工作。在目标集群再使用bulkload的方式导入就实现了数据的迁移。
执行完distcp命令后,需要执行hbase hbck -repairHoles修复HBase表元数据。缺点在于需要停写,不然会导致数据不一致,比较适合迁移历史表(数据不会被修改的情况)
2. copytable的方式实现表的迁移和备份
以表级别进行迁移,其本质也是使用MapReduce的方式进行数据的同步,它是利用MapReduce去scan源表数据,然后把scan出来的数据写到目标集群,从而实现数据的迁移和备份。示例:
./bin/hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable-Dhbase.client.scanner.caching=300-Dmapred.map.tasks.speculative.execution=false-Dmapreduc.local.map.tasks.maximum=20--peer.adr=zk_address:/hbasehbase_table_name
这种方式需要通过scan数据,对于很大的表,如果这个表本身又读写比较频繁的情况下,会对性能造成比较大的影响,并且效率比较低。
copytable常用参数说明(更多参数说明可参考hbase官方文档)
startrow、stoprow:开始行、结束行
starttime:版本号最小值
endtime:版本号最大值,starttime和endtime必须同时制定
peer.adr:目标hbase集群地址,格式:hbase.zk.quorum:hbase.zk.client.port:zk.znode.parent
families:要同步的列族,多个列族用逗号分隔
3. replication的方式实现表的复制
类似MySQL binlog日志的同步方式,HBase通过同步WAL日志中所有变更来实现表的同步,异步同步。
需要在两个集群数据一样的情况下开启复制,默认复制功能是关闭的,配置后需要重启集群,并且如果主集群数据有出现误修改,备集群的数据也会有问题。
4. Export/Import的方式实现表的迁移和备份
和copytable的方式类似,将HBase表的数据转换成Sequence File并dump到hdfs,也涉及scan表数据。
和copytable不同的是,export不是将HBase的数据scan出来直接put到目标集群,而是先转换成文件并同步到目标集群,再通过import的方式导到对应的表中。
示例:在老集群上执行:
./hbaseorg.apache.hadoop.hbase.mapreduce.Export test_tabNamehdfs://ip:port/test
在新集群上执行:
./hbaseorg.apache.hadoop.hbase.mapreduce.Import test_tabNamehdfs://ip:port/test
这种方式要求需要在import前在新集群中将表建好。需要scan数据,会对HBase造成负载的影响,效率不高。
5. snapshot的方式实现表的迁移和备份
通过HBase快照的方式实现HBase数据的迁移和拷贝。示例:
1.在老集群首先要创建快照:
snapshot 'tabName', 'snapshot_tabName'
2
../bin/hbaseorg.apache.hadoop.hbase.snapshot.ExportSnapshot-snapshot snapshot_tabName-copy-from hdfs://src-hbase-dir/hbase-copy-to hdfs://dst-hbase-dir/hbase-mappers 30-bandwidth 10
这种方式比较常用,效率高,也是最为推荐的数据迁移方式。