ZK:/hbase/meta-region-server,该节点保存了meta表的region server数据
scan "hbase:meta", { FILTER => "PrefixFilter('ORDER_INFO')"}
ROW COLUMN+CELL
ORDER_INFO column=table:state, timestamp=1622254701537, value=\x08\x00
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:regioninfo, timestamp=1622373881754, value={ENCODED => d65e1e7a6a32104b50bae2e688e8a151, NAME => 'ORDER_IN
04b50bae2e688e8a151. FO,,1622254700267.d65e1e7a6a32104b50bae2e688e8a151.', STARTKEY => '', ENDKEY => ''}
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:seqnumDuringOpen, timestamp=1622373881754, value=\x00\x00\x00\x00\x00\x00\x02_
04b50bae2e688e8a151.
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:server, timestamp=1622373881754, value=bd-offcn-02:16020
04b50bae2e688e8a151.
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:serverstartcode, timestamp=1622373881754, value=1622373861799
04b50bae2e688e8a151.
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:sn, timestamp=1622373880034, value=bd-offcn-02,16020,1622373861799
04b50bae2e688e8a151.
ORDER_INFO,,1622254700267.d65e1e7a6a321 column=info:state, timestamp=1622373881754, value=OPEN
04b50bae2e688e8a151.
2、Vx
HBase的数据存储过程是分为几个阶段的。写入的过程与HBase的LSM结构对应。
(1)写入MemStore
(2)MemStore溢写合并
a、说明
b、触发条件
Region级别
hbase.hregion.memstore.flush.size
134217728
当一个 Region 中所有 MemStore 占用的内存达到了上限hbase.hregion.memstore.flush.size,默认128MB,会触发Memstore刷新。
但是如果数据增加得很快,达到了hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier的大小,
hbase.hregion.memstore.block.multiplier 默认值为4,也就是128*4=512MB的时候,那么除了触发 MemStore 刷写之外,HBase 还会在刷写的时候同时阻塞所有写入该 Store 的写请求!这时候如果你往对应的 Store 写数据,会出现RegionTooBusyException 异常
HBase 为 RegionServer 的整体的 MemStore 分配了一定的写缓存,大概占用 RegionServer 整个 JVM 内存使用量的 40%:
hbase.regionserver.global.memstore.size=0.4,如果整个 RegionServer 的所有 MemStore 占用内存总和大于写缓存的0.95。将会触发 MemStore 的刷写。
hbase.regionserver.global.memstore.size.lower.limit=0.95
举个例子,如果我们 HBase 堆内存总共是 32G,按照默认的比例,那么触发 RegionServer 级别的 Flush 是 RS 中所有的 MemStore 占用内存为:32 * 0.4 * 0.95 = 12.16G。
RegionServer 级别的Flush策略是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值。需要注意的是,如果达到了RegionServer 级别的 Flush,那么当前 RegionServer 的所有写操作将会被阻塞,而且这个阻塞可能会持续到分钟级别。
hbase.regionserver.optionalcacheflushinterval
3600000
用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个Region进行flush。
disable 'user'
drop 'user'
create 'user', 'info', 'data'
put 'user','001','info:name','zhangsan'
flush 'user'
put 'user','002','info:name','lisi'
flush 'user'
(3)模拟数据查看MemStore使用情况
注意:此处小数是无法显示的,只显示整数位的MB。
hbase org.apache.hadoop.hbase.mapreduce.Import WATER_BILL /water_bill/output_ept_10W
点击Memory查看内存占用情况
将数据可以手动刷新到到磁盘
hbase(main):004:0> flush 'WATER_BILL'
(4) In-memory合并(了解)
a、In-memory compaction介绍
In-memory合并是HBase 2.0之后添加的。它与默认的MemStore的区别:实现了在内存中进行compaction(合并)。
在CompactingMemStore中,数据是以段(Segment)为单位存储数据的。MemStore包含了多个segment。
b、compaction策略
但Active segment flush到pipeline中后,后台会触发一个任务来合并pipeline中的数据。合并任务会扫描pipeline中所有的segment,将segment的索引合并为一个索引。有三种合并策略:
c、配置
hbase.hregion.compacting.memstore.type
hbase-2.2.4版本
hbase.systemtables.compacting.memstore.type
NONE | BASIC | EAGER >
create "test_memory_compaction", {NAME => 'C1', IN_MEMORY_COMPACTION => "BASIC"}
(5)StoreFile合并
compact操作需要对HBase的数据进行多次的重新读写,因此这个过程会产生大量的IO。可以看到compact操作的本质就是以IO操作换取后续的读性能的提高
a、minor compaction
(1)说明
(2)触发条件
可以查看具体配置:
http://bd-offcn-01:16010/conf
hbase.hstore.compaction.min
3
false
b、major compaction
(1)说明
(2)触发条件
将Store下面所有StoreFile合并为一个StoreFile,此操作会删除其他版本的数据(不同时间戳的),忽略标记为delete的KeyValue(被删除的KeyValue只有在compact过程中才真正被"删除"),可以想象major会产生大量的IO操作,对HBase的读写性能产生影响。
major 大合并 默认7天进行一次 生成环境中建议将其关闭 由自己在业务空闲的时候手动触发,因为大合并的时候会非常消耗IO资源。
hbase.hregion.majorcompaction = 建议设置为0,还可以设置抖动比例(hbase.hregion.majorcompaction.jitter),默认是0.5,最终的周一起为3.5-10.5天
hbase.hregion.majorcompaction
604800000
604800000毫秒 = 604800秒 = 168小时 = 7天
手动触发方式:触发完成之后,可以查看hdfs的数据,原本多个storefile文件会变成一个。
手动触发方式:触发完成之后,可以查看hdfs的数据,原本多个storefile文件会变成一个。
hbase(main):009:0> major_compact 'WATER_BILL'
(1)region分配
(2)region server上线
(3)region server下线
(4)Region分裂
当region中的数据逐渐变大之后,达到某一个阈值,会进行裂变
<-- Region最大文件大小为10G -->
hbase.hregion.max.filesize
10737418240
false
a、自动分区
自动分区的算法 根据hbase版本的不同而不同,可以引入hbase-server包查看源码
hbase0.94版本以前是:ConstantSizeRegionSplitPolicy
0.94-2.0.0是:IncreasingToUpperBoundRegionSplitPolicy
2.0.0及以后是:SteppingSplitPolicy
org.apache.hbase
hbase-server
2.2.4
0.94以前如果一个region大小超过10G才会进行切片
0.94-2.0.0之间,如果一个表中region的数量等于0或者大于100,则按照10G切片
否则,每次计算一个表中region的数量,然后通过region数*region数*region数*2*flushsize(即128M)得出一个值,将该值与10G比较,取最小值,
某个region的大小超过该最小值才切片,
例如,
此时region数量为2,则2*2*2*256=2048M,该值小于10G,则这两个region中的一个超过2048M,则可切片。
此时region数量为3,则3*3*3*256=6912M,该值小于10G,则这3个region中的一个超过6912M,则可切片。
此时region数量为4,则4*4*4*256=16384M,该值大于10G,则这4个region中的一个超过10G,则可切片。
即可总结,若一个表的region数量大于等于4的话,是按照10G切片
b、手动分区
在创建表的时候,就可以指定表分为多少个Region。默认一开始的时候系统会只向一个RegionServer写数据,系统不指定startRow和endRow,可以在运行的时候提前Split,提高并发写入。
hbase(main):012:0> create 'staff1','info',SPLITS => ['1000','2000','3000','4000']
(1)Master上线
Master启动进行以下步骤:
(2)Master下线
(二) HBase批量装载(Bulk load)
很多时候,我们需要将外部的数据导入到HBase集群中,例如:将一些历史的数据导入到HBase做备份。我们之前已经学习了HBase的Java API,通过put方式可以将数据写入到HBase中,我们也学习过通过MapReduce编写代码将HDFS中的数据导入到HBase。但这些方式都是基于HBase的原生API方式进行操作的。这些方式有一个共同点,就是需要与HBase连接,然后进行操作。HBase服务器要维护、管理这些连接,以及接受来自客户端的操作,会给HBase的存储、计算、网络资源造成较大消耗。此时,在需要将海量数据写入到HBase时,通过Bulk load(大容量加载)的方式,会变得更高效。可以这么说,进行大量数据操作,Bulk load是必不可少的。
我们知道,HBase的数据最终是需要持久化到HDFS。HDFS是一个文件系统,那么数据可定是以一定的格式存储到里面的。例如:Hive我们可以以ORC、Parquet等方式存储。而HBase也有自己的数据格式,那就是HFile。Bulk Load就是直接将数据写入到StoreFile(HFile)中,从而绕开与HBase的交互,HFile生成后,直接一次性建立与HBase的关联即可。使用BulkLoad,绕过了Write to WAL,Write to MemStore及Flush to disk的过程
更多可以参考官方对Bulk load的描述:
Apache HBase ™ Reference Guide
Bulk load的流程主要分为两步:
银行每天都产生大量的转账记录,超过一定时期的数据,需要定期进行备份存储。本案例,在MySQL中有大量转账记录数据,需要将这些数据保存到HBase中。因为数据量非常庞大,所以采用的是Bulk Load方式来加载数据。
(1)数据集
id |
ID |
code |
流水单号 |
rec_account |
收款账户 |
rec_bank_name |
收款银行 |
rec_name |
收款人姓名 |
pay_account |
付款账户 |
pay_name |
付款人姓名 |
pay_comments |
转账附言 |
pay_channel |
转账渠道 |
pay_way |
转账方式 |
status |
转账状态 |
timestamp |
转账时间 |
money |
转账金额 |
(2)项目准备工作
a、HBase中创建银行转账记录表
create_namespace "OFFCN_BANK"
# disable "TRANSFER_RECORD"
# drop "TRANSFER_RECORD"
create "OFFCN_BANK:TRANSFER_RECORD", { NAME => "C1", COMPRESSION => "GZ"}, { NUMREGIONS => 6, SPLITALGO => "HexStringSplit"}
b、创建项目
groupid |
com.offcn |
artifactid |
bankrecord_bulkload |
c、导入POM依赖
org.apache.hbase
hbase-client
2.2.4
org.apache.hbase
hbase-mapreduce
2.2.4
org.apache.hadoop
hadoop-mapreduce-client-jobclient
3.2.1
org.apache.hadoop
hadoop-common
3.2.1
org.apache.hadoop
hadoop-mapreduce-client-core
3.2.1
org.apache.hadoop
hadoop-auth
3.2.1
org.apache.hadoop
hadoop-hdfs
3.2.1
commons-io
commons-io
2.6
junit
junit
4.12
compile
d、创建包结构
包 |
说明 |
com.offcn.bank_record.bulkload.mr |
MapReduce相关代码 |
com.offcn.bank_record.entity |
实体类 |
e、导入配置文件
将 core-site.xml、hbase-site.xml、log4j.properties三个配置文件拷贝到resources目录中。
(3)编写实体类
实现步骤:
7e59c946-b1c6-4b04-a60a-f69c7a9ef0d6,SU8sXYiQgJi8,6225681772493291,杭州银行,丁杰,4896117668090896,卑文彬,老婆,节日快乐,电脑客户端,电子银行转账,转账完成,2020-5-13 21:06:92,11659.0
参考代码: