HBase表数据倾斜治理_shell命令实现bulkload

HBase表数据倾斜治理_shell命令实现bulkload

Bulkload原理

HBase底层物理存储是以HFile文件的形式将数据存储在磁盘上的。

将数据加载到HBase表中最直接的方法可以使用HBase提供的shell api或者java api进行数据导入,这种采用HBase api的方式主要过程:预写日志,将数据的操作信息和数据信息写入WAL;将数据放入RegionServer的内存MemStore中;再将数据flush到磁盘中形成HFile文件;当HFile文件较多还会进行compaction和split。这一系列过程很容易造成节点不稳定、极大消耗系统资源。

Bulkload不会预写日志,不会引起过量的flush、split和GC,主要分成两步:

  1. 对外部或者HDFS上需要导入HBase的数据执行MR任务,将处理完成的数据直接按照HBase底层存储格式保存到HFile中。
  2. 将目标HFile直接推送到HBase目录下。

注意bulkload实际上所需要的物理存储为源数据的两倍,第一步MR任务完成后先将HFile存放在设置的输出目录上,第二步推送到HBase目录下时会将HFile移动到对应的hbase存储目录下。

shell命令实现bulkload

1.准备工作

1.1开启hadoop和hbase
1
2
E:\HBase\hadoop\sbin>start-all.cmd
E:\HBase\hbase\bin>start-hbase.cmd

开启hadoop之后可以在http://localhost:50070客户端界面查看HDFS文件目录。

1.2创建一个csv数据文件

创建一个文件fellow.csv。

1
2
3
4
5
38343,2022/4/24,jiazhengyang,男,正式
374836,2022/4/4,zengqingfan,男,实习
34783484,2022/3/18,lijun,男,正式
37438,2022/4/11,lijiazheng,男,实习
2384783,2022/3/16,qiuyuchen,男,正式
1.3将文件上传到HDFS系统

需要先将文件从本地文件夹中上传到HDFS中,这样Bulkload的MR任务就可以直接从HDFS当中读取文件数据。

1
2
E:\HBase\hbase\bin>hdfs dfs -mkdir /fellowtest
E:\HBase\hbase\bin>hdfs dfs -put fellow.csv /fellowtest
1.4创建HBase表

要先创建好HBase表和列簇,这样Bulkload才能将处理后的HFile文件与HBase表关联起来。

HBase的一个store对象中保存一个列簇数据。store越多集群内存中创建的memstore就越多,内存占用太高;只要一个store需要flush,同一张表的所有store都会flush,造成磁盘IO太频繁。所以列簇越少越好,一般只创建一个列簇。

1
2
E:\HBase\hbase\bin>hbase shell
hbase(main):001:0> create 'fellowshell','d'

2.执行MR任务生成HFile文件

1
2
E:\HBase\hbase\bin>
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.bulk.output=/fellowshellhfile -Dimporttsv.columns="HBASE_ROW_KEY,d:birthday,d:name,d:sex,d:work" fellowshell /fellowtest/fellow.csv

语法说明:

1
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator=数据分隔符 -Dimporttsv.bulk.output=输出HFile目录 -Dimporttsv.columns=HBase表字段结构 HBase表名 输入HFile路径

在windows系统中HBase表字段结构必须加双引号,且需要开启用户创建符号表的权限以管理员模式运行命令提示符

3.将Hfile文件推送到HBase目录当中

1
2
E:\HBase\hbase\bin>
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /fellowshellhfile fellowshell

语法说明:

1
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles 输出HFile目录 HBase表名

最后进入HBase shell中即可查看表中是否出现数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
E:\HBase\hbase\bin>hbase shell
hbase(main):006:0> scan 'fellowshell'
ROW COLUMN+CELL
2384783 column=d:birthday, timestamp=1650797020232, value=2022/3/16
2384783 column=d:name, timestamp=1650797020232, value=qiuyuchen
2384783 column=d:sex, timestamp=1650797020232, value=\xE7\x94\xB7
2384783 column=d:work, timestamp=1650797020232, value=\xE6\xAD\xA3\xE5\xBC\x8F
34783484 column=d:birthday, timestamp=1650797020232, value=2022/3/18
34783484 column=d:name, timestamp=1650797020232, value=lijun
34783484 column=d:sex, timestamp=1650797020232, value=\xE7\x94\xB7
34783484 column=d:work, timestamp=1650797020232, value=\xE6\xAD\xA3\xE5\xBC\x8F
37438 column=d:birthday, timestamp=1650797020232, value=2022/4/11
37438 column=d:name, timestamp=1650797020232, value=lijiazheng
37438 column=d:sex, timestamp=1650797020232, value=\xE7\x94\xB7
37438 column=d:work, timestamp=1650797020232, value=\xE5\xAE\x9E\xE4\xB9\xA0
374836 column=d:birthday, timestamp=1650797020232, value=2022/4/4
374836 column=d:name, timestamp=1650797020232, value=zengqingfan
374836 column=d:sex, timestamp=1650797020232, value=\xE7\x94\xB7
374836 column=d:work, timestamp=1650797020232, value=\xE5\xAE\x9E\xE4\xB9\xA0
38343 column=d:birthday, timestamp=1650797020232, value=2022/4/24
38343 column=d:name, timestamp=1650797020232, value=jiazhengyang
38343 column=d:sex, timestamp=1650797020232, value=\xE7\x94\xB7
38343 column=d:work, timestamp=1650797020232, value=\xE6\xAD\xA3\xE5\xBC\x8F
5 row(s) in 0.1110 seconds

可以看到数据bulkload成功。