1.什么是Sqoop
Sqoop即 SQL to Hadoop ,是一款方便的在传统型数据库与Hadoop之间进行数据迁移的工具,是hadoop与关系型数据库的桥梁,它支持关系型数据库和hive、hdfs,hbase之间数据的相互导入,可以使用全表导入和增量导入。
Sqoop充分利用MapReduce并行特点以批处理的方式加快数据传输,发展至今主要演化了二大版本,Sqoop1和Sqoop2。
2. 安装
我的 Hadoop版本为2.5,
1) 下载 sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz,解压即可。
2) 将mysql-connector的jar包(5.1.34版本)复制至sqoop解压后的lib目录下。
2. 配置
在修改:sqoop/conf/sqoop-env.sh
export HADOOP_COMMON_HOME=/data/app/hadoop-2.5.0 export HADOOP_MAPRED_HOME=/data/app/hadoop-2.5.0
修改SQOOP的文件configure-sqoop
注释掉hbase和zookeeper检查(除非你准备使用HABASE等HADOOP上的组件), 否则会报Waring提示
3. 测试
查看语法: $ ./bin/sqoop --help
或者 ./bin/sqoop help import
查看数据库
$ ./sqoop list-databases --connect jdbc:mysql://IP_ADDRESS:3306/ --username root -P information_schema test hive mysql performance_schema
如上所示则连接mysql数据库成功! -P表示输入密码 可以直接使用--password来制定密码
4. 常用命令
4.1 Mysql数据导入到HDFS
通过以下shell脚本从mysql数据库向hdfs导入数据
导入时,要建立对应的mysql帐号,如果是分布式的,mysql要对每台都授权。
4.1.1 常用
$ ./sqoop import --connect jdbc:mysql://IP_ADDRESS:3306/DATA_BASE --table DATA_BASE --username root --password 123 -m 1 --target-dir /user/hive/result
--target-dir 指定导入的目录,
--hive-import 数据导入hive空间中,如果不使用该选项,复制到hdfs中.
-m 表示启动几个map任务来读取数据 如果数据库中的表没有主键这个参数是必须设置的而且只能设定为1 , 而这个参数设置为几会直接决定导入的文件在hdfs上面是分成几块的 比如 设置为1 则会产生一个数据文件,
4.1.2 使用 sql 语句
参照上表,使用 sql 语句查询时,需要指定 $CONDITIONS
$ ./bin/sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password 123456 --query SELECT * from TBLS where $CONDITIONS --split-by tbl_id -m 4 --target-dir /user/hive/result
4.1.3 使用 direct 模式:
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --delete-target-dir --direct --default-character-set UTF-8 --target-dir /user/hive/result
4.1.4 如果需要指定压缩:
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by " " --lines-terminated-by " " --delete-target-dir --null-string N --null-non-string N --compression-codec "com.hadoop.compression.lzo.LzopCodec" --target-dir /user/hive/result
$ ./sqoop import --connect jdbc:mysql://IP_ADDRESS:3306/DATA_BASE --table DATA_BASE --username root --password 123 -m 1 --target-dir /user/hive/result --hive-import方式2
$ sqoop create-hive-table --connect jdbc:mysql://192.168.56.121:3306/metastore --table users --username hiveuser --password redhat --hive-table users方式3 使用column 和 where把 mysql导出到hive中:
sqoop import --connect jdbc:mysql://192.168.1.1:3306/kettle --username root --password 123456 --table student --columns "id,age,name" --where "id > 3 and (age = 88 or age = 80)" -m 1 --target-dir /user/hive/warehouse/userinfos2 --fields-terminated-by ",";
注意:--target-dir /user/hive/warehouse/userinfos2 可以用 --hive-import --hive-table userinfos2 进行替换
4.3 Mysql数据导入到Hbase
$ ./sqoop import --connect jdbc:mysql://IP_ADDRESS:3306/DATA_BASE --table TABLE_NAME --username root --password 123 -m 1 --hbase-create-table --hbase-table student2 --column-family info --hbase-row-key sid
选项解释
--hbase-create-table 自动在HBase中创建表
--column-family 指定列族名
--hbase-row-key 指定rowkey对应的mysql的键
4.4 HDFS中的数据导出到mysql
表名必须存在
$ ./sqoop export --connect jdbc:mysql://IP_ADDRESS:3306/DATA_BASE --table TABLE_NAME --username root --password 123 --export-dir '/output/student2'
4.5 hive中的数据导出到mysql
$ ./sqoop export --connect jdbc:mysql://IP_ADDRESS:3306/DATA_BASE --table TABLE_NAME --username root --password 123 --export-dir '/hivefile/student2'
和4.4相似 ,只需要修改export-dir目录为hive目录
4.6 HBase中数据导出到mysql
目前没有直接的命令将HBase中的数据导出到MySQL,但可以先将HBase中的数据导出到HDFS中,再将数据导出到MySQL。
参数 | 说明 |
---|---|
--hive-home
|
Hive的安装目录,可以通过该参数覆盖掉默认的hive目录 |
--hive-overwrite | 覆盖掉在hive表中已经存在的数据 |
--create-hive-table | 默认是false,如果目标表已经存在了,那么创建任务会失败 |
--hive-table | 后面接要创建的hive表 |
--table | 指定关系数据库表名 |
参数 | 说明 |
--append | 将数据追加到hdfs中已经存在的dataset中。使用该参数,sqoop将把数据先导入到一个临时目录中,然后重新给文件命名到一个正式的目录中,以避免和该目录中已存在的文件重名。 |
--as-avrodatafile | 将数据导入到一个Avro数据文件中| |
--as-sequencefile | 将数据导入到一个sequence文件中 |
--as-textfile | 将数据导入到一个普通文本文件中,生成该文本文件后,可以在hive中通过sql语句查询出结果。 |
--boundary-query |
|
--columns | 指定要导入的字段值,格式如:--columns id,username |
--direct | 直接导入模式,使用的是关系数据库自带的导入导出工具。官网上是说这样导入会更快 |
--direct-split-size | 在使用上面direct直接导入的基础上,对导入的流按字节数分块,特别是使用直连模式从PostgreSQL导入数据的时候,可以将一个到达设定大小的文件分为几个独立的文件。 |
--inline-lob-limit | 设定大对象数据类型的最大值 |
-m,--num-mappers | 启动N个map来并行导入数据,默认是4个,最好不要将数字设置为高于集群的节点数 |
--query,-e |
从查询结果中导入数据,该参数使用时必须指定–target-dir、–hive-table,在查询语句中一定要有where条件且在where条件中需要包含 $CONDITIONS,示例:--query select * from t where $CONDITIONS --target-dir /tmp/t –hive-table t |
--split-by |
表的列名,用来切分工作单元,一般后面跟主键ID |
--table |
关系数据库表名,数据从该表中获取 |
--delete-target-dir | 删除目标目录 |
--target-dir
|
指定hdfs路径 |
--warehouse-dir
|
与 --target-dir 不能同时使用,指定数据导入的存放目录,适用于hdfs导入,不适合导入hive目录 |
--where | 从关系数据库导入数据时的查询条件,示例:--where "id = 2" |
-z,--compress | 压缩参数,默认情况下数据是没被压缩的,通过该参数可以使用gzip压缩算法对数据进行压缩,适用于SequenceFile, text文本文件, 和Avro文件 |
--compression-codec | Hadoop压缩编码,默认是gzip |
--null-string |
可选参数,如果没有指定,则字符串null将被使用 |
--null-non-string |
可选参数,如果没有指定,则字符串null将被使用| |
附:可选的文件参数如下表。
参数 | 说明 |
---|---|
--enclosed-by |
给字段值前后加上指定的字符,比如双引号,示例:--enclosed-by ",显示例子:"3","jimsss","dd@dd.com" |
--escaped-by |
给双引号作转义处理,如字段值为"测试",经过 --escaped-by "" 处理后,在hdfs中的显示值为:"测试",对单引号无效 |
--fields-terminated-by |
设定每个字段是以什么符号作为结束的,默认是逗号,也可以改为其它符号,如句号.,示例如:--fields-terminated-by |
--lines-terminated-by |
设定每条记录行之间的分隔符,默认是换行串,但也可以设定自己所需要的字符串,示例如:--lines-terminated-by "#" 以#号分隔 |
--mysql-delimiters | Mysql默认的分隔符设置,字段之间以,隔开,行之间以换行 隔开,默认转义符号是,字段值以单引号包含起来。 |
--optionally-enclosed-by |
enclosed-by是强制给每个字段值前后都加上指定的符号,而--optionally-enclosed-by只是给带有双引号或单引号的字段值加上指定的符号,故叫可选的 |
6 创建job,运行job
刚刚我们使用了import和export命令进行了常规的导入导出操作,但是每次都要我们使用那么长的命令不太容易记忆。于是,我们可以将其创建为一个job,每次需要使用时只需要记住job名,运行job即可。
这里以导入为例,创建一个名为myjob1的job:
sqoop job --create myjob1 -- import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TBLS --fields-terminated-by ' ' -m 1 --append
可以通过命令查看是否存在job:sqoop job --list
执行刚刚创建的job:
sqoop job --exec myjob1
但是,我们发现上面的设置后还需要我们输入密码,这样便无法做到真正的自动执行job。
于是,我们做一点小小的配置(hive-site.xml)修改:将下面的xml配置的注释移除即可
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>If true, allow saved passwords in the metastore. </description>
</property>
移除之后,还需要将刚刚那个job删除掉,重新创建job后才可以无密码自动执行。
--create 创建一个新的job. --delete 删除job --exec 执行job --show 显示job的参数 --list 列出所有的job #创建job $ sqoop job --create myjob -- import --connect jdbc:mysql://example.com/db --table mytable #列出所有job $ sqoop job --list #查看job $ sqoop job --show myjob #执行job $ sqoop job --exec myjob