为了能利用大数据技术处理和存储关系型数据(如mysql,oracle),首先需将这些数据导入到像HDFS、HBase这样的大数据存储系统中,以便使用MapReduce、Spark这样的分布式计算技术进行高效分析和处理。从另一个角度讲,为了便于与前端的数据可视化系统对接,我们通常需要讲Hadoop大数据系统分析产生的结果(如报表,通常数据量不会太大)导回到关系型数据库中。为了解决上述问题,高效地实现关系型数据库与Hadoop之间的数据导入导出,Hadoop生态系统提供了工具Sqoop(SQL to Hadoop),以下重点剖析Sqoop设计思想,基本架构以及常见的使用场景。
1、Apache Sqoop是一个性能高、易用、灵活的数据导入导出工具,解决了关系型数据库与Hadoop之间的数据传输问题。
2、设计动机:数据迁移、可视化分析结果、数据增量导入
3、基本思想:Sqoop采用插拔式Connector架构,Connector是与特定数据源相关的组件,主要负责抽取和加载数据,可自己定制。
4、特点:性能高、自动类型转换、自动传播元信息
1、Sqoop1(1.4.x)基本架构
Sqoop1 实际上是一个只有 Map 的 MapReduce 作业,只是一个客户端工具。
当用户通过shell命令提交迁移作业后,Sqoop会从关系型数据库中读取元信息,并根据并发度和数据表大小将数据划分成若干分片,每片交给一个Map Task处理,这样,多个Map Task同时读取数据库中的数据,并行将数据写入目标存储系统,比如HDFS、HBase和Hive等。
缺点:Connector定制麻烦(仅支持基于JDBC的Connector)、客户端软件繁多(Mysql、Hadoop/HBase/Hive、JDBC驱动、数据库厂商提供的Connector等)、安全性差(明文提供数据库的用户名和密码)
2、Sqoop2(1.9.x)基本架构
Sqoop2对Sqoop1进行了改进,引入了Sqoop Server,将所有管理工作放到Server端,包括Connector管理、MySQL/Hadoop相关的客户端、安全认证等,这使得Sqoop客户端变得非常轻,用户只需要通过命令行或浏览器便可随时随处使用Sqoop。Sqoop Server会根据用户创建的Sqoop Job生成一个MapReduce作业,提交到Hadoop集群中分布式执行。
Sqoop2主要组件及功能:
(1)Sqoop Client:用户可以通过客户端命令行(CLI)和浏览器两种方式,其中浏览器方式允许用户直接通过HTTP方式完成Sqoop的管理和数据的导入导出。
(2)Sqoop Server:
Connector:Connector被进一步抽象化和模块化,通用部分被抽取出来,本身只关注数据解析和加载相关的功能,包括Partitioner(如何对源数据分片)、Extractor(将一个分片中的数据解析成一条条记录,并输出)和Loader(读取Extractor输出的数据,并以特定格式写入目标数据源中)等主要模块。
Metadata:Sqoop中的元信息,包括可用的Connector列表、用户创建的作业和Link(实力化的一个Connector,以便创建作业时使用)等。元信息被存储在数据仓库中,默认使用轻量级数据库Apache Derby,用户也可根据需要替换成MySQL等其他数据库。
RESTful和HTTP Server:与客户端对接,相应客户端发出的RESTful请求和HTTP请求。
3、Sqoop1与Sqoop2对比
易用性方面:
Sqoop1:Client-Only架构,所有软件依赖部署到客户端;客户端仅支持命令行访问方式(CLI);客户端需访问Hive、HBase等数据源。
Sqoop2:Client/Server架构,所有软件依赖部署到服务器端,进而使得客户端很轻量级;客户端支持命令行和Web两种访问方式;服务器端访问Hive、HBase等数据源,客户端只需发送请求即可。
扩展性方面:
Sqoop1:Connector必须遵循JDBC模型;Connector实现需要考虑通用功能模块,比如下游数据流的文件格式转化、与其他系统(比如HDFS、Hive等)集成等;Sqoop根据配置隐式地为用户选择Connector,很容易导致Connector误用。
Sqoop2:Connector被进一步泛化,只需实现若干组件即可;通用功能模块被独立出来,用户设计Connector时只需考虑与特定数据源相关的数据抽取、数据加载等功能即可;用户可显式为作业指定Connector,避免误用。
安全性方面:
Sqoop1:仅支持Hadoop Security;无任何资源管理机制。
Sqoop2:增加对基于角色的安全访问控制;增加资源管理机制,用户可更加细粒度地管理作业所占用的资源,比如同时打开的连接数、显式删除连接等。
总结:Sqoop2通过将访问入口服务化,将所有的复杂功能放到服务器端,大大简化了客户端实现,使其更轻量级,进而变得更加易用。
1、Sqoop1使用方式
(1)import:将关系数据库(MySql、Oracle等)中的数据导入Hadoop(比如HDFS、HBase和Hive)中。关系型数据库中的每一条记录都被转化为HDFS文件中的一行,每条记录可表示为文本、二进制文件或SequenceFile等格式。
基本用法:sqoop import [generic-args] [import-args]
generic-args:Hadoop通用参数 import-args:import特有参数
Hadoop通用参数主要包括:
-conf 指定应用程序配置文件
-D
-fs
-jt
-files <逗号分隔的文件列表> 需要分发到集群中各个节点的文件列表
-libjars <逗号分隔的jar文件列表> 需要分发到集群中各个节点的jar文件列表,这些jar包会自动被加到任务环境变量CLASSPATH中
-archives <逗号分隔的归档文件列表> 需要分发到集群中各个节点的归档文件(主要指以“.tar”,".tar.gz"以及".zip"结尾的压缩文件)列表,这些文件会自动解压到任务的工作目录下。
import特有参数(可以通过“bin/sqoop import help”命令查看所有参数。):
--connect
--driver
--password
--username
--table
--target-dir
--as-textfile 保存在Hadoop的格式:文本文件
--as-parquetfile 保存在Hadoop的格式:Parquet文件
--as-avrodatafile 保存在Hadoop的格式:Avro文件
--as-sequencefile 保存在Hadoop的格式:二进制key/value文件sequenceFile
-m,--num-mappers
-e,--query
实例:
a、将MySQL数据库movie中表data中的数据导出到HDFS(user/用户/data)中:
bin/sqoop import --connect jdbc:mysql://mysql.example.com/movie --table data -username xicheng --password 123456
b、将MySQL数据库movie中表data中符合某种条件导出到HDFS(/prod/data)中:
bin/sqoop import --connect jdbc:mysql://mysql.example.com/movie --username xicheng --password 123456 --num-mapper 10 --query "select name,id from data where date > 10" --target-dir /prod/data
(2)export:将Hadoop中的数据导回到关系型数据库中。HDFS中的文件将按照某个设定的分隔符拆分成一条条记录,插入到数据库表中。
基本用法:sqoop export [generic-args] [export-args]
export特有参数:
--connect
--driver
--password
--username
--table
--export-dir
--update-key
--update-mode
-m,--num-mappers
实例:
a、将HDFS中 /user/用户/data目录下的数据导入MySQL数据库movie中表data中:
bin/sqoop export --connect jdbc:mysql://mysql.example.com/movie --table data --export-dir /user/用户/data/ --username xicheng --password 123456
b、将HDFS中数据(逗号分隔)增量导入MySQL表中:
bin/sqoop export --connect jdbc:mysql://mysql.example.com/movie --table data --export-dir /user/用户/data --username xicheng --password 123456 --update-key id --update-mode allowinsert
2、Sqoop2使用方式
(1)关键概念
Connector:访问某种数据源的组件,负责从数据源中读取数据,或将数据写入数据源,Sqoop2内置了多种数据源,具体如下:
generic-jdbc-connector:访问支持JDBC协议数据库的Connector
hdfs-connector:访问Hadoop HDFS的Connector
kafka-connector:访问分布式消息队列Kafka的Connector
kite-connector:使用Kite SDK实现,可访问HDFS/HBase/Hive
Link:一个Connector实例
Job:完成数据迁移功能的分布式作业,可从某个数据源(From link)中读取数据,并导入到另一种数据源(To link)中。
(2)创建Link
进入Sqoop2提供的shell命令行:sqoop.sh client
查看Sqoop2提供的所有可用Connector:show connector
创建一个link:create link -c
查看已创建的Link:show link
实例:
a、创建一个JDBC类型的Link
create link -c 4
Name:MySQL-Reader
JDBC Driver Class:com.mysql.jdbc.Driver
JDBC Connection String:jdbc:mysql://localhost/movie
Username:dongxicheng
Password:123456
b、创建一个HDFS类型的Link
create link -c 3
Name:HDFS-Loader
HDFS URI:hdfs://localhost:8020
(3)创建Job(扩展:更新update、删除delete、复制clone)
创建从 link-id1 到 link-id2 的数据迁移作业的命令:create job -f
实例:
create job -f 1 -t 2
Name:mysql-to-hdfs
Schema name:movie
Table name:user
Partition column name:userid
Output format:0(TEXT_FILE)
Compression format:0(NONE)
output directory:/tmp/xicheng/user_table
Extractors:5
Loaders:2
注释:除了“Name”(job名称),“Schema Name”(数据库名称),“Table Name”(表名)和“Partition column name”(采用指定的列对数据分片,每片由一个任务处理,通常设置为主键),其他均可以使用默认值。“Extractors”和“Loaders”两栏相当于指定Map Task(默认是10)和Reduce Task的数目。
(4)提交并监控Job
将作业提交到集群中:start job -jid
查看作业运行状态:status job -jid
对于Sqoop Import任务,由于Hadoop CleanUp Task的存在,这个问题不存在
对于Sqoop Export任务则提供了一个“中间表”的解决办法
先将数据写入到中间表,写入中间表成功,在一个transaction中将中间表的数据写入目标表
Sqoop采用MapReduce可进行全量关系型数据的收集,但难以高效地增量收集数据。在很多场景下,除了收集数据库全量数据外,还希望只获取增量数据,即MySQL某个表从某个时刻开始修改/插入/删除的数据,该操作被称为CDC。为了实现CDC,可选的方案有:定时扫描整表(性能低,延迟高)、写双份数据(凡是数据更新,除了改数据库,同时将更新的数据发送到数据收集器,需业务层写代码,一致性难以保证)、利用触发器机制(管理繁琐,且对数据库性能影响大)
为了克服以上三种方案的问题,基于事务或提交日志解析的方案出现了。这种方案通过解析数据库更新日志,还原更新的数据,能够在不对业务层代码做任何修改的前提下,高效地获取更新数据。目前常见的开源实现有阿里巴巴的Canal和LinkedIn的Databus(Databus更强大,包括支持更多的数据源Oracle、MySQL等)。以下以Canal为主。
1、CDC动机与应用场景
主要功能:捕获数据库中的数据更新,将增量数据发送给各个订阅者和消费者。
应用:异地机房同步、数据库实时备份、业务Cache刷新、数据库全库迁移
2、CDC开源实现Canal
Canal主要定位:基于数据库增量日志解析,提供增量数据订阅和消费,目前主要支持了MySQL关系型数据库。
Canal主要原理:模拟数据库的主备复制协议,接收主数据库产生的binary log(简称 binlog),进而捕获更新数据。
Canal的模块化架构:
Canal Server:代表一个Canal实例,对应于一个JVM
Canal Instance:对应于一个数据队列(1个Canal Server对应1到n个instance),主要包括:
EventParse:数据源接入,模拟slave协议和master进行交互,协议解析
EventSink:Parser和Store链接器,进行数据过滤、加工、分发的工作
EventStore:数据存储
MetaManager:增量订阅和消费信息管理器
以MySQL为例:
(1)Canal实现MySQL主备复制协议,向MySQL Server发送dump协议
(2)MySQL收到dump请求,开始推送binlog给Canal
(3)Canal解析binlog对象,并发送给各个消费者
3、多机房数据同步系统Otter
Otter是Canal消费端的一个实现,定位是分布式数据库同步系统,它基于数据库增量日志解析,准时同步到本机房或异地机房的MySQL/Oracle数据库。
(1)Otter基本原理
采用典型的管理系统架构:Manager(Web管理)+ Node(工作节点)。Manager负责发布同步任务配置,接收同步任务反馈的状态信息等。Node节点负责执行同步任务,并将同步状态反馈给Manager。为了解决分布式状态调度,许多Node节点之间协同工作,Otter采用了开源分布式协调组件Zookeeper。
(2)Otter的S、E、T、L阶段模型
Select阶段:与数据源对接的阶段,为解决数据来源的差异性而引入
Extract、Transform、Load阶段:类似于数据仓库的ETL模型,即数据提取、数据转换和数据载入三个阶段。用户可根据需要设置不同阶段部署的方式,比如在夸机房同步的场景中,Select和Extract一般部署在原机房,而Transform和Load则部署在目标机房。
(3)Otter夸机房数据同步
用户通过Manager可设置跨机房同步任务。在原机房中,数据由Canal获取后,经数据接入和数据提取两个阶段处理后,通过网络发送给目标机房,在目标机房中,经数据转换和数据载入两个阶段处理后,最终将数据写入新的数据库或消息队列等系统。
说明:数据涉及网络传输,S、E、T、L 几个阶段会分散在2个或者更多的Node节点上,多个Node之间通过ZooKeeper进行协同工作(一般是Select和Extract在一个机房的Node,Transform/Load落在另一个机房的Node)。Node节点可以有failover/loadBalancer。
---内容主要来自于《大数据技术体系详解:原理、架构与实践》