一、前言

数据同步是很多公司在做数据迁移时的一个痛点,当然互联网公司有自己的同步机制或者工具,但是困惑了我这几天的需求,还是没有得到解决,事已至此,来写这篇博客记录一下自己最近的研究成果。

二、如何同步

hive如何与Hbase直接实现数据同步呢,目前有两种方案:

(一)hive关联hbase表的方式

1.适用场景

数据量不大4T以下(因为需要走hbase的api导入数据);

2.连接方式

从hbase页面获取zk连接地址(http://hadoop102:16010 ),并用下述方式启动hive客户端;

3.同步方式:

(1)如果hbase表不存在的情况下:

  • 创建hive表tmp_hive_hbase_table映射hbase表tmp_hbase_table,会自动创建hbase表tmp_hbase_table,且会随着hive表删除而删除。这里需要指定hive的schema到hbase schema的映射关系(指的是hive表的字段跟hbase的字段一一对应)。
CREATE TABLE tmp_hive_hbase_table(id string, val string) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf_1113:val") 
TBLPROPERTIES ("hbase.table.name" = "tmp_hbase_table", 
"hbase.mapred.output.outputtable" = "tmp_hbase_table");
  • 创建一张hive表tmp_hive_hbase_table,并添加几条数据:
-- 创建hive的普通表
create table tmp_hive_data(id int,val string);
-- 添加3条数据
insert into tmp_hive_data values(1,"ceshi1");
insert into tmp_hive_data values(2,"ceshi2");
insert into tmp_hive_data values(10,"ceshi10");
  • 把hive原表tmp_hive_data中数据,通过hive表tmp_hive_hbase_table导入到hbase的表tmphbase_table中:
insert into table tmp_hive_hbase_table select * from tmp_hive_data;
  • 查看hbase表hbase_table中是否有数据

hbase hive 导入数据 hive数据到hbase_hbase hive 导入数据

(2)如果hbase存在的情况下使用外部表的形式进行同步,其他步骤跟同上一样;

CREATE EXTERNAL TABLE tmp_hive_hbase_external_table(key int, value string) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val") 
TBLPROPERTIES ("hbase.table.name" = "tmp_hbase_table", 
"hbase.mapred.output.outputtable" = "tmp_hbase_table");

(二)hive表生成hfile,通过bulkload导入到hbase

  1. 适用场景

该方式适合大数据量的情况下使用,官方建议数据量大(4T以上),视情况而定。

    2.把hive数据转换为hfile

该方式先把hive数据转换成hfile文件上传至hdfs上,通过阿里提供的bulkload工具去hdfs上加载hfile文件,解析并入habse数据库;

(1)启动hive并添加相关hbase的jar包,一定要add以下的jar包,否则报HiveHFileOutputFormat错;

add jar /xxx/lib/hive-hbase-handler-2.3.3.jar;
add jar /xxx/lib/hbase-common-1.1.1.jar;
add jar /xxx/lib/hbase-client-1.1.1.jar;
add jar /xxx/lib/hbase-protocol-1.1.1.jar;
add jar /xxx/lib/hbase-server-1.1.1.jar;

(2)创建一个outputformat为HiveHFileOutputFormat的hive表

  • 其中hdfs:127.0.0.1:8888/tmp/tmphbase_table_hfile/cf_0是hfile保存到hdfs的路径,cf_0是hbase 列族名(family)
create table tmp_hive_hbase_table (
id int,
val string)
stored as
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHFileOutputFormat'
TBLPROPERTIES ('hfile.family.path' = 'hdfs://127.0.0.1:8888/tmp/tmp_hive_hbase_table/cf_0');

注意:如果hive跟hbase不在同一台主机上,执行完上一步操作,记得执行下面的语句:该语句映射hbase集群,打通hive和hbase的关系

set hbase.zookeeper.quorum=xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181
  • 把原始数据表的数据通过tmp_hbase_hfile_table表保存为hfile
insert into table tmp_hbase_hfile_table select * from tmp_hive_data;
  • 查看对应hdfs路径是否生成了hfile,可以通过浏览器直接查看,也可以通过hafs命令查看(hadoop fs -ls /tmp/tmp_hive_hbase_table/cf_0):

hbase hive 导入数据 hive数据到hbase_hdfs_02

  •  在hbase中使用hbase shell命令,创建一张表:
create 'tmp_hbase_load_table','cf_0'
  • 下载云hbase客户端,配置hbase-site.xml,并将hdfs-site.xml、core-site.xml拷贝到hbase/conf目录:
wget http://public-hbase.oss-cn-hangzhou.aliyuncs.com/installpackage/alihbase-1.1.4-bin.tar.gz
 vi conf/hbase-site.xml
 <property>
         <name>hbase.zookeeper.quorum</name>
         <value>配置Habse集群的地址</value>
 </property>
  • 执行bulkload导入到hbase表中
bin/hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles hdfs://127.0.0.1:port/tmp/tmp_hive_hbase_table/  tmp_hbase_load_table
  • 在hbase表tmp_hbase_load_table查看数据是否导入,使用habse的scan tableName查看即可:

hbase hive 导入数据 hive数据到hbase_hbase hive 导入数据

三、总结

以上就是最近做的需求实现思路,仅供大家参考,hive和habse直接数据同步有很多种方式,通过kettle、DataX等等工具都可以实现,但是个有利弊吧,希望能够帮助到大家!