Linux环境下命令行方式数据迁移(全量导入)
添加驱动
拷贝驱动Oracle JDBC Driver至Sqoop安装目录lib下 ,本文档目录为/opt/cloudera/parcels/CDH-5.11.0-1.cdh5.11.0.p0.34/lib/sqoop/lib/
测试连接
测试Sqoop与Oracle数据库连接。
命令示例:
bin/sqoop \
list-tables \
-connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl \
--username scott \
--password tiger \
备注:
可能的报错:java.lang.RuntimeException: Could not load db driver class: oracle.jdbc.OracleDriver。
原因: sqoop安装lib目录下缺少Oracle JDBC Driver,将其拷贝至lib目录下(本文档为目录)
全量数据迁移
Sqoop使用命令行方式迁移Oracle数据至HBase。
命令示例:
bin/sqoop import
--connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl
--username scott
--password tiger
--table EMP
--hbase-table EmpTest
--column-family cf
--hbase-row-key EMPNO
--hbase-create-table
--split-by EMPNO
-m 2
sqoop import
-D sqoop.hbase.add.row.key=true \
--connect "jdbc:oracle:thin:@192.168.0.2:1521:orasid" \
--password "password" \
--username "system" \
--query "SELECT * FROM SCHEMANAME.TABLENAME " \
--hbase-create-table \
--hbase-table "HADP:TABLENAME " \
--hbase-row-key "ID" \
--column-family "ID" \
--split-by "ID" \
--verbose
备注:sqoop.hbase.add.row.key 导入时将KEY也作为值写入HBASE表中
增量导入
在实际的生产环境下,我们常常需要将数据增量的导入
核心参数
·–check-column
检查指定的列,根据此列判断哪些记录是新数据且需要导入的,列不能是字符相关类型(CHAR/NCHAR/VARCHAR/VARNCHAR/ LONGVARCHAR/LONGNVARCHAR),一般为数据库中的关键字,和关系型数据库中的自增字段及时间戳类似。
注意:这些被指定的列的类型不能是任意字符类型,同时–check-column可以指定多个列。
·–incremental
指定增量导入的模式,两种模式分别为Append和Lastmodified
- Append:当表中记录是以id持续增加导入新的记录的时候,可以使用append模式,–check-column id 用于检查id。
- lastmodified:表有时候也需执行更新操作,此时可以使用lastmodified导入。
·–last-value
指定上一次导入中检查列指定字段最大值(–check-column的某个值),将大于(append)或者大于等于(lastmodified)该值的检查列记录导入,以确定仅将新的或者更新后的记录导入新的文件系统。
以上三个参数必须同时指定。
和–append参数的区别:
–append导入的时候不会再次创建新的HDFS目录(使用普通命令的话,会创建一个新的HDFS目录,如果该目录已存在则会失败),该命令会直接在已存在的目录下继续导入数据,但是不管数据是否重复。
Append模式增量导入
在数据库的表字段中常常会设置一个自增的字段来作为数据表的主键,本文档这里以ID字段来作为判断数据行是否为增量数据的依据.
last-value设置为上次导入的ID的最大值,因此Sqoop就只会将大于ID(>ID)值的数据进行导入,实现了数据的增量导入.
注意:如果不指定last-value值,将会将表的所有数据进行导入,便发生了数据的冗余.
CREATE TABLE "SCOTT"."PEOPLE" (
"ID" NUMBER NOT NULL ,
"NAME" VARCHAR2(50) NOT NULL
)
NOCOMPRESS
;
命令示例:
bin/sqoop import \
--connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl \
--username scott \
--password tiger \
--table PEOPLE \
--hbase-table people \
--column-family cf \
--hbase-row-key ID \
--split-by ID \
-m 2 \
--check-column ID \
--incremental append \
--last-value 13 \
Lastmodified模式增量导入
首先创建一个customer表,指定一个时间戳字段
CREATE TABLE "SCOTT"."TEST" (
"ID" NUMBER(10) NOT NULL ,
"NAME" VARCHAR2(50) NOT NULL ,
"LAST_MOD" TIMESTAMP(6) NOT NULL
)
NOCOMPRESS
;
采用lastmodified模式去处理增量时,会将大于等于(≧)last-value值的数据当做增量插入.
注意: 使用lastmodified模式进行增量处理要指定增量数据是以append模式(附加)还是merge-key(合并)模式添加.
命令示例:
bin/sqoop import \
--connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl \
--username scott \
--password tiger \
--table TEST \
--hbase-table test \
--column-family cf \
--hbase-row-key ID \
--split-by ID \
-m 2 \
--check-column LAST_MOD \
--incremental lastmodified \
--last-value "2017-11-14 18:14:01.9" \
--append
本文档采用merge-by的模式进行增量更新,merge-key这种模式进行了一次完整的mapreduce操作。
命令示例:
bin/sqoop import
--connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl \
--username scott \
--password tiger \
--table TEST \
--hbase-table test \
--column-family cf \
--hbase-row-key ID \
--split-by ID \
-m 2 \
--check-column LAST_MOD \
--incremental lastmodified \
--last-value "2017-11-15 15:19:26:8" \
--merge-key ID \
使用Sqoop Job工具同步数据
使用Sqoop进行数据同步时,如果使用--incremental选项,需要记录一个--last-value值,而如果每次手动执行同步命令时,都需要获取这个--last-value最新值,然后重新设置命令参数才能正确同步,保证不会发生数据重复的问题,因而非常不方便。
Sqoop提供了一种比较方便的方式,即直接创建Sqoop Job,通过Job来管理特定的同步任务。通过创建Job,Sqoop每次完成调用之后都会将最新的last_value值自动保存至Sqoop的metastore中,用于替换下一次调用job时的last_value值,从而实现增量更新。
Sqoop Job命令使用
Sqoop job相关命令有两个,使用这两个都可以:
bin/sqoop job
bin/sqoop-job
其基本用法如下:
- 创建job:--create
- 删除job:--delete
- 执行job:--exec
- 显示job:--show
- 列出job:--list
Job增量数据迁移创建示例:
bin/sqoop job --create test-job
-- import //注意为空格
--connect jdbc:oracle:thin:@//192.168.13.210:1521/orcl
--username scott
--password tiger
--table TEST
--hbase-table test
--column-family cf
--hbase-row-key ID
--split-by ID
-m 2
--check-column LAST_MOD
--incremental lastmodified
--last-value "2017-11-15 13:30:12.8"
--merge-key ID
查看所有Job列表:
命令格式:bin/sqoop job --list
执行Job任务:
命令格式:bin/sqoop job --exec jobName
e.g:bin/sqoop job --exec test-job
显示Job参数细节:
命令格式:bin/sqoop job --show jobName
e.g:bin/sqoop job --show test-job
增量导入前last-value值
执行增量Job更新后的last-value值
Sqoop Job无密码执行
要将Oracle数据库中的数据同步到Hbase中,每次执行sqoop job都需要输入访问Oracle数据库的连接账号信息。在Sqoop安装目录下,通过修改配置文件conf/sqoop-site.xml可以对job进行更高级的配置。实际上,我们使用Sqoop的metastore工具,它能够对Sqoop进行细粒度的配置。
可以设置sqoop.metastore.client.record.password的值为true。在conf/sqoop-site.xml中增加如下配置,则会将连接账号信息存储到Sqoop的metastore中。
vim /etc/sqoop/conf/sqoop-site.xml
增加如下配置
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>If true, allow saved passwords in the metastore.
</description>
</property>
- Windows环境下以API方式迁移数据
环境搭建与配置
配置Hadoop相关环境变量,本文档相关环境配置如下:
1)HADOOP_HOME =
C:\DevelopmentFile\Hadoop\hadoop-2.6.0-cdh5.11.0
2)PATH =
%HADOOP_HOME%\bin
- 进入HADOOP_HOME/bin目录下,将winutils.exe等相关程序拷入
- Eclipse环境下拷入core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml配置文件,并编辑项目下的mapred-site.xml,添加如下属性:
<property>
<name>mapred.remote.os</name>
<value>Linux</value>
<description>Remote MapReduce framework's OS, can be either linux or Windows</description>
</property>
<property>
<name>mapreduce.app-submission.cross-platform</name>
<value>true</value>
</property>
或者在程序中配置如下:
- pom.xml配置文件如下
6)Maven导入相关Jar包至本地仓库
导入示例:
加载命令:
mvn install:install-file \
-DgroupId=com.oracle \
-DartifactId=ojdbc6 \
-Dversion=11.2.0.1.0 \
-Dpackaging=jar \
-Dfile=C:\DevelopmentFile\Jars\oracle-jdbc\ojdbc6.jar
将加载命令在cmd命令提示符中进行执行(Maven环境需要提前配置好,同时要注意DartifactId和Dversion与使用的jar版本一致)
安装完后,在pom.xml文件中添加引用
备注:需注意上述xml文件中的groupId、artifactId、version必须和命令中的信息一致
7)异常备注:
可能报错:windows下eclipse 远程调用HADOOP:Hadoop 2.6.0 Remote Submit Job Error:ExitCodeException: /bin/bash: line 0: fg: no job control
Error Occurs:
Exception message: /bin/bash: line 0: fg: no job control
Stack trace: ExitCodeException exitCode=1: /bin/bash: line 0: fg: no job control
at org.apache.Hadoop.util.Shell.runCommand(Shell.Java:538)
at org.apache.hadoop.util.Shell.run(Shell.java:455)
at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:715)
at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:211)
at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:302)
at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:82)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Container exited with a non-zero exit code 1
解决问题: 编辑项目下的mapred-site.xml,添加如下属性:
<property>
<name>mapred.remote.os</name>
<value>Linux</value>
<description>Remote MapReduce framework's OS, can be either linux or Windows</description>
</property>
<property>
<name>mapreduce.app-submission.cross-platform</name>
<value>true</value>
</property>
API调用
迁移数据至HBase建议提前手动建好HBase表。
Hbase操作API创建表示例:
调用示例:
手动创建HBase表后,手动调用API,API调用主要有两种方式:一是通过修改Sqoop源码,二是通过Sshxcute 远程连接至主机,操作服务器。
Sqoop源码方式调用:
通过传递不同命令参数,执行不同场景应用。支持全量导入和增量导入,但在进行增量导入时需要手动或者实现其他程序(连接数据据库,获取最新last-value值)来维护last-value值,实现自动更新,本文档暂未提供相关程序
调用示例:
Sshxcute方式调用:
通过SSH方式远程连接服务器,相当于通过程序逻辑实现远程操作,可以通过执行相关命令的方式,也可以通过执行脚本的方式,或者其他方式。支持数据的全量导入和增量导入。在进行数据迁移操作时,建议采用创建Job的方式,并设置sqoop-site.xml保存密码(否则执行Job时需要输入数据库密码),因而在进行增量导入时自动维护last-value值,可以实现自动操作。本文档假设所有相关配置、环境等已搭建完成。