3 Sqoop 导出
将数据从 Hadoop 生态体系导出到 RDBMS 数据库导出前,目标表必须存在于
目标数据库中。
export 有三种模式:
默认操作是从将文件中的数据使用 INSERT 语句插入到表中。
更新模式:Sqoop 将生成 UPDATE 替换数据库中现有记录的语句。
调用模式:Sqoop 将为每条记录创建一个存储过程调用。
以下是 export 命令语法:
$ sqoop export (generic-args) (export-args)
3.1 默认模式导出 HDFS 数据到 mysql
默认情况下,sqoop export 将每行输入记录转换成一条 INSERT 语句,添加到目标数据库表中。如果数据库中的表具有约束条件(例如,其值必须唯一的主键列)并且已有数据存在,则必须注意避免插入违反这些约束条件的记录。如果INSERT 语句失败,导出过程将失败。此模式主要用于将记录导出到可以接收这些结果的空表中。通常用于全表数据导出。
导出时可以是将 Hive 表中的全部记录或者 HDFS 数据(可以是全部字段也可以部分字段)导出到 Mysql 目标表。
3.1.1 准备 HDFS 数据
在 HDFS 文件系统中“/emp/”目录的下创建一个文件 emp_data.txt:
1201,gopal,manager,50000,TP 1202,manisha,preader,50000,TP 1203,kalil,php dev,30000,AC 1204,prasanth,php dev,30000,AC 1205,kranthi,admin,20000,TP 1206,satishp,grpdes,20000,GR
3.1.2 手动创建 mysql 中的目标表
mysql> USE userdb; mysql> CREATE TABLE employee ( id INT NOT NULL PRIMARY KEY, name VARCHAR(20), deg VARCHAR(20), salary INT, dept VARCHAR(10));
3.1.3 执行导出命令
bin/sqoop export \ --connect jdbc:mysql://node-1:3306/userdb \ --username root \ --password hadoop \ --table employee \ --export-dir /emp/emp_data
3.1.4 相关配置参数
--input-fields-terminated-by '\t'
指定文件中的分隔符
--columns
选择列并控制它们的排序。当导出数据文件和目标表字段列顺序完全一致的时候可以不写。否则以逗号为间隔选择和排列各个列。没有被包含在–columns 后面列名或字段要么具备默认值,要么就允许插入空值。否则数据库会拒绝接受 sqoop 导出的数据,导致 Sqoop 作业失败
--export-dir导出目录,在执行导出的时候,必须指定这个参数,同时需要具
备–table 或–call 参数两者之一,–table 是指的导出数据库当中对应的表,
--call 是指的某个存储过程。
--input-null-string --input-null-non-string如果没有指定第一个参数,对于字符串类型的列来说,“NULL”这个字符串就回被翻译成空值,如果没有使用第二个参数,无论是“NULL”字符串还是说空字符串也好,对于非字符串类型的字段来说,这两个类型的空串都会被翻译成空值。比如:
--input-null-string "\\N" --input-null-non-string "\\N"
3.2 更新导出(updateonly 模式)
2.1. 参数说明
– update-key,更新标识,即根据某个字段进行更新,例如 id,可以指定多
个更新标识的字段,多个字段之间用逗号分隔。
– updatemod,指定 updateonly(默认模式),仅仅更新已存在的数据记录,
不会插入新纪录。
2.2. 准备 HDFS 数据
在 HDFS “/updateonly_1/”目录的下创建一个文件 updateonly_1.txt:
1201,gopal,manager,50000
1202,manisha,preader,50000
1203,kalil,php dev,30000
2.3. 手动创建 mysql 中的目标表
mysql> USE userdb;
mysql> CREATE TABLE updateonly (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20),
deg VARCHAR(20),
salary INT);
2.4. 先执行全部导出操作
bin/sqoop export
–connect jdbc:mysql://node-1:3306/userdb
–username root
–password hadoop
–table updateonly
–export-dir /updateonly_1/
2.5. 查看此时 mysql 中的数据
可以发现是全量导出,全部的数据
2.6. 新增一个文件
updateonly_2.txt 。修改 了 前 三条 数 据并且 新 增 了一 条 记录 。 上传至
/updateonly_2/目录下:
1201,gopal,manager,1212
1202,manisha,preader,1313
1203,kalil,php dev,1414
1204,allen,java,1515
2.7. 执行更新导出
bin/sqoop export
–connect jdbc:mysql://node-1:3306/userdb
–username root --password hadoop
–table updateonly
–export-dir /updateonly_2/
–update-key id
–update-mode updateonly
2.8. 查看最终结果
虽然导出时候的日志显示导出 4 条记录:
但最终只进行了更新操作
3. 更新导出(allowinsert 模式)
3.1. 参数说明
– update-key,更新标识,即根据某个字段进行更新,例如 id,可以指定多
个更新标识的字段,多个字段之间用逗号分隔。
– updatemod,指定 allowinsert,更新已存在的数据记录,同时插入新纪录。 实质上是一个 insert & update 的操作。
3.2. 准备 HDFS 数据
在 HDFS “/allowinsert_1/”目录的下创建一个文件 allowinsert_1.txt:
1201,gopal,manager,50000
1202,manisha,preader,50000
1203,kalil,php dev,30000
3.3. 手动创建 mysql 中的目标表
mysql> USE userdb;
mysql> CREATE TABLE allowinsert (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20),
deg VARCHAR(20),
salary INT);
3.4. 先执行全部导出操作
bin/sqoop export
–connect jdbc:mysql://node-1:3306/userdb
–username root
–password hadoop
–table allowinsert
–export-dir /allowinsert_1/
3.5. 查看此时 mysql 中的数据
可以发现是全量导出,全部的数据
3.6. 新增一个文件
allowinsert_2.txt。修改了前三条数据并且新增了一条记录。上传至/
allowinsert_2/目录下:
1201,gopal,manager,1212
1202,manisha,preader,1313
1203,kalil,php dev,1414
1204,allen,java,1515
3.7. 执行更新导出
bin/sqoop export
–connect jdbc:mysql://node-1:3306/userdb
–username root --password hadoop
–table allowinsert
–export-dir /allowinsert_2/
–update-key id
–update-mode allowinsert
3.8. 查看最终结果
导出时候的日志显示导出 4 条记录:
数据进行更新操作的同时也进行了新增的操作
4 Sqoop job 作业
1. job 语法
$ sqoop job (generic-args) (job-args)
[-- [subtool-name] (subtool-args)]
$ sqoop-job (generic-args) (job-args)
[-- [subtool-name] (subtool-args)]
2. 创建 job
在这里,我们创建一个名为 itcastjob,这可以从 RDBMS 表的数据导入到
HDFS 作业。
下面的命令用于创建一个从 DB 数据库的 emp 表导入到 HDFS 文件的作业。
bin/sqoop job --create itcastjob – import --connect jdbc:mysql://node-
1:3306/userdb
–username root
–password hadoop
–target-dir /sqoopresult333
–table emp --m 1
注意 import 前要有空格
3. 验证 job
‘–list’ 参数是用来验证保存的作业。下面的命令用来验证保存 Sqoop 作业的
列表。
bin/sqoop job --list
4. 检查 job
‘–show’ 参数用于检查或验证特定的工作,及其详细信息。以下命令和样本
输出用来验证一个名为 itcastjob 的作业。
bin/sqoop job --show itcastjob
5. 执行 job
‘–exec’ 选项用于执行保存的作业。下面的命令用于执行保存的作业称为
itcastjob。
bin/sqoop job --exec itcastjob
6. 免密执行 job
sqoop 在创建 job 时,使用–password-file 参数,可以避免输入 mysql 密码,
如果使用–password 将出现警告,并且每次都要手动输入密码才能执行 job,sqoop
规定密码文件必须存放在 HDFS 上,并且权限必须是 400。
并且检查 sqoop 的 sqoop-site.xml 是否存在如下配置:
sqoop.metastore.client.record.password
true
If true, allow saved passwords in the metastore.
bin/sqoop job --create itcastjob1 – import --connect jdbc:mysql://cdh-
1:3306/userdb
–username root
–password-file /input/sqoop/pwd/itcastmysql.pwd
–target-dir /sqoopresult333
–table emp --m 1
5 Apache Sqoop 小结
sqoop 安装验证
bin/sqoop list-databases \ --connect jdbc:mysql://localhost:3306/ \ --username root --password hadoop
注意事项:命令携带参数必须出现在一行中,若换行就意味着自动提交执行,可通过\表示未结束。
全量导入数据到hdfs
mysql的地址尽量不要使用localhost 请使用ip或者host
如果不指定 导入到hdfs默认分隔符是 “,”
可以通过-- fields-terminated-by '\ t‘ 指定具体的分隔符
如果表的数据比较大 可以并行启动多个maptask执行导入操作,如果表没有主键,请指定根据哪个字段进行切分
bin/sqoop import \ --connect jdbc:mysql://node-1:3306/userdb \ --username root \ --password hadoop \ --target-dir /sqoopresult214 \ --fields-terminated-by '\t' \ --split-by id \ --table emp --m 2
导入表数据子集(query查询)
使用 query sql 语句来进行查找不能加参数–table ;
并且必须要添加 where 条件;
并且 where 条件后面必须带一个$CONDITIONS 这个字符串;
并且这个 sql 语句必须用单引号,不能用双引号;
增量数据的导入
所谓的增量数据指的是上次至今中间新增加的数据
sqoop支持两种模式的增量导入
append追加 根据数值类型字段进行追加导入 大于指定的last-value
lastmodified 根据时间戳类型字段进行追加 大于等于指定的last-value
注意在lastmodified 模式下 还分为两种情形:append merge-key
关于lastmodified 中的两种模式:
append 只会追加增量数据到一个新的文件中 并且会产生数据的重复问题
因为默认是从指定的last-value 大于等于其值的数据开始导入
merge-key 把增量的数据合并到一个文件中 处理追加增量数据之外 如果之前的数据有变化修改
也可以进行修改操作 底层相当于进行了一次完整的mr作业。数据不会重复。
数据导出操作
注意:导出的目标表需要自己手动提前创建 也就是sqoop并不会帮我们创建复制表结构
导出有三种模式:
默认模式 目标表是空表 底层把数据一条条insert进去
更新模式 底层是update语句
调用模式 调用存储过程
相关配置参数
导出文件的分隔符 如果不指定 默认以“,”去切割读取数据文件 --input-fields-terminated-by
如果文件的字段顺序和表中顺序不一致 需要–columns 指定 多个字段之间以","
导出的时候需要指定导出数据的目的 export-dir 和导出到目标的表名或者存储过程名
针对空字符串类型和非字符串类型的转换 “\n”
更新导出
updateonly 只更新已经存在的数据 不会执行insert增加新的数据
allowinsert 更新已有的数据 插入新的数据 底层相当于insert&update