一、业务背景
业务方需要搭建一套hbase集群,数据来源是hive表。为响应公司上云规划,hbase集群需通过EMR搭建。hive集群是在IDC机房,和普通集群迁移相比,这涉及到跨机房、跨集群的数据迁移,以及hive表数据到hbase集群数据的转换。
二、技术方案步骤
1、IDC机房与EMR网络的联通性验证
2、在EMR上搭建hbase集群,hive组件
3、迁移数据,数据校验
4、在目标集群创建对应hive库、表
5、在目标集群中将数据转换为HFile以hive中间表方式存储
6、创建hbase表,通过bulkload方式将数据导入hbase表
7、hbase集群验证数据
三、具体实施
1、IDC机房与EMR网络的联通性验证
需要自建集群和EMR各个节点网络互通。设置后可以在新集群节点上ssh 老集群节点确定网络连通情况,distcp操作如果有xx 节点无法连接xx节点的异常,说明没有连通,需要继续设置。
2、在EMR上搭建hbase集群,hive组件(略)
3、迁移数据,数据校验
i)迁移数据
一般在新集群上运行同步,这样同步的作业可以在新集群上运行,对老集群影响较小。
方式:通过distcp命令同步集群数据
hadoop distcp -pb -m xx 源集群 目标集群(hdfs路径为hive表的location位置)
迁移整体速度受集群间带宽,集群规模影响。
-m指定map数,和集群规模,数据量有关;先同步几个分区,调整-m参数,找到一个适合该集群的值并评估一下整体时间。
-bandwidth指定单个map的同步速度,是靠控制副本复制速度实现的,是大概值,由于IDC与EMR 是万兆带宽,就没设置该参数。
-pb,当源集群中的dfs块的大小与目标集群不一致,需设置该参数,不然会报FileNotFoundException
如果迁移过程中老集群还有写入,可以用-udpate再将变化同步过来。一般完全同步,需要有个短暂的业务停写,以启用双写双算或直接将业务切换到新集群上。
ii) 数据校验
分别统计每个分区数据的大小,与原集群进行对比,做一个初步的数据校验。在第四步完成后通过hive命令统计每个分区的条数做对比。
4、在目标集群创建对应hive库、表
i) 通过hive -e "create database/table xxx"
ii) 由于hive的元数据放在MySQL或其他db里,通过上述步骤,并没绑定hive表与数据的关系,需执行msck repair table *** ,修复hive表元数据。
5、在目标集群中将数据转换为HFile以hive中间表方式存储
执行以下脚本,生成hfile文件存储在 /tmp/hbase_table_hfile/cf_0
#!/bin/bash
hadoop fs -mkdir -p /tmp/hbase_table_hfile/cf_0
hive -e "
add jar /usr/local/service/hive/lib/hive-hbase-handler-2.3.2.jar;
add jar /usr/local/service/hive/lib/hbase-common-1.1.1.jar;
add jar /usr/local/service/hive/lib/hbase-client-1.1.1.jar;
add jar /usr/local/service/hive/lib/hbase-protocol-1.1.1.jar;
add jar /usr/local/service/hive/lib/hbase-server-1.1.1.jar;
create table if not exists default.hbase_hfile_table(rowkey string, value string)
stored as
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHFileOutputFormat'
TBLPROPERTIES ('hfile.family.path' = '/tmp/hbase_table_hfile/cf_0');
insert into table default.hbase_hfile_table select guid,xxx sort by guid;(必须添加sort by guid,不然会报错,因为在hbase里rowkey是有序存储 )
"
6、创建hbase表,通过bulkload方式将数据导入hbase表
i)执行以下命令创建hbase表
echo "create 'hbase_hfile_load_table',{NAME => 'cf_0', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'true', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'FAST_DIFF', COMPRESSION => 'GZ', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '32768', REPLICATION_SCOPE => '0'}" | hbase shell
ii)执行以下命令将hive中间表的hfile数据导入hbase集群中
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles -Dhbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily=20000 hdfs://HDFSXXX/tmp/hbase_table_hfile/ hbase_hfile_load_table
注意:若按i)命令创建hbase表,通过ii)命令导入hbase中时,只会形成一个region,落入一台机器,后续hbase集群额外还需进行切割。所以需要集群提前做好table的region分配。可以创建表时指定split region个数,如创建表时添加以下切分策略 {SPLITS => ['10', '20', '30', '40']}。
hbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily默认为32,若导入时,切分的region中hfile个数大于32,会报错,所以需要进行调整。