致敬 Apache Sqoop

2021-07-09 10:11:10 浏览数 (1)

大家好,我是一哥,昨天看到了过往记忆大佬发了一篇文章,才发现Sqoop这个项目最近不咋好,心里很不是滋味,这个帮助过很多开发者的项目,竟然从Apache顶级项目中“下架”了,今天还是想给大家分享介绍一些这个很棒的项目,致敬!

01

Sqoop介绍

Sqoop is a tool designed to transfer data between Hadoop and relational databases or mainframes. You can use Sqoop to import data from a relational database management system (RDBMS) such as MySQL or Oracle or a mainframe into the Hadoop Distributed File System (HDFS), transform the data in Hadoop MapReduce, and then export the data back into an RDBMS.

Sqoop是一种用于在Hadoop和关系数据库或大型机之间传输数据的工具。你可以使用Sqoop从一个关系数据库管理系统(RDBMS)中导入数据,比如MySQL或Oracle,或者一个大型机到Hadoop分布式文件系统(HDFS),在Hadoop MapReduce中转换数据,然后将数据导出到RDBMS中。

其实我们不使用Sqoop也可以完成MySQL和HDFS的数据传递,采用Flume监控MySQL,能读到数据,那么也就能把数据写到HDFS上。

02

Sqoop原理

其实Sqoop做的就是把导入导出命令翻译成MapReduce程序来实现,该MapReduce程序主要是对InputFormat和OutputFormat进行定制。和Flume一样,没有什么bin/start.sh,不用启动任何进程,一个任务就对应一个MapReduce。

03Sqoop的安装和配置

目前Sqoop有两个版本,Sqoop1(1.4.x)和Sqoop2(1.99.x),Sqoop1最新版本是1.4.7,Sqoop2最新版本是1.99.7(注意:1.99.7和1.4.7不兼容,且功能不完整),另外Sqoop1.4.7和CentOS6.8配合有问题,要改很多地方,所以使用1.4.6。

1、去官网(http://archive.apache.org/dist/sqoop/)下载压缩包:

2、解压、重命名

代码语言:javascript复制
tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/
cd /opt/module/
cp -r sqoop-1.4.6.bin__hadoop-2.0.4-alpha/ sqoop-1.4.6

注意:Sqoop只是一个工具,所以不需要分发到其他设备上

3、配置

代码语言:javascript复制
cp conf/sqoop-env-template.sh conf/sqoop-env.sh
vim conf/sqoop-env.sh

#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/opt/module/hadoop-2.7.2

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/opt/module/hadoop-2.7.2

#set the path to where bin/hbase is available
export HBASE_HOME=/opt/module/hbase-1.3.2.1

#Set the path to where bin/hive is available
export HIVE_HOME=/opt/module/hive-1.2.2

#Set the path for where zookeper config dir is
export ZOOCFGDIR=/opt/module/zookeeper-3.4.10

因为Sqoop要从Mysql导入数据,又会把数据导出到Mysql,都需要Mysql Java驱动jar,所以需要把MySQL的驱动jar包copy到Sqoop的./lib目录下。

代码语言:javascript复制
cp /opt/soft/mysql-libs/mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar ./lib/

验证Sqoop是否配置正确:

代码语言:javascript复制
bin/sqoop help

我们之前并没有在sqoop.env.sh中配置MySQL的相关内容,是因为我们在执行命令的时候,要主动地在命令当中去连接我们的MySQL。

测试Sqoop能否成功连接数据库:

代码语言:javascript复制
bin/sqoop list-databases --connect jdbc:mysql://hadoop102:3306/ --username root --password 123456

04

Sqoop简单使用案例

MySQL --> HDFS

全表导入:

代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456 
# 要导入的表名是staff,表示staff表全表导入!
--table staff 
# ====== HDFS的配置 ======
# 要导入到HDFS的哪个目录
--target-dir /user/company 
# 因为Sqoop原理就是跑MR,MR不允许输出目录存在,这个参数的意思就是target-dir目录存在则删除
# 但是现在仅是为了学习使用这个参数,实际到公司中慎用,避免删除数据!
--delete-target-dir 
# maptask并不像以前MR读文件会切片,得根据实际表的数据量大小自己估计下maptask
--num-mappers 1 
# 字段分割符是t
--fields-terminated-by "t"

查询导入:

代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456 
# 必须在where字句中加上$CONDITIONS保证导入的数据顺序
--query 'select name,sex from staff where id <=2 and $CONDITIONS'
# ====== HDFS的配置 ======
--target-dir /user/company 
--delete-target-dir 
--num-mappers 1 
--fields-terminated-by "t" 

Sqoop把数据库的数据导入到HDFS上,应该保证数据的顺序和查询的结果集一致才行!但是实际开发中,数据量很大,我们不可能只分配一个mapper工作,所以我们得加上$CONDITIONS保证多个maptask写入到HDFS上的文件数据的顺序和原表查询的结果一致!

If you want to import the results of a query in parallel, then each map task will need to execute a copy of the query, with results partitioned by bounding conditions inferred by Sqoop. Your query must include the token $CONDITIONS which each Sqoop process will replace with a unique condition expression. You must also select a splitting column with --split-by.

导入指定列:

代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456
--table staff 
# 指定列,如果是多个列用,分隔,分隔时不要加空格,否则会抛异常
--columns id,sex 
# ====== HDFS的配置 ======
--target-dir /user/company 
--delete-target-dir 
--num-mappers 1 
--fields-terminated-by "t"

查询条件导入:

代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password aaa 
--table staff
# 指定查询条件
--where 'id=1' 
# ====== HDFS的配置 ======
--target-dir /user/company 
--delete-target-dir 
--num-mappers 1 
--fields-terminated-by "t" 

MySQL --> Hive

Sqoop从MySQL导入到Hive中,分为两步:

  • 创建一个临时目录存放从MySQL上导入的数据,默认目录为:/user/{mysqlTableName}/
  • 将临时目录的数据迁移到Hive表目录中,迁移完毕删除临时目录
代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456 
--table staff 
# ====== HDFS的配置 ======
--delete-target-dir 
--num-mappers 1 
--fields-terminated-by "t" 
# ====== Hive的配置 ======
# --hive-import:把从MySQL导入到临时目录的数据迁移到Hive表目录
--hive-import 
--hive-overwrite 
--hive-table staff_hive

注意:如果抛出异常:Could not load org.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly,则需要$HIVE_HOME/lib/*加入到环境变量HADOOP_CLASSPATH中。在sqopp-env.sh下添加如下代码:

代码语言:javascript复制
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*

问题:Sqoop1.4.6会自动创建Hive表,Sqoop1.4.7可能与Hive1.2.2版本不兼容,不会自动创建Hive表,虽然已经把数据导入到指定创建的Hive表目录下,但是没有添加元数据,在Hive中查询不到该表。

解决方法:把Hive的hive-site.xml拷贝到Sqoop的conf目录。

MySQL --> HBase

Sqoop可以直接从MySQL把数据导入到HBase中,不像Hive有个--hive-import需要分为两步执行。像Sqoop、Oozie要和很多框架进行交互,所以它们和其他框架的版本兼容性就非常重要,所以公司中一般使用cdh版本,cdh版本把版本兼容性全部搞定,不需要我们再操心这些事情!

代码语言:javascript复制
bin/sqoop import 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456 
--table staff 
--columns id,name,sex 
# ====== HBase的配置 ======
--hbase-table hbase_company 
--hbase-row-key id 
--column-family info 
# Column of the table userd to split work units 测试后发现不加也不影响导入
--split-by id 
--hbase-create-table 
--num-mappers 1 

HDFS-->MySQL

代码语言:javascript复制
bin/sqoop export 
# ====== MySQL的配置 ======
--connect jdbc:mysql://hadoop102:3306/company 
--username root 
--password 123456 
--table staff 
# ====== HDFS的配置 ======
--num-mappers 1 
# 导出目录,这样看是不是HDFS和Hive没区别?
--export-dir /user/hive/warehouse/staff_hive 
# --update-key:表示所有操作变成update ... 操作
# 但是,如果原来表中不存在的id则不会插入进去,只会更新
--update-key id 
# --update-mode allowinsert:表示存在的就更新,不存在的就插入
--update-mode allowinsert 
# 必须指定分隔符、否则默认不分隔,导出到MySQL会解析错误(可能把一整行字符串当做主键插入)
--input-fields-terminated-by "t"

注意:MySQL中的staff表必须提前存在,否则会抛出异常。由于MySQL的数据类型很多,导出的时候Sqoop不知道该怎么给MySQL的列定义类型,必须我们自己提前创建表,指定MySQL列的类型,所以导出之前MySQL的表必须存在。

Hive数据本来就在HDFS上,所以Hive导出到MySQL和上述方法一样。

05

Sqoop的遗憾

Apache Sqoop moved into the Attic in 2021-06. Apache Sqoop mission was the creation and maintenance of software related to Bulk Data Transfer for Apache Hadoop and Structured Datastores.

这款很多人都用过的工具,从Apache顶级项目列表中“下架”了,相信现在还有很多公司在使用的。其实很多开源项目并不是因为它不够优秀,有时候可能是没有商业公司运营推广,像Spark,Flink,包括国人的顶级项目Kylin,背后都有商业公司在运营推广。

资本的力量很强大!

希望大家能够在用到好的开源项目的时候能够给予一定的贡献,哪怕是贡献一个想法,修改一处文档也可以。这里有之前写的一份如何参与Apache项目的指南《如何参与一个Apache开源项目》,一起加入开源!

开源,让技术更美好!

0 人点赞