
# Sqoop客户端使用实践
Sqoop是一款开源的工具，主要用于在Hadoop与传统的数据库间进行数据的传递，可以将一个关系型数据库（例如MySQL、Oracle、PostgreSQL等）中的数据导进到Hadoop的HDFS中，也可以将HDFS的数据导出到关系型数据库中。
#### 前提条件
- MRS 3.1.0及之后版本在创建集群时已勾选Sqoop组件。
- 安装客户端，具体请参考[安装客户端（3.x及之后版本）](https://support.huaweicloud.com/cmpntguide-mrs/mrs_01_2127.html)。
  例如安装目录为"/opt/client"，以下操作的客户端目录只是举例，请根据实际安装目录修改。
  
- 客户端目录/Sqoop/sqoop/lib下已有对应驱动包（例mysql驱动包mysql-connector-java-5.1.47.jar），如果没有请参考[Sqoop1.4.7适配MRS 3.x集群](https://support.huaweicloud.com/cmpntguide-mrs/mrs_01_24455.html)章节中的步骤[3](https://support.huaweicloud.com/cmpntguide-mrs/mrs_01_24455.html#mrs_01_24455__l945d89eadc024485b6c0bd53e78cfce4)下载对应MySQL包。
 
#### sqoop export（HDFS到MySQL）
1. 登录客户端所在节点。
2. 执行如下命令初始化环境变量。 
   **source /opt/client/bigdata_env**
   
   
3. 使用sqoop命令进行数据导出操作。 
   **sqoop export --connect jdbc:mysql://** *10.10.* *xxx* **.** *xxx* **:** *3306/test* **--username root** **--table** *component13* **--export-dir hdfs://hacluster/** *user/hive/warehouse/component_test3* **--fields-terminated-by ',' -m 1** **-P**
   *输入用户名密码*
   更多参数介绍请参见[Sqoop常用命令及参数介绍](https://support.huaweicloud.com/cmpntguide-mrs/mrs_01_24456.html)。
   表1参数说明 
   | 参数                                      | 说明                                                                                                                                                                                              |
   |:---|:---|
   | --connect                               | 指定JDBC连接的URL，格式为：**jdbc:mysql://** *MySQL数据库IP地址* :*MySQL的端口* /*数据库名称*。                                                                                                                         |
   | --username                              | 连接MySQL数据库的用户名。                                                                                                                                                                                 |
   | -P                                      | 交互式输入连接MySQL数据库的密码。建议使用此参数避免信息泄漏，其他方式存在一定的安全风险。                                                                                                                                                 |
   | --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表）
1. 登录客户端所在节点。
2. 执行如下命令初始化环境变量。 
   **source /opt/client/bigdata_env**
   
   
3. 使用sqoop命令进行数据导入操作。 
   **sqoop import --connect jdbc:mysql://10.100.** *xxx* **.** *xxx* **:** *3306* **/** *test* **--username root** **--table component --hive-import --hive-table** *component_test2* **--delete-target-dir --fields-terminated-by "," -m 1 --as-textfile** **-P**
   *输入用户名密码*
   表2参数说明 
   | 参数                                       | 说明                                                                                                                                                                                                                                                                                                                             |
   |:---|:---|
   | --hive-import                            | 表示从关系型数据库中导入数据到MRS Hive中。                                                                                                                                                                                                                                                                                                      |
   | --delete-target-dir                      | 若Hive中已存在目标文件，则先删除该文件再导入。                                                                                                                                                                                                                                                                                                      |
   | --append                                 | 将数据追加到hdfs中已经存在的dataset中。使用该参数，sqoop将把数据先导入到一个临时目录中，然后重新给文件命名到一个正式的目录中，以避免和该目录中已存在的文件重名。                                                                                                                                                                                                                                       |
   | --as-avrodatafile                        | 将数据导入到一个Avro数据文件中。                                                                                                                                                                                                                                                                                                             |
   | --as-sequencefile                        | 将数据导入到一个sequence文件中。                                                                                                                                                                                                                                                                                                           |
   | --as-textfile                            | 将数据导入到一个普通文本文件中，生成该文本文件后，可以在hive中通过sql语句查询出结果。                                                                                                                                                                                                                                                                                 |
   | --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数。                                                                                                                                                                                                                                                                                          |
   | -e,--query \<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.10.231.134:3306/test --username root** **--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** **-P**
  
- sqoop export （OBS到MySQL） **sqoop export --connect jdbc:mysql://10.10.231.134:3306/test --username root** **--table component14 --export-dir obs://obs-file-bucket/xx/part-m-00000 --fields-terminated-by ',' -m 1** **-P**
  
- sqoop import（MySQL到OBS） **sqoop import --connect jdbc:mysql://10.100.231.134:3306/test --username root** **--table component --target-dir obs://obs-file-bucket/xx --delete-target-dir --fields-terminated-by "," -m 1 --as-textfile** **-P**
  
- sqoop import（MySQL到Hive外obs表） **sqoop import --connect jdbc:mysql://10.100.231.134:3306/test --username root** **--table component --hive-import --hive-table component_test01 --fields-terminated-by "," -m 1 --as-textfile** **-P**
  
 
#### 导入或导出数据时缺少MySQL驱动包
若执行**sqoop import** 或**sqoop export** 命令报错"Could not load db driver class: com.mysql.jdbc.Driver"，如[图1]所示，则表示缺少MySQL驱动包，需在MySQL官网下载对应MySQL驱动包，解压并上传至"*客户端安装目录*/Sqoop/sqoop/lib"目录下，再执行Sqoop导入或导出数据命令即可。
图1缺少MySQL驱动包报错   
![](https://support.huaweicloud.com/cmpntguide-mrs/zh-cn_image_0000001763992937.png)
