【HBase-Mysql】HBase数据和Mysql数据的相互迁移

  • 1)准备工作
  • 1.1.修改sqoop-env.sh中的配置文件
  • 1.2.在MySQL中添加测试数据
  • 2)MySQL数据导入到hbase中
  • 2.1.方式一
  • 2.1.1.使用sqoop直接进行导入
  • 2.2.方式二
  • 2.2.1.先将数据导入到hive中,然后通过importtsv进行导入
  • 2.2.1.1.put方式导入
  • 2.2.1.2.bulkload方式导入
  • 2.2.2.将Mysql数据导入HDFS中,使用HBase的importtsv直接导入数据


1)准备工作

如果使用Sqoop方式导入需要修改sqoop-env.sh中的相关配置

1.1.修改sqoop-env.sh中的配置文件

cd /export/servers/sqoop-1.4.6-cdh5.14.0/conf
vim sqoop-env.sh

#需要修改的内容
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0

#set the path to where bin/hbase is available
export HBASE_HOME=/export/servers/hbase-1.2.0-cdh5.14.0

#Set the path to where bin/hive is available
export HIVE_HOME=/export/servers/hive-1.1.0-cdh5.14.0

1.2.在MySQL中添加测试数据

#创建表
 CREATE DATABASE  IF NOT EXISTS library;
USE library;
CREATE TABLE book(
    id INT(4) PRIMARY KEY NOT NULL AUTO_INCREMENT, 
    NAME VARCHAR(255) NOT NULL, 
    price VARCHAR(255) NOT NULL
);
#插入数据
INSERT INTO book (NAME, price) VALUES('Lie Sporting', '30');  
INSERT INTO book (NAME, price) VALUES('Pride & Prejudice', '70');  
INSERT INTO book (NAME, price) VALUES('Fall of Giants', '50');

2)MySQL数据导入到hbase中

2.1.方式一

2.1.1.使用sqoop直接进行导入

#根据Mysql表结构在HBase中创建表
bin/sqoop import \
--connect jdbc:mysql://10.70.71.52:3306/library \
--username root \
--password 123456 \
--table book \
--columns "id,name,price" \
--column-family "info" \ #HBase列簇
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_book" \ #HBase表名
--num-mappers 1  \
--split-by id
#导入数据到HBase
sqoop import \
-D sqoop.hbase.add.row.key=true \
--connect jdbc:mysql://10.70.71.52:3306/library \
--username root \
--password 123456 \
--table book \
--hbase-create-table \
--hbase-table books \
--column-family info \
--hbase-row-key id

注意

此时如果失败了,提示NotFoundClass HBaseClient之类的错误,应该就是版本不兼容的问题,那么此时就可以使用另一种方式了,耐心向下看。

2.2.方式二

2.2.1.先将数据导入到hive中,然后通过importtsv进行导入

2.2.1.1.put方式导入

注意

下面的脚本中,有使用put的方式进行导数据到hbase中的方式,还有bulkload的方式,注意区分。

(1)在hive中根据MySQL的表结构创建表

sqoop create-hive-table \
--connect jdbc:mysql://5gcsp-bigdata-svr1:3306/library \
--table book \
--username root \
--password 123456 \
--hive-table sqooptohive.book

(2)先将数据导入到hive中

sqoop import \
--connect jdbc:mysql://5gcsp-bigdata-svr1:3306/library \
--username root \
--password 123456 \
--table book \
--hive-table sqooptohive.book \
--hive-import \
-m1

(3)使用put的方式直接导数据到hbase中

#进入HBase控制台
hbase shell
#创建对应表
create 'book','info'
#执行put方式写入到HBase中
HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.4
HBASE_HOME=/export/servers/hbase-1.6.0
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
importtsv \
-Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:price \
book \
/user/hive/warehouse/sqooptohive.db/book
2.2.1.2.bulkload方式导入

使用bulkload方式,先在指定目录中生成HFile文件,然后将HFile文件移动到HBase相关目录下。

注意:

-Dimporttsv.bulk.output,这个路径不能存在,否则会报错。

(1)生成HFile文件

HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.4
HBASE_HOME=/export/servers/hbase-1.6.0
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
importtsv \
-Dimporttsv.bulk.output=hdfs://5gcsp-bigdata-svr1:8020/datas/output_hfile/tbl_logs \
-Dimporttsv.columns=HBASE_ROW_KEY,info:id,info:name,info:price \
book \
/user/hive/warehouse/sqooptohive.db/book

(2)将HFILE文件加载到HBase表中

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
completebulkload \
hdfs://5gcsp-bigdata-svr1:8020/datas/output_hfile/tbl_logs \
book

注意:

如果此时命令执行成功,但是通过hbase shell查看对应的表中的数据的时发现表中并没有数据,那么可能是因为MySQL的数据同步到Hive的时候,Hive的分割符号不是\t,而是默认的分隔符导致的。

此时小伙伴们可能会提出疑问了,直接先在Hive中建表,指定好分隔符为\t,然后用sqoop导入不就行了吗?确实可以这样,但是可能会出现版本不兼容问题。

如果版本无冲突的情况下大家可以这样操作,如果版本有冲突那么可以参考下面办法

2.2.2.将Mysql数据导入HDFS中,使用HBase的importtsv直接导入数据

可以通过sqoop直接将数据导入到HDFS中,并指定分隔符为\t,然后再利用HBase中的importtsv进行导入数据到HBase

(1)将MySQL中的数据导入到HDFS中,并用指定分割符号\t分割

sqoop import \
--connect jdbc:mysql://5gcsp-bigdata-svr1:3306/test \
--username root \
--password 123456 \
--delete-target-dir \
--table emp \
--target-dir /test/input \
--m 1 \
--fields-terminated-by '\t'

(2)利用HBase中的importtsv将HDFS中的数据导入到HBase中

  • 使用put的方式进行导数据到hbase中
hbase shell
create 'book','info'

HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.4
HBASE_HOME=/export/servers/hbase-1.6.0
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
importtsv \
-Dimporttsv.columns=HBASE_ROW_KEY,info:id,info:NAME,info:price \
book \
/test/input/book.tsv
  • 或者使用bulkload方式,先在指定目录中生成HFile文件
    注意:-Dimporttsv.bulk.output,这个路径不能存在。
HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.4
HBASE_HOME=/export/servers/hbase-1.6.0
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
importtsv \
-Dimporttsv.bulk.output=hdfs://5gcsp-bigdata-svr1:8020/datas/output_hfile/tbl_logs \
-Dimporttsv.columns=HBASE_ROW_KEY,info:id,info:name,info:price \
book \
/test/input/book.tsv

#将HFILE文件加载到HBase表中
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf
${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.6.0.jar \
completebulkload \
hdfs://5gcsp-bigdata-svr1:8020/datas/output_hfile/tbl_logs \
book

最后用hbase shell查看hbase中的表,发现数据成功导入,搞定。