Sqoop高级操作[译]

A-complete-guide-for-Sqoop

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表.

data_in_mysql

现在我们将数据导入到HDFS

sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee -P

用户在最后加一个-P参数执行的时候会要求数据密码

standard_password_input

上图中你可以看到Sqoop提示用户输入密码. 这是密码保护的第一种方式.

从文件读取密码

先将密码写入一个文件

echo -n "kiran0541" >> mysql_sqoop_password

copying_passwrd_toa_file.png

注意,你需要在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

paswd_file_from_lffs

密码文件在HDFS

同本地文件一样,你可以设置400防止别人访问.

sqoop import --connect jdbc:mysql://localhost/Acadgild --username root --table employee --password-file mysql_sqoop_password --driver com.mysql.jdbc.Driver -m1

paswd_file_from_hdfs

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

compress_data

并行控制

默认情况下Sqoop的并行数量为4 ,我们可以使用–num-mappers指定 mappers的数量

parallelism_control

快速传送

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

speed_transfer

处理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表中的数据:

null+_values_in_mysql

现在我们使用Sqoop来传输这些包含空值的数据

sqoop_null_handling

现在我们看下HDFS中的数据 ,如下图所示空值已经被替换为\N

Null_value_data_in_hdfs

希望这篇文章对你使用Sqoop有帮助,更多内容请关注www.acadgild.com

原文:A Quick Guide to Advanced Apache Sqoop Operations

打赏支持:支付宝/微信,感谢赏口饭吃