数据采集引擎 —— Sqoop
一、数据采集引擎
在 Hadoop 生态圈中,数据采集引擎负责直接对数据源进行数据采集,常用的有 Sqoop 和 Flume,Sqoop 应用场景主要是对 mysql、oracle 等数据库进行数据采集,而 Flume 主要用来采集日志,多用于实时计算(流式计算)。
Sqoop(发音:skup)是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql、postgresql...)间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。
Sqoop项目开始于2009年,最早是作为Hadoop的一个第三方模块存在,后来为了让使用者能够快速部署,也为了让开发人员能够更快速的迭代开发,Sqoop独立成为一个Apache项目。
Sqoop 依赖 JDBC 来操作数据库,常用于离线计算,执行时本质是 MapReduce 任务。
二、环境搭建
1、Oracle 数据库
这里使用 Oracle 数据库作为 sqoop 数据采集的数据源,为了简化安装,在 windows xp 的虚拟机上运行,将安装介质拷贝到虚拟机中,解压。
双击 setup.exe 执行,出现安装向导窗口,创建一个 orcl 的数据库,为系统管理员(system)创建口令 password,点击下一步
安装向导检查操作系统是否满足安装条件
勾选网络配置
一共将安装 114 个组件
正式安装
创建数据库
安装完成
解锁用户(设置 scott/tiger、sh/sh)
创建 emp 数据库并导入数据,表结构如下
数据如下
2、Sqoop 安装配置
解压
tar -zxvf sqoop-1.4.5.bin__hadoop-0.23.tar.gz -C ~/training/
配置环境变量(~/.bash_profile)
SQOOP_HOME=/root/training/sqoop-1.4.5.bin__hadoop-0.23
export SQOOP_HOME
PATH=$SQOOP_HOME/bin:$PATH
export PATH
将 oracle 安装目录 C:\oracle\product\10.2.0\db_1\jdbc\lib 下的 ojdbc14.jar 拷贝到 $SQOOP_HOME/lib 中,这样 sqoop 通过 jdbc 操作 oracle 时才不会缺乏依赖。
三、数据采集
1、sqoop 命令
使用 sqoop help 可以查到所有可用的命令:
22/03/28 15:09:39 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5
usage: sqoop COMMAND [ARGS]
Available commands:
codegen Generate code to interact with database records
create-hive-table Import a table definition into Hive
eval Evaluate a SQL statement and display the results
export Export an HDFS directory to a database table
help List available commands
import Import a table from a database to HDFS
import-all-tables Import tables from a database to HDFS
job Work with saved jobs
list-databases List available databases on a server
list-tables List available tables in a database
merge Merge results of incremental imports
metastore Run a standalone Sqoop metastore
version Display version information
See 'sqoop help COMMAND' for information on a specific command.
通过 sqoop help COMMAND 可以查看某个命令的使用方法和参数。
2、实战
① codegen
根据表结构生成对应的 Java 类
# 使用jdbc连接192.168.190.133上安装的orcl数据库,用户名为scott,密码为tiger,操作的表为tiger,生成的java类输出到本地文件系统的/root/temp目录下
sqoop codegen --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --table EMP --outdir /root/temp
# 操作oracle数据库时,用户名、表名、列名要使用大写
生成的 java 类实现了 Writable 接口,可用于在 MapReduce 中使用。
② create-hive-table
根据关系型数据库的表结构去创建 Hive 的表结构。
# 根据oracle中的EMP表创建hive的emps表
sqoop create-hive-table --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --table EMP --hive-table emps;
执行完后,可以看到保存 hive 表的 HDFS 目录下多出了一个 emps 的目录,可以通过 Hive Shell 查看表结构
③ eval
通过 sqoop 执行 SQL
# 查询数据库中emp表的数据
sqoop eval --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --query 'select * from emp'
执行结果如下
④ export
把HDFS中的数据导入到数据库中
⑤ import
将数据库中的输入导入到HDFS中
# 将EMP表的数据导入到HDFS的/sqoop/import/emp1目录下
sqoop import --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --table EMP --target-dir /sqoop/import/emp1
会触发一个 MapReduce 作业的执行
查看 HDFS 可以看到生成了四个分区数据文件
PS.这是因为Sqoop默认情况下执行 MapReduce 作业时,map 作业的个数是4个
某些时候可能只想采集某些列,sqoop 支持指定只采集部分列
# 采集EMP表的ENAME,SAL列到HDFS中
sqoop import --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --table EMP --columns ENAME,SAL --target-dir /sqoop/import/emp2
查看生成的目录文件,只有两个列
如果采集的数据表中不含主键
# 导入订单表,该表不含主键
sqoop import --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SH --password sh --table SALES --target-dir /sqoop/import/sales
这种情况有两种解决方法:
- 1)将 map 的个数设为1,在命令末尾加上 '-m 1',但是会降低采集效率;
- 2)使用 --split-by,后面跟上表的最后一列名字。从而能够对数据进行分行
sqoop import --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SH --password sh --table SALES --target-dir /sqoop/import/sales --columns "PROD_ID,CUST_ID,TIME_ID,CHANNEL_ID,PROMO_ID,QUANTITY_SOLD,AMOUNT_SOLD" --split-by AMOUNT_SOLD
⑥ import-all-tables
将某个用户下的所有表导入到 HDFS 中。
# 将scott用户下的所有表导入到HDFS中
sqoop import-all-tables --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger
不指定HDFS目录时,默认采集到 /user/root 目录下。
⑦ job
执行 sqoop 命令需要对 HDFS 操作时,会生成一个 MapReduce 作业,我们可能想先创建好一个作业,再延期触发执行,可以使用 job 命令实现。
# 创建一个作业名为import-emp-job的作业,注意import之前是空格,然后才是--
sqoop job --create import-emp-job -- import --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SCOTT --password tiger --table EMP --target-dir /sqoop/import/emp-job
查看当前存在的所有job
sqoop job --list
查看作业的配置
sqoop job --show import-emp-job
执行作业
sqoop job --exec import-emp-job
⑧ list-databases
列出所有可用数据库。MySQL 列出的就是数据库的名称,Oracle 列出的是数据库中所有的用户名。
sqoop list-databases --connect jdbc:oracle:thin:@192.168.190.133:1521/orcl --username SYSTEM --password password
这里连接数据库需要使用管理员用户,否则权限不足
⑨ merge
合并多次采集的数据(相同的表)
# --new-data:新的数据集
# --onto:旧的数据集
# --target-dir:合并后的输出目录
# --jar-file & --class-name:合并时必须使用 codegen 命令生成的类,将这些类打成jar包,这两个参数就用来指定jar包和序列化类
# --merge-key:表的主键
sqoop merge --new-data newer --onto older --target-dir merged \
--jar-file datatypes.jar --class-name Foo --merge-key id