Sqoop高级操作[译]
默认分类
2020-01-15
468
0
Apache Sqoop(TM) 是用来从关系型数据库系统导入数据到Hadoop或者从Hadoop中导出数据到关系型数据库的工具.
在之前Sqoop的文章中我们讨论了以下内容:
- 从MySQL导入指定表至HDFS
- 将数据库中所有表导入到HDFS
- 将表导入到指定的HDFS目录
- 导入指定表到HDFS(感觉跟上面重了啊)
- 导入表到HDFS并保存为Sequence格式文件
- Sqoop增量导入
- 从HDFS导出数据到MySQL表中
更多信息建议看我们之前的文章:
https://acadgild.com/blog/beginners-guide-for-sqoop/ https://acadgild.com/blog/sqoop-tutorial-incremental-imports/
本文中,我们将讨论以下操作
- 密码保护技术
- 导入到HDFS后的数据压缩
- 并行控制
- 快速传输
- null值处理
密码保护技术
直接在你的命令行里面写上密码是极其危险的.因此Sqoop提供了两个选项来保护你的密码.让我们看看它们是如何应用的吧.
从标准输入读取密码
下图是我们的MySQL数据库,他有一个名为AcadGild,里面有个employee表.
现在我们将数据导入到HDFS
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee -P
用户在最后加一个**-P**参数执行的时候会要求数据密码
上图中你可以看到Sqoop提示用户输入密码. 这是密码保护的第一种方式.
从文件读取密码
先将密码写入一个文件
echo -n "kiran0541" >> mysql_sqoop_password
注意,你需要在echo后面加上**-n选项,否则一个输出的文件里面会有一个新的空白行.Sqoop会一起读入,然后导致Access Denied for User**错误.
密码文件在本地
我们在本地创建一个文件,可以使得Sqoop放问它,另外你可以把文件的权限设置成400,这样其他用户就无法查看这个文件.
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee --password-file file:///home/kiran/mysql_sqoop_password --driver com.mysql.jdbc.Driver -m1
密码文件在HDFS
同本地文件一样,你可以设置400防止别人访问.
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee --password-file mysql_sqoop_password --driver com.mysql.jdbc.Driver -m1
Sqoop 错误
如果你导入的时候碰到以下错误此时你需要指定**–driver com.mysql.jdbc.Driver**参数.
ERROR manager.SqlManager: Error reading from database: java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDynamic@277f7dd3 is still active. No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries.
java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDynamic@277f7dd3 is still active. No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries.
如果你的MySQL表没有主键,会显示下面这个错误.
ERROR tool.ImportTool: Error during import: No primary key could be found for table employee. Please specify one with –split-by or perform a sequential import with ‘-m 1’.
此时需要指定**-m1**选项.这样Sqoop会限制mapper的数量为1.一次只传送一条数据.
压缩导入的数据
为了减小导入HDFS数据的大小,我们可以使用**-compress**选项.
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee -P --driver com.mysql.jdbc.Driver -m1 --compress
并行控制
默认情况下Sqoop的并行数量为4 ,我们可以使用**–num-mappers**指定 mappers的数量
快速传送
Sqoop 支持快速传输.你可以使用 –direct 参数提升传输速度. 通常Sqoop使用JDBC作为一个接口传输数据.direct模式则使用数据库提供的原生组件进行传送.在MySQL中有两种这样的工具mysqldump和mysqlimport. Sqoop使用pg_dump导入数据.
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee -P --driver com.mysql.jdbc.Driver -m1 --direct
处理Null值
我们在MySQL的表中加了一些null值,让我们看看Sqoop如何处理这些null值
sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee -P --driver com.mysql.jdbc.Driver -m1 --null-string '\\N' --null-non-string '\\N'
这里使用**\N**来替换空值,我们需要指定参数 -ull-string 或 –null-non-string
我们使用**–null-string来转换Char, Varchar, Nchar, Text 的值,其余的通过–null-non-string**转换
MySQL表中的数据:
现在我们使用Sqoop来传输这些包含空值的数据
现在我们看下HDFS中的数据 ,如下图所示空值已经被替换为**\N**
希望这篇文章对你使用Sqoop有帮助,更多内容请关注www.acadgild.com