从零开始使用Sqoop
Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(MySQL、PostgreSQL等)间进行数据的传递,可以将一个关系型数据库(例如:MySQL、Oracle、PostgreSQL等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。
前提条件
- 创建集群时已勾选Sqoop组件以及依赖的服务。
- 安装客户端,具体请参考安装客户端(3.x及之后版本)。例如安装目录为“/opt/client”,请根据实际安装目录修改。为使用Sqoop时简单方便,使用Sqoop时需要安装全量客户端。
- 如果集群已开启kerberos认证,需要先创建或获取具有相应权限的用户,用于执行Sqoop命令。创建的用户需要加入“hadoop”、“supergroup”、“hive”组。具体请参考创建用户。
- 客户端目录“/Sqoop/sqoop/lib”下已放置对应JDBC驱动包(例如mysql驱动包mysql-connector-java-5.1.47.jar),并已修改权限和用户组与该目录下其他Jar包保持一致。
sqoop export(HDFS到MySQL)
- 登录Sqoop客户端所在节点。
- 执行如下命令初始化环境变量。
source /opt/client/bigdata_env
- 如果当前集群已启用Kerberos认证,执行kinit命令认证当前用户。如果集群未开启Kerberos认证,直接执行4。
例如,使用sqoop_user用户进行认证:
kinit sqoop_user
- 使用sqoop命令操作sqoop客户端。
sqoop export --connect jdbc:mysql://10.100.xxx.xxx:3306/test --username root --password xxx --table component13 -export-dir hdfs://hacluster/user/hive/warehouse/component_test3 --fields-terminated-by ',' -m 1
更多参数介绍请参见Sqoop常用命令及参数介绍。
表1 参数说明 参数
说明
--connect
指定JDBC连接的URL,格式为:jdbc:mysql://MySQL数据库IP地址:MySQL的端口/数据库名称。
--username
连接MySQL数据库的用户名。
-password
连接MySQL数据库的用户密码。命令中如果携带认证密码信息可能存在安全风险,在执行命令前建议关闭系统的history命令记录功能,避免信息泄露。
-table <table-name>
MySQL中用于存放导出数据的表名称。
-export-dir <dir>
需要导出的Sqoop表所在的HDFS路径。
--fields-terminated-by
指定导出数据的分隔符,与需要导出的HDFS中的数据表中的分隔符保持一致。
-m或-num-mappers <n>
启动n个map来并行导入数据,默认是4个,该值请勿高于集群的最大Map数。
-direct
快速模式,利用了数据库的导入工具,如MySQL的mysqlimport,可以比jdbc连接的方式更为高效的将数据导入到关系数据库中。
-update-key <col-name>
后面接条件列名,通过该参数可以将关系数据库中已经存在的数据进行更新操作,类似于关系数据库中的update操作。
-update-mode <mode>
更新模式,有两个值updateonly和默认的allowinsert,该参数只能在关系数据表里不存在要导入的记录时才能使用,例如要导入的HDFS中有一条id=1的记录,如果在表里已经有一条记录id=2,则更新会失败。
-input-null-string <null-string>
可选参数,如果没有指定,则字符串null将被使用。
-input-null-non-string <null-string>
可选参数,如果没有指定,则字符串null将被使用。
-staging-table <staging-table-name>
创建一个与导入目标表同样数据结构的表,将所有数据先存放在该表中,然后由该表通过一次事务将结果写入到目标表中。
该参数是用来保证在数据导入关系数据库表的过程中的事务安全性,如果在导入的过程中可能会有多个事务,则一个事务失败会影响到其它事务。如果导入的数据会出现错误或出现重复的记录等情况,则通过该参数可以避免这种情况。
-clear-staging-table
如果该staging-table非空,则通过该参数可以在运行导入前清除staging-table里的数据。
sqoop import(MySQL到Hive表)
- 登录Sqoop客户端所在节点。
- 执行如下命令初始化环境变量。
source /opt/client/bigdata_env
- 如果当前集群已启用Kerberos认证,执行kinit命令认证当前用户。如果集群未开启Kerberos认证,直接执行4。
例如,使用sqoop_user用户进行认证:
kinit sqoop_user
- 使用sqoop命令操作sqoop客户端。
sqoop import --connect jdbc:mysql://10.100.xxx.xxx:3306/test --username root --password xxx --table component --hive-import --hive-table component_test2 --delete-target-dir --fields-terminated-by "," -m 1 --as-textfile
表2 参数说明 参数
说明
--hive-import
表示从关系型数据库中导入数据到MRS Hive中。
--delete-target-dir
若Hive中已存在目标文件,则先删除该文件再导入。
-append
将数据追加到HDFS中已经存在的dataset中。使用该参数,sqoop将把数据先导入到一个临时目录中,然后重新给文件命名到一个正式的目录中,以避免和该目录中已存在的文件重名。
-as-avrodatafile
将数据导入到一个Avro数据文件中。
-as-sequencefile
将数据导入到一个sequence文件中。
-as-textfile
将数据导入到一个普通文本文件中,生成该文本文件后,可以在Hive中通过sql语句查询出结果。
--as-parquetfile
将数据导入到Parquet文件中
-boundary-query <statement>
边界查询,在导入前先通过SQL查询得到一个结果集,然后导入的数据就是该结果集内的数据,格式如:-boundary-query 'select id,creationdate from person where id = 3',表示导入的数据为id=3的记录,或者select min(<split-by>), max(<split-by>) from <table name>。
注意:查询的字段中不能有数据类型为字符串的字段,否则会报错:java.sql.SQLException: Invalid value for getLong()。
-columns<col,col,col…>
指定要导入的字段值,格式如:-columns id,username
-direct
快速模式,利用了数据库的导入工具,如MySQL的mysqlimport,可以比jdbc连接的方式更为高效的将数据导入到关系数据库中。
-direct-split-size
在使用上面direct直接导入的基础上,对导入的流按字节数分块,特别是使用直连模式从PostgreSQL导入数据时,可以将一个到达设定大小的文件分为几个独立的文件。
-inline-lob-limit
设定大对象数据类型的最大值。
-m或-num-mappers
启动n个map来并行导入数据,默认是4个,该值请勿高于集群的最大Map数。
-query,-e<statement>
从查询结果中导入数据,该参数使用时必须指定-target-dir、-hive-table,在查询语句中一定要有where条件且在where条件中需要包含$CONDITIONS。
示例:-query 'select * from person where $CONDITIONS ' -target-dir /user/hive/warehouse/person -hive-table person
-split-by<column-name>
表的列名,用来切分工作单元,一般后面跟主键ID。
-table <table-name>
关系数据库表名,数据从该表中获取。
-target-dir <dir>
指定HDFS路径。
-warehouse-dir <dir>
与-target-dir不能同时使用,指定数据导入的存放目录,适用于导入HDFS,不适合导入Hive目录。
-where
从关系数据库导入数据时的查询条件,示例:-where 'id = 2'
-z,-compress
压缩参数,默认数据不压缩,通过该参数可以使用gzip压缩算法对数据进行压缩,适用于SequenceFile,text文本文件,和Avro文件。
–compression-codec
Hadoop压缩编码,默认为gzip。
–null-string <null-string>
替换null字符串,如果没有指定,则字符串null将被使用。
–null-non-string<null-string>
替换非String的null字符串,如果没有指定,则字符串null将被使用。
-check-column (col)
增量导入参数,用来作为判断的列名,如id。
-incremental (mode) append
或lastmodified
增量导入参数。
append:追加,例如对大于last-value指定的值之后的记录进行追加导入。
lastmodified:最后的修改时间,追加last-value指定的日期之后的记录。
-last-value (value)
增量导入参数,指定自从上次导入后列的最大值(大于该指定的值),也可以自己设定某一值。
Sqoop使用样例
- sqoop import(MySQL到HDFS)
sqoop import --connect jdbc:mysql://10.100.231.134:3306/test --username root --password xxx --query 'SELECT * FROM component where $CONDITIONS and component_id ="MRS 1.0_002"' --target-dir /tmp/component_test --delete-target-dir --fields-terminated-by "," -m 1 --as-textfile
- sqoop export (obs到MySQL)
sqoop export --connect jdbc:mysql://10.100.231.134:3306/test --username root --password xxx --table component14 -export-dir obs://obs-file-bucket/xx/part-m-00000 --fields-terminated-by ',' -m 1
- sqoop import(MySQL到obs)
sqoop import --connect jdbc:mysql://10.100.231.134:3306/test --username root --password xxx --table component --target-dir obs://obs-file-bucket/xx --delete-target-dir --fields-terminated-by "," -m 1 --as-textfile
- sqoop import(MySQL到Hive外obs表)
sqoop import --connect jdbc:mysql://10.100.231.134:3306/test --username root --password xxx --table component --hive-import --hive-table component_test01 --fields-terminated-by "," -m 1 --as-textfile
导入或导出数据时缺少MySQL驱动包
若执行sqoop import或sqoop export命令报错“Could not load db driver class: com.mysql.jdbc.Driver”,如图1所示,则表示缺少MySQL驱动包,需在MySQL官网下载对应MySQL驱动包,解压并上传至“客户端安装目录/Sqoop/sqoop/lib”目录下,再执行Sqoop导入或导出数据命令即可