基于Sqoop 的高校数据中心数据自动传输方案研究
作者: 曹素丽 杨延广 张磊
摘要:随着大数据技术在高校的快速应用,如何高效地在关系型数据库与Hadoop之间进行数据传输成了必须解决的问题。文章针对这一需求,设计了一种基于Sqoop的数据自动传输方案。方案首先分析了Sqoop的基本原理和安装方法,之后结合高校教务系统,阐述了利用Sqoop实现数据导入、导出和增量同步的具体方法,并给出了完整的命令和Shell脚本程序。实际应用表明,该方案能够有效地实现数据自动传输,提升了数据处理效率。
关键词:数据传输;Sqoop;Hadoop;关系数据库;数据中心;大数据;高校
中图分类号:TP311.13 文献标识码:A
文章编号:1009-3044(2025)02-0060-04 开放科学(资源服务) 标识码(OSID) :
0 引言
随着高校信息化建设的不断推进,各个业务系统产生了海量数据。为了更好地挖掘和利用这些数据,高校纷纷构建数据中心,将分散在各个业务系统的数据集中存储和处理,以支持数据分析、决策支持等应用。然而,传统的关系型数据库难以满足海量数据的存储和处理需求,因此需要将数据迁移到分布式计算平台Hadoop中进行处理。处理后的结果数据还需要回传到关系数据库中,以便于进行数据可视化等后续处理。Sqoop就是一种能够高效实现Hadoop与关系型数据库之间数据传输的开源工具[1]。
1 Sqoop 简介
Sqoop是Hadoop生态圈中一个数据迁移组件,可实现数据的双向传输。将数据从关系数据库传输到Hadoop 集群(HDFS、Hive 或HBase) 称为Sqoop 导入;反之,数据从Hadoop 集群传输到关系数据库称为Sqoop 导出。Sqoop 存在两个系列版本Sqoop1 和Sqoop2,相较于Sqoop2,Sqoop1架构更为简单,部署和使用更加方便,因此本项目选择Sqoop1作为数据传输工具。
Sqoop通过将数据传输任务转换为MapReduce作业来实现数据的导入和导出。如图1所示,Sqoop的工作流程如下[2]。
1) 接收命令:Sqoop接收用户输入的导入或导出命令。
2) 获取元数据生成记录容器类:Sqoop连接到关系型数据库,获取要传输的表的元数据信息,包括Schema、表名、字段名、字段类型等,根据元数据生成一个记录容器类。
3) 启动MapReduce作业:Sqoop根据传输要求,自动生成一个只有Map任务的MapReduce作业,然后启动作业开始数据传输,容器类向Map提供数据保存及转换功能。
4) 数据传输:Sqoop可使用多个Map任务并行传输。在导入过程中,数据是从数据库传输到HDFS;在导出过程中,数据是从HDFS传输到数据库。
2 Sqoop 环境部署
在使用Sqoop之前,首先需要搭建其运行环境。假定Sqoop的安装包及数据库所需的JDBC连接包均已完成下载,下面是在Hadoop 2.x集群的数据节点上部署Sqoop(本例版本为1.4.7.bin__hadoop-2.6.0) 环境的具体步骤。
2.1 释放Sqoop 软件包
将/soft 目录下的Sqoop 安装包释放到/apps 目录下:
tar -xzvf /soft/sqoop-1.4.7. bin__hadoop-2.6.0. tar.gz -C /apps
将释放后的目录重命名,便于后续引用:
mv /apps/sqoop-1.4.7.bin__hadoop-2.6.0 /apps/sqoop
2.2 修改环境变量
修改用户配置文件,如.bashrc,在文件末尾添加如下两行文本:
export SQOOP_HOME=/apps/sqoop
export PATH=$SQOOP_HOME/bin:$PATH
使配置立即生效:
source ~/.bashrc
2.3 拷贝MySQL 的JDBC 包
将MySQL 的JDBC 连接包拷贝到Sqoop 的lib 目录下:
cp/soft/mysql-connector-java-5.1.42-bin. jar /apps/sqoop/lib
如果是Oracle或其他数据库,则需要拷贝它们所对应的JDBC连接包。
2.4 配置Sqoop
在$SQOOP_HOME/conf/sqoop-env.sh文件末行添加如下内容,作用是告诉Sqoop关于Hadoop、HBase、Hive等软件的相关路径:
export HADOOP_COMMON_HOME=/apps/hadoop
export HADOOP_MAPRED_HOME=/apps/hadoop
export HBASE_HOME=/apps/hbase
export HIVE_HOME=/apps/hive
#export ZOOCFGDIR=/apps/zookeeper
之后,通常使用命令sqoop version 和sqoop listdatabases进行安装结果的验证,如果正常执行则表示成功安装[3]。
3 Sqoop 导入导出命令及参数
导入命令格式:
sqoop import --参数1 值1 --参数2 值2 …… -- 参数n 值n
导出命令格式:
sqoop export --参数1 值1 --参数2 值2 …… -- 参数n 值n
命令可选参数很多,除了三个基本的数据库连接参数——connect <jdbc-uri>、username <username>和password <password>以外,其他常用参数如表1所示。
对HBase分布式数据库的导入Sqoop也是提供支持的,HBase 相关的参数有column-family <列族>、hbase-row-key <行键>、hbase-table <Hbase 表>等[4],限于篇幅,本文将不再做HBase的相关介绍。
4 导入导出具体实现
4.1 数据导入
实际系统中会涉及多种业务系统数据源的导入,下面选择几种典型场景进行分析。
1) 将MySQL表导入HDFS中
$sqoop import \
--connect jdbc:mysql://dbsvr1:3306/jwdb?charac⁃terEnconding=UTF-8 \
--username root --password root \
--table student -m 3 \
--target-dir /jwxtdir/students \
--fields-terminated-by ','
命令及参数说明:
此命令实现将MySQL表导入HDFS的功能;
MySQL的主机为dbsvr1,端口是标准3306时可以不写,数据源是jwdb数据库,由于数据含有中文字符,需要使用选项“characterEnconding=UTF-8”;
数据库用户名是root,密码root;
数据源是数据表student;
启用3个map任务并行导入;
导入目标位置是HDFS 的/jwxtdir/students 目录,需注意/jwxtdir/students路径的最后一级目录students,导入时会自动创建,导入前不能存在;
文件内部用逗号分隔各数据项。
2) 将MySQL表导入Hive表中
$sqoop import \
--connect jdbc: mysql://dbsvr1/jwdb? characterEn⁃conding=UTF-8 \
--username root --password root \
--table student -m 3 \
--hive-import --hive-table studhive \
--fields-terminated-by ',' \
--hive-overwrite \
--delete-target-dir
命令及参数说明:
此命令实现将MySQL数据库表向Hive表的数据导入功能[5];
启用3个map并行任务;
目标表studhive 是Hive 中提前创建好的,且与student表结构一致的Hive表,未指定Hive数据库默认使用default数据库;
覆盖Hive表中已经存在的数据;
如果存在目标目录则先删除。
向Hive导入过程中可能会出现一些报错或异常,常见原因有缺少jar包、数据库不存在、版本不兼容等,需要根据提示信息做相应处理。
3) 增量导入
增量导入就是仅导入数据源中有变化的数据。通过记录前次导入的状态,Sqoop可以检测出哪些数据是新增或更新的,增量导入模式避免了重复导入全部数据,提高了传输效率。
Sqoop提供了两种增量导入模式:一是append模式,适用于源表中存在自增主键且主键值是递增的情形;二是lastmodified模式,适用于源表包含有时间戳列的情形。增量导入命令中,通过check-column 和last-value 参数指定要检查的列及上次已导入的最大值。
以下代码段完成append模式的增量导入,它将导入sno值超过7 000的行。
$sqoop import \
--connect jdbc: mysql://dbsvr1/jwdb? characterEn⁃conding=UTF-8 \
--username root --password root \
--table student \
--target-dir /jwxtdir/students/incredata -m 2 \
--incremental append --check-column sno --last-value 7000
以下代码段实现lastmodified模式的增量导入,它将抽取“2024-03-16 22:33:42”以后新产生的行进行导入。
$sqoop import \
--connect jdbc: mysql://dbsvr2/yktdb? characterEn⁃conding=UTF-8 \
--username root --password root \
--table cards \
--target-dir /yktdbdir/cards/incredata -m 2 \
--incremental lastmodified \