Sqoop是一个用来将Hive和Mysql中的数据相互转移的工具,也可以将Hdfs的数据导入到Mysql中。
官方地址:http://sqoop.apache.org/
安装包下载地址,
https://mirrors.cnnic.cn/apache/sqoop/1.4.7/sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz
解压到当前目录
tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
然后可以用mv命令移动重命名解压后的目录到指定目录
mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha sqoop-1.4.6.bin
vi ~/.bash_profile
添加如下内容进去
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/Users/liuxunming/MyConfigure/apache-hive-1.2.2-bin/lib/*
export SQOOP_HOME=/Users/liuxunming/MyConfigure/sqoop-1.4.6.bin__hadoop-2.0.4-alpha
export PATH=$SQOOP_HOME/bin:$PATH
使其生效
source .bash_profile
配置sqoop-env.sh,默认解压后的sqoop安装目录的conf下没有这个文件,复制conf/sqoop-env-template.sh改名为sqoop-env.sh,并修改其中内容如下:
# Hadoop
export HADOOP_PREFIX=/Users/liuxunming/MyConfigure/hadoop-2.7.4
export HADOOP_HOME=${HADOOP_PREFIX}
export PATH=$PATH:$HADOOP_PREFIX/bin:$HADOOP_PREFIX/sbin
export HADOOP_COMMON_HOME=${HADOOP_PREFIX}
export HADOOP_HDFS_HOME=${HADOOP_PREFIX}
export HADOOP_MAPRED_HOME=${HADOOP_PREFIX}
export HADOOP_YARN_HOME=${HADOOP_PREFIX}
# Native Path
export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_PREFIX}/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib/native"
# Hadoop end
#Hive
export HIVE_HOME=/Users/liuxunming/MyConfigure/apache-hive-1.2.2-bin
export PATH=$HIVE_HOME/bin:$PATH
导入几个jar包到lib目录下
hive-hcatalog-core-2.3.1.jar
mysql-connector-java-5.1.34.jar
至此,配置基本完成。
导出hive表到mysql,首先得有一个hive表,当然这里我们已经配置好了hive环境
create table cup (id string,dname string) row format delimited fields terminated by '|';
注意这个分隔符命令要有
源数据样式为,存在于hdfs上,这就是hadoop的mapreduce的执行结果文件
13501590629|55D7203CF53C8BDD709A52009EFB4106
15305100178|425D5120A23B40A4C28559D61478E1E2
18305111883|84CCFFDBB47C2F529AD0BCB8ADE9D185
13345189666|39A0B547B1C80C09D0A0739F106023FB
导入hdfs文件到hive表命令
load data inpath '/data/result/part-r-00000' into table cup;
执行以上命令后,是直接把原数据导走,就是原数据已经不再存在原来的位置。
sqoop export --connect jdbc:mysql://127.0.0.1:3306/cc --username root --password 123456 --table ff --columns id,name,sex,date --export-dir /user/hive/warehouse/cup4 --input-fields-terminated-by '|'
有几个注意点:
1、127.0.0.1这是ip地址,3306是端口号,cc是数据库名,不能使用localhost代替,否则会报Access denied for user ‘root’
2、–password这里可以使用-P,就不会出现密码的明文在命令行里
3、–table 代表的是本地mysql中建立的表名
4、–export-dir 后面的参数值是hdfs上的hive数据表对应的文件位置,道理上讲,创建一个数据表的话,在/user/hive/warehouse下就会有对应的目录生成
5、–input-fields-terminated-by 这是一个很重要的字段,分隔符,根据数据格式填入相应分隔符,不然无法正确导入,或者导入进去的会是NULL
6、–columns 这代表可以指定导入某些列,应用场景是hive中的结构与mysql的表结构不一致的情况,如果顺序不一致的话,只能去调整hdfs文件的输出顺序,也没有办法跨列导出,这也是一个不足之处
7、导出过程中sqoop会根据目标表(数据库)的结构会生成一个Java类,该类的作用为序列化和反序列化。
批量导入到奥义就是在上一步到基础上把–export-dir到输入路径改为一个目录,类似这样
/xm/output/*/result/
意思就是说/xm/output目录下有多个以日期命名的结果集,hadoop跑出的最终结果放在了result目录下,即result/part-r-00000
添加两个属性,数据存在则更新,不存在则插入
update-key "id,url_id" update-mode allowinsert #指定联合主键的值
或者多个主键
update-key id update-mode allowinsert #指定更新的模式为可插入,默认为 updateonly
要注意的是 表中主键要是id,且有唯一约束
在sqoop的export命令中,需要连接数据库,这里不能使用明文,太不安全了,所以hadoop提供了一种最优方式–别名,当然还有一种较安全的方式是文件密码,但是存在文件里的密码还是明文,然而这种别名密码所对应的文件就是一堆乱码了,无法解析,足够安全。
hadoop credential create mysql.test.pwd.alias -provider jceks://hdfs/user/password/mysql.test.pwd.jceks
按下回车后,需要输入两次密码才算成功创建别名文件。其中mysql.test.pwd.alias这个是我们要使用的别名,mysql.test.pwd.jceks这个是生成的别名文件名,前面的hdfs代表这个文件存放在hdfs上,/user/password/目录下;当然我们也可以把别名文件放在本地,形如这样:
localjceks://file/tmp/mysql.test.pwd.jceks
两者各有利弊吧,建议还是使用hdfs方式
sqoop export -Dhadoop.security.credential.provider.path=jceks://hdfs/user/password/mysql.test.pwd.jceks --connect jdbc:mysql://192.168.10.1:3306/test --username test --password-alias mysql.test.pwd.alias
这里有注意的是-Dhadoop…要放在export命令的后面,不然会报错,当然正常人应该不会犯这种低级错误
No such sqoop tool: -Dhadoop.security.credential.provider.path=jceks://hdfs/user/password/mysql.test.pwd.jceks. See 'sqoop help'.
Sqoop导出hdfs到mysql失败:卡住map阶段100%,超时四五次后自动停止失败
查看错误日志(查看方法就是根据applicationid去hadoop的logs目录下的userlogs目录下查找对应目录)
org.apache.sqoop.mapreduce.AsyncSqlOutputFormat: Got exception in update thread: java.sql.SQLException: Incorrect string value: '\xEF\xBB\xBFcre...' for column 'url' at row 28
解决办法:明显是url这个字段的字符集有问题,于是修改这张表的url字段,设置它的字符集为utf8mb64,原理是mysql中规定utf8字符的最大字节数是3,但是某些unicode字符转成utf8编码之后有4个字节,所以需要换成utf8mb64
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
报上面的错误的话,就把HADOOP_CLASSPATH增加到环境变量中即可,见参考博文4
有一个貌似是直接导出hive表名到mysql的命令
sqoop export --connect jdbc:mysql://127.0.0.1:3306/cc --username root --password 123456 --table dd --hcatalog-database mydatabase --hcatalog-table cup
不过执行后却抛出了以下错误异常,基本没搜到类似错误,暂时无解,留个坑在这里,望路过的各位大神不吝赐教
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hive.common.util.ShutdownHookManager.addShutdownHook(Ljava/lang/Runnable;)V
这里有一篇文章介绍了具体的参数,但是呢,没有例子说明
sqoop mysql数据导入Hive中
这里还有一片文章介绍hcatalog的,不顾是导入oracle的
从hive导入到oracle(Hcatalog)