一、安装:
1 解压然后把mysql的驱动放在$SQOOP_HOME/lib 目录中
2. conf/sqoop-en.shexport HADOOP_COMMON_HOME=/home/hadoop/hadoop/hadoop-2.3.0
export HADOOP_MAPRED_HOME=/home/hadoop/hadoop/hadoop-2.3.0
注意事项
1.数据库驱动:在执行sqoop命令的client的sqoop lib目录下面放入驱动jar包即可(CDH默认在/opt/cloudera/parcels/CDH/lib/sqoop/lib/目录),驱动版本使用mysql-connector-java-5.1.32-bin.jar以上。2.client端JDK版本1.6~1.7,并且配置环境变量
命令
二、sqoop工具import
sqoop工具汇总
选项
含义说明
--connect <jdbc-uri>
指定JDBC连接字符串
--connection-manager <class-name>
指定要使用的连接管理器类
--driver <class-name>
指定要使用的JDBC驱动类
--hadoop-mapred-home <dir>
指定$HADOOP_MAPRED_HOME路径
--help
万能帮助
--password-file
设置用于存放认证的密码信息文件的路径
-P
从控制台读取输入的密码
--password <password>
设置认证密码
--username <username>
设置认证用户名
--verbose
打印详细的运行信息
--connection-param-file <filename>
可选,指定存储数据库连接参数的属性文件
选项
含义说明
--append
将数据追加到HDFS上一个已存在的数据集上
--as-avrodatafile
将数据导入到Avro数据文件
--as-sequencefile
将数据导入到SequenceFile
--as-textfile
将数据导入到普通文本文件(默认)
--boundary-query <statement>
边界查询,用于创建分片(InputSplit)
--columns <col,col,col…>
从表中导出指定的一组列的数据
--delete-target-dir
如果指定目录存在,则先删除掉
--direct
使用直接导入模式(优化导入速度)
--direct-split-size <n>
分割输入stream的字节大小(在直接导入模式下)
--fetch-size <n>
从数据库中批量读取记录数
--inline-lob-limit <n>
设置内联的LOB对象的大小
-m,--num-mappers <n>
使用n个map任务并行导入数据
-e,--query <statement>
导入的查询语句
--split-by <column-name>
指定按照哪个列去分割数据
--table <table-name>
导入的源表表名
--target-dir <dir>
导入HDFS的目标路径
--warehouse-dir <dir>
HDFS存放表的根路径
--where <where clause>
指定导出时所使用的查询条件
-z,--compress
启用压缩
--compression-codec <c>
指定Hadoop的codec方式(默认gzip)
--null-string <null-string>
果指定列为字符串类型,使用指定字符串替换值为null的该类列的值
--null-non-string <null-string>
如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值
2.把mysql中的表复制到hdfs中
默认情况下,使用导入语句,直接导入到HDFS当前用户的目录下面,生成相应的表明,文件夹名称默认为表名。
默认(在行命令的机器上添加驱动):
sqoop import --connect jdbc:mysql://crxy172:3306/testsqoop --username 'root' --password '123456' --table info
指定到入目录:
sqoop import --connect jdbc:mysql://crxy172:3306/testsqoop --username 'root' --password '123456' --table info –target-dir info_dir
如果目录以及存在,使用--delete-target-dir:
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --delete-target-dir
指定map个数
默认启动4个进程导入(map数量),可以设置 1表示不并行
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1
同一个目录进行数据追加
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --check-column 'id' --incremental append --last-value 23
指定条件
注意两点:
第一、不能含中文;第二、"job='CTO'"
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --where "job='CTO'" (可以使用模糊批量匹配)
启用压缩
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --where "job like 'CTO'" -z (默认Gzip压缩)
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root -password 123456 --table info -m 1 --append --where "job like 'CTO'" -z --compression-codec org.apache.hadoop.io.compress.SnappyCodec (直接指定压缩编码)
导入空值处理
字符串类型:
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "--" (不可以,不能是关键字符)
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "*"
非字符串类型:
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "*" --null-non-string "="
3.把mysql中的表复制到hive中
Sql导入
sqoop import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --query "select name,job from info where $CONDITIONS" -m 1 --target-dir queryinfo --fields-terminated-by "," --split-by "id" (必须指定-m 、--fields-terminated-by 、--split-by)
追加数据
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" (如果数据表已经存在,并且字段不一样,指定分隔符时会把加到第一列中,不指定时取mysql第一列id值加到hive中)
覆盖数据
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" --hive-overwrite (只覆盖数据,不覆盖表结构)
创建hive表(自定义表名)
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" --hive-table "info_t" --hive-overwrite (如果表已经存在,不会删除,只能重新定义表名)
注意:如果导出过程失败,需要到HDFS目录当前用户目录下将临时目录删除,hdfs当前用户目录下不能存在表目录,可以另外指定--target-dir --delete-target-dir
复制mysql的表结构到Hive
sqoop create-hive-table --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-table users --fields-terminated-by " 001" --lines-terminated-by " " (不复制数据)
导出所有的表到hive
sqoop import-all-tables --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --hive-import --fields-terminated-by "u0001" --lines-terminated-by " "
4.把mysql中的表复制到HBase
选项 说明
--hbase-table 指定导入到hbase中的表
--column-family 创建列族
--hbase-row-key <id> 以id字段作为key
--hbase-create-table 创建hbase表
导入hive时,默认以主键作为key,没有主键使用--split-by ,暂时处理不了联合主键情况。
sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hbase-create-table --hbase-row-key id --hbase-table info --column-family xxx
三、sqoop工具export
选项
含义说明
--validate <class-name>
启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类
--validation-threshold <class-name>
指定验证门限所使用的类
--direct
使用直接导出模式(优化速度)
--export-dir <dir>
导出过程中HDFS源路径
--m,--num-mappers <n>
使用n个map任务并行导出
--table <table-name>
导出的目的表名称
--call <stored-proc-name>
导出数据调用的指定存储过程名
--update-key <col-name>
更新参考的列名称,多个列名使用逗号分隔
--update-mode <mode>
指定更新策略,包括:updateonly(默认)、allowinsert
--input-null-string <null-string>
使用指定字符串,替换字符串类型值为null的列
--input-null-non-string <null-string>
使用指定字符串,替换非字符串类型值为null的列
--staging-table <staging-table-name>
在数据导出到数据库之前,数据临时存放的表名称
--clear-staging-table
清除工作区中临时存放的数据
--batch
使用批量模式导出
1.把HDFS中的表数据复制到mysql中
导出到mysql(默认使用逗号作为分隔)
直接导出,导出时字段需要一一对应
sqoop export --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --export-dir export
乱码问题
sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export
指定map数
sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export -m 1
插入和更新
如果存在就更新,不存在就插入
sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export -m 1 --update-key id --update-mode allowinsert
指定分隔符(和导入区别开来)
导入导出的事务是以Mapper任务为单位。
注意:1--fields-terminated-by导入数据时(import)字段分割、行分割
2 --input-fields-terminated-by解析HDFS上面的数据到数据库时使用参数
2.从HBase到mysql
没有直接导出方案。只能使用以下步骤,先通过mapreduce写入到HDFS在通过export工具导入到mysql。
导出空值处理
--input-null-string string类型使用参数
--input-null-non-string <null-string> 非string类型使用参数
四、其他工具使用
1.
Codegen
编译jar包和record类
sqoop codegen --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info --bindir sqoopjar
直接使用已经编译好的类
sqoop import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info --class-name info --jar-file info.jar
导出过程生成的和Codegen生成代码区别:
a.导出过程生成代码纯属于副产品,无法控制,默认和表名一样
b.Codegen可以指定生成代码的参数,可以用来重新生成导入过程的源代码
主要作用:a) 可以将需要导入的数据事先序列化到HDFS中
b) 检查数据表,采用最合适的数据类型
c) 如果事先已经将数据序列化到了HDFS,可以采用该方式读取出来
2.
Eval
直接使用sql查询mysql
sqoop eval --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --query "select * from info"
插入操作:
sqoop eval --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username 'root' --password '123456' --query "insert into info values (24,'超人','飞人',1)"
3.
job生成
?创建job:--create
?删除job:--delete
?执行job:--exec
?显示job:--show
?列出job:--listsqoop job --create myjob -- import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info
sqoop job --list
sqoop job --exec myjob
五、常见问题
事务处理
由于线程的并发性,一个导入操作可能并不是原子性的。会一次statement插入100条数据,然后每100个statement提交一次,所以一次就会提交10000条数据。如果tasks失败了(由于网络问题或者其它的问题),这些tasks会尝试从它们开始导入数据的地方重新开始,会插入重复的记录。这次写数据的时候,Sqoop不提防这种潜在的问题。Sqoop提供的一个解决办法就是使用中间表,参数为:
--staging-table <staging-table-name>
--clear-staging-table
字段名称问题
sqoop 从mysql导入hive的字段名称问题
hive中有些关键字限制,因此有些字段名称在mysql中可用,但是到了hive就不行。部分不能在hive中使用的字段名称
order;sort;reduce;cast;directory
参数处理
部分字段含有特殊字符时需要添加双引号,单双引号都有时,一般采用双引号套单引号。