黑洞

这里藏着一些独特的想法

0%

Sqoop使用说明

概述

Sqoop是Apache旗下一款ETL工具,用于Hadoop和RDBMS之间传送数据。

工作原理:将命令转换为MapReduce程序实现。

导入数据:MySQL、Oracle导入数据到Hadoop的HDFS、HIVE、HBASE等数据存储系统。

导出数据:从Hadoop的HDFS、HIVE中导出数据到关系数据库MySQL等。

抽取方式

通过Sqoop将RDMBS中的数据导入到Hive有两种方式。一种是原生Sqoop API,另一种是HCatalog API,两种方式略有不同。

区别

数据格式支持

Sqoop方式支持的数据格式较少,HCatalog支持的数据格式多,包括RCFile、ORCFile、CSV、JSON和SequenceFile等格式。

数据覆盖

Sqoop方式允许数据覆盖,HCatalog不允许数据覆盖,每次都只是追加。

字段名

Sqoop方式比较随意,不要求源表和目标表字段相同(字段名称和个数都可以不相同),它抽取的方式是将字段按顺序插入,比如目标表有3个字段,源表有一个字段,它会将数据插入到Hive表的第一个字段,其余字段为NULL。但是HCatalog不同,源表和目标表字段名需要相同,字段个数可以不相等,如果字段名不同,抽取数据的时候会报NullPointerException错误。HCatalog抽取数据时,会将字段对应到相同字段名的字段上,哪怕字段个数不相等。

总结

不论是从格式兼容性还是数据的完整性、安全性考虑,都建议使用HCatalog方式抽取,并且字段不管是顺序还是名字都保持一致。

基操命令

Sqoop1以Client客户端的形式存在和运行。没有任务时是没有进程存在的。
Sqoop2则是B/S的架构,始终有Server进程运行着。
官方文档:https://sqoop.apache.org/

以下是Sqoop1的一些使用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 查看版本
sqoop-version

# 查看帮助文档
sqoop help

# 查看所有数据库
sqoop list-databases \
--connect jdbc:mysql://192.168.52.150:3306 \
--username root \
--password 123456

# 查看数据库下的所有表
sqoop list-tables \
--connect jdbc:mysql://192.168.52.150:3306/tmall \
--username root \
--password 123456

# 全量导入至HDFS
sqoop import \
--connect jdbc:mysql://192.168.52.150:3306/test \
--username root \
--password 123456 \
--table emp

不指定其他参数的情况下,每条数据(记录)会运行一个mapTask, 数据的默认分隔符号为逗号。

如果是root(Linux用户)运行了Sqoop,则数据在HDFS中的存放路径为/user/root/

常用参数

参数 说明 用法
--connect 连接数据库 --connect jdbc:mysql://192.168.52.150:3306/test
--username 数据库用户 --username root
--password 用户的密码 --password 123456
--table 源表名(RDBMS) --table emp
--m map任务数(数量不为1时必须指定划分字段) --m 2
--split-by 根据字段划分 --split-by id
--target-dir 目标路径 --target-dir '/sqoop_works/t_emp'
--delete-target-dir 如果目标路径存在则删除 --delete-target-dir
--fields-terminated-by 指定字段分隔符(导入时) --fields-terminated-by '\001'
--input-fields-terminated-by 指定字段分隔符(导出时) --input-fields-terminated-by '\001'
--hcatalog-database 指定Hive数据库 --hcatalog-database testdb
--hcatalog-table 指定Hive表 --hcatalog-table t_emp
--where 条件过滤 --where 'id>=100'
--query --e SQL查询(使用时必须指定目标路径和划分字段) 单引号 --query 'select id, name, age from t_emp where age > 30 and $CONDITIONS'
双引号 --query "select id, name, age from t_emp where age > 30 and \$CONDITIONS"
--null-string 导入时处理string类型的NULL值 --null-string '\N'
--null-non-string 导入时处理非string类型的NULL值 --null-non-string '\N'
--create-hcatalog-table 自动创建Hive表(一般不用,手动建表更灵活) --create-hcatalog-table

解决中文乱码

--connect参数后加上?useUnicode=true&characterEncoding=utf-8

栗子

需求:从户籍维度分析每个地方学生的男女比例。

导入

  1. 参考源表建立Hive中的表,同时指定文件格式、分隔符、压缩方式。

  2. MySQL中的university数据库下有一张名为stu的学生表。导入所有2022届的学生信息至Hive中的edu_ods数据库,分隔符为\001,存放路径为/edu/stu_ods

无需在sqoop设置分隔符、压缩方式以及文件格式。因为手动建表时已经设置了。

1
2
3
4
5
6
7
8
9
10
11
12
sqoop import \
--connect jdbc:mysql://192.168.52.150:3306/university \
--username root \
--password 123 \
--table stu \
--hcatalog-database edu_ods \
--hcatalog-table stu_ods \
--query 'select * from stu where enroll_year = 2022 and $CONDITIONS' \
--delete-target-dir \
--target-dir '/edu/stu_ods' \
--split-by sid \
--m 1

导出

  1. 参考结果表建立MySQL中的表。
  2. 将分析结果导出至MySQL中的BI数据库。
1
2
3
4
5
6
7
8
sqoop export \
--connect jdbc:mysql://192.168.52.150:3306/bi?useUnicode=true&characterEncoding=utf-8 \
--username root \
--password 123 \
--table stu_household_gender_ratio \
--hcatalog-database edu_da \
--hcatalog-table stu_household_gender_ratio_da \
--m 1
如果觉得文章写得不错或对您有帮助,请我喝杯柠檬茶吧!