Hadoop生态圈之Sqoop

  • 1、sqoop是什么
  • 2、安装配置
    • 2.1 安装sqoop
    • 2.2 配置环境变量
  • 3、数据表导出
    • 3.1 创建hive表
    • 3.2 导入数据到hive表
    • 3.3 导出到mysql
    • 3.4 批量导入到mysql
    • 3.5 数据覆盖更新
  • 4、Password配置别名
    • 4.1 生成别名
    • 4.2 使用别名
  • 5、参考博文
  • 6、问题 — 字符编码
  • 7、问题 — hive到mysql

1、sqoop是什么

Sqoop是一个用来将Hive和Mysql中的数据相互转移的工具,也可以将Hdfs的数据导入到Mysql中。

官方地址:http://sqoop.apache.org/

2、安装配置

2.1 安装sqoop

安装包下载地址,

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

2.2 配置环境变量

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

至此,配置基本完成。

3、数据表导出

导出hive表到mysql,首先得有一个hive表,当然这里我们已经配置好了hive环境

3.1 创建hive表

create table cup (id string,dname string) row format delimited fields terminated by '|';

注意这个分隔符命令要有

3.2 导入数据到hive表

源数据样式为,存在于hdfs上,这就是hadoop的mapreduce的执行结果文件

13501590629|55D7203CF53C8BDD709A52009EFB4106
15305100178|425D5120A23B40A4C28559D61478E1E2
18305111883|84CCFFDBB47C2F529AD0BCB8ADE9D185
13345189666|39A0B547B1C80C09D0A0739F106023FB

导入hdfs文件到hive表命令

load data inpath '/data/result/part-r-00000' into table cup;

执行以上命令后,是直接把原数据导走,就是原数据已经不再存在原来的位置。

3.3 导出到mysql

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类,该类的作用为序列化和反序列化。

3.4 批量导入到mysql

批量导入到奥义就是在上一步到基础上把–export-dir到输入路径改为一个目录,类似这样

/xm/output/*/result/

意思就是说/xm/output目录下有多个以日期命名的结果集,hadoop跑出的最终结果放在了result目录下,即result/part-r-00000

3.5 数据覆盖更新

添加两个属性,数据存在则更新,不存在则插入

update-key "id,url_id" update-mode allowinsert #指定联合主键的值

或者多个主键

update-key id update-mode allowinsert #指定更新的模式为可插入,默认为 updateonly

要注意的是 表中主键要是id,且有唯一约束

4、Password配置别名

在sqoop的export命令中,需要连接数据库,这里不能使用明文,太不安全了,所以hadoop提供了一种最优方式–别名,当然还有一种较安全的方式是文件密码,但是存在文件里的密码还是明文,然而这种别名密码所对应的文件就是一堆乱码了,无法解析,足够安全。

4.1 生成别名

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方式

4.2 使用别名

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'.

5、参考博文

  1. Sqoop安装配置及Hive导入
  2. Sqoop-1.4.4工具import和export使用详解
  3. 将Hive统计分析结果导入到MySQL数据库表中(一)——Sqoop导入方式
  4. Hive启动报错解决方法
  5. Sqoop导出hive数据到mysql
  6. [总结型] sqoop导入到HDFS怎么都是java文件总结
  7. Hadoop数据传输工具sqoop(四)Java远程调用Sqoop进行数据传输

6、问题 — 字符编码

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

7、问题 — hive到mysql

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)

你可能感兴趣的:(Big,Data,Hadoop学习笔记)