flume&sqoop
一. 背景
Hadoop提供了一个中央化的存储系统
有利于进行集中式的数据分析与数据共享
Hadoop对存储格式没有要求:
- 用户访问日志
- 产品信息
- 网页数据等
如何将数据存入Hadoop
- 数据分散在各个离散的设备上
- 数据保存在传统的存储设备和系统
常见的两种数据来源
分散的数据源
- 机器产生的数据
- 用户访问日志
- 用户购买日志
传统系统中的数据:
- 传统关系型数据库:MySQL、Oracle等;
- 磁盘阵列;
- 磁带
Hadoop收集和入库基本要求
分布式
- 数据源多样化
- 数据源分散
可靠性
- 保证不丢数据
- 允许丢部分数据
可扩展
- 数据源可能会不断增加
通过并行提高性
常见的Hadoop收集与入库系统
数据收集
- Flume
- Kafka
- Scribe
传统数据库与Hadoop同步
- Sqoop
二. Hadoop数据收集系统—Flume
Flume OG
- OG:“Original Generation”
- 0.9.x或cdh3以及更早版本
- 由agent、collector、master等组件构成
Flume NG
- NG:“Next/New Generation”
- 1.x或cdh4以及之后的版本
- 由Agent、Client等组件构成
为什么要推出NG版本
- 精简代码
- 架构简化
 ![]() 
agent产生数据,由collector汇总
master监控前两者的状态

Agent
用于采集数据
数据流产生的地方
通常由source和sink两部分组成
- Source用于获取数据,可从文本文件,syslog,HTTP等获 取数据;
- Sink将Source获得的数据进一步传输给后面的Collector。
Flume自带了很多source和sink实现
- syslogTcp(5140) | agentSink("localhost",35853)
- tail("/etc/services") | agentSink("localhost",35853)
**Collector **
汇总多个Agent结果
将汇总结果导入后端存储系统,比如HDFS,HBase
Flume自带了很多collector实现
- collectorSource(35853) | console
- collectorSource(35853) | collectorSink("file:///tmp/flume/collected", "syslog");
- collectorSource(35853) | collectorSink("hdfs://namenode/user/flume/ ","syslog");
Agent和Collector对应关系

可手动指定,也可自动匹配
自动匹配的情况下,master会平衡collector之间的负载

可以配置定时写一次,或者汇集多少数据写一次。
为什么引入collector?
- 对Agent数据进行汇总,避免产生过多小文件;
- 避免多个agent连接对Hadoop造成过大压力 ;
- 中间件,屏蔽agent和hadoop间的异构性
**Master **
管理协调agent和collector的配置信息;
Flume集群的控制器;
跟踪数据流的最后确认信息,并通知agent;
通常需配置多个master以防止单点故障;
借助zookeeper管理管理多Master
容错机制

每个agent配置多个collect,首先导入主的collect上,如果挂了拷贝到备的collect上
如果hdfs挂了,collect保存本地
如果collect都挂了,agent保存本地
三种可靠性级别
- agentE2ESink[("machine"[,port])]
 agent收到确认消息才认为数据发送成功,否则重试.
- agentDFOSink[("machine"[,port])]
 当agent发现在collector操作失败的时候,agent写入到本地硬盘上,当 collctor恢复后,再重新发送数据。
- agentBESink[("machine"[,port])]
 效率最好,agent不写入到本地任何数据,如果在collector 发现处理失败, 直接删除消息
**构建基于Flume的数据收集系统 **
Agent和Collector均可以动态配置
可通过命令行或Web界面配置
命令行配置
- 在已经启动的master节点上,依次输入"flume shell"->"connect localhost"
 如执行 exec config a1 'tailDir("/data/logfile")' 'agentSink'
Web界面
- 选中节点,填写source、sink等信息
例子-拓扑1
agentA : tail(“/ngnix/logs”) | agentSink("collector",35853); 
agentB : tail(“/ngnix/logs”) | agentSink("collector",35853); 
agentC : tail(“/ngnix/logs”) | agentSink("collector",35853); 
agentD : tail(“/ngnix/logs”) | agentSink("collector",35853); 
agentE : tail(“/ngnix/logs”) | agentSink("collector",35853); 
agentF : tail(“/ngnix/logs”) | agentSink("collector",35853); 
collector : collectorSource(35853) | collectorSink("hdfs://namenode/flume/","srcdata"); 
srcdata是文件的前缀

**例子—拓扑2 **
agentA : src | agentE2ESink("collectorA",35853); 
agentB : src | agentE2ESink("collectorA",35853); 
agentC : src | agentE2ESink("collectorB",35853); 
agentD : src | agentE2ESink("collectorB",35853); 
agentE : src | agentE2ESink("collectorC",35853); 
agentF : src | agentE2ESink("collectorC",35853); 
collectorA : collectorSource(35853) | collectorSink("hdfs://...","src"); 
collectorB : collectorSource(35853) | collectorSink("hdfs://...","src"); 
collectorC : collectorSource(35853) | collectorSink("hdfs://...","src"); 

例子—拓扑3
agentA : src | agentE2EChain("collectorA:35853","collectorB:35853"); 
agentB : src | agentE2EChain("collectorA:35853","collectorC:35853"); 
agentC : src | agentE2EChain("collectorB:35853","collectorA:35853"); 
agentD : src | agentE2EChain("collectorB:35853","collectorC:35853"); 
agentE : src | agentE2EChain("collectorC:35853","collectorA:35853"); 
agentF : src | agentE2EChain("collectorC:35853","collectorB:35853"); 
collectorA : collectorSource(35853) | collectorSink("hdfs://...","src"); 
collectorB : collectorSource(35853) | collectorSink("hdfs://...","src"); 
collectorC : collectorSource(35853) | collectorSink("hdfs://...","src"); 

三. 传统数据库与Hadoop间数据同步
Sqoop是什么
Sqoop:SQL-to-Hadoop
连接 传统关系型数据库 和 Hadoop 的桥梁
- 把关系型数据库的数据导入到 Hadoop 系统 (如 HDFS HBase 和 Hive) 中;
- 把数据从 Hadoop 系统里抽取并导出到关系型数据库里。
 利用MapReduce加快数据传输速度
 批处理方式进行数据传输
Sqoop优势
高效、可控地利用资源
- 任务并行度,超时时间等
数据类型映射与转换
- 可自动进行,用户也可自定义
支持多种数据库
- MySQL
- Oracle
- PostgreSQL
Sqoop1

Sqoop2

将数据从关系型数据库导入Hadoop中
步骤1:Sqoop与数据库Server通信获取数据库表的元数据 信息;
步骤2:Sqoop启动一个MapOnly的MR作业,利用元数据信 息并行将数据写入Hadoop
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities 
--connnect: 指定JDBC URL
--username/password:mysql数据库的用户名
--table:要读取的数据库表
查看
bin/hadoop fs -cat cities/part-m-* 
默认导入同名的目录下,如果想指定目录
sqoop import \      
    --connect jdbc:mysql://mysql.example.com/sqoop \      
    --username sqoop \    
    --password sqoop \     
    --table cities \     
    --target-dir /etl/input/cities 
导入符合某种要求的数据
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --where "country = 'USA'" 
默认是文本格式,如果想导成其他格式
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \    
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --as-sequencefile
限制并发map的数量,防止把这个数据库拖垮
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \    
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --num-mappers 10 
导入多个表,对表做join连接,然后导入
sqoop import \   
    --connect jdbc:mysql://mysql.example.com/sqoop \   
    --username sqoop \   
    --password sqoop \   
    --query 'SELECT normcities.id, \                  
            countries.country, \                  
            normcities.city \                  
            FROM normcities \                  
            JOIN countries USING(country_id) \                  
            WHERE $CONDITIONS' \ 
    --split-by id \ 
    --target-dir cities
增量导入
append模式,只增加,需要指定上一次最新id的值,然后这次id递增导入
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table visits \     
    --incremental append \     
    --check-column id \     
    --last-value 1 
适用于数据每次被追加到数据库中,而已有数据不变的情况;
仅导入id这一列值大于1的记录。
自动运行作业
sqoop job \   
    --create visits \   
    --import \   
    --connect jdbc:mysql://mysql.example.com/sqoop \   
    --username sqoop \   
    --password sqoop \   
    --table visits \   
    --incremental append \   
    --check-column id \   
    --last-value 0 运行sqoop作业:sqoop job 
    --exec visits 
运行sqoop作业:sqoop job --exec visits
每次成功运行后,sqoop将最后一条记录的id值保存到 metastore中,供下次使用,不用人工记忆id值了
update模式
sqoop import \   
    --connect jdbc:mysql://mysql.example.com/sqoop \   
    --username sqoop \   
    --password sqoop \   
    --table visits \   
    --incremental lastmodified \   
    --check-column last_update_date \   
    --last-value “2013-05-22 01:01:01” 
数据库中有一列last_update_date,记录了上次修改时间;
Sqoop仅将某时刻后的数据导入Hadoop
Sqoop Export
将数据从Hadoop导入关系型数据库导中
步骤1:Sqoop与数据库Server通信,获取数据库表的元数据 信息;
步骤2:并行导入数据:
- 将Hadoop上文件划分成若干个split;
- 每个split由一个Map Task进行数据导入
使用方法:
sqoop export \     
--connect jdbc:mysql://mysql.example.com/sqoop \     
--username sqoop \     
--password sqoop \     
--table cities \    
--export-dir cities 
--connnect: 指定JDBC URL
--username/password:mysql数据库的用户名
--table:要导入的数据库表
export-dir:数据在HDFS上存放目录
保证原子性
sqoop export \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --staging-table staging_cities
更新已有数据
不覆盖
sqoop export \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --update-key id 
已有数据覆盖
sqoop export \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --update-key id \     
    --update-mode allowinsert 
选择性导入
sqoop export \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --columns country,city
Sqoop与其他系统结合
Sqoop可以与Oozie、Hive、Hbase等系统结合;
用户需要在sqoop-env.sh中增加HBASE_HOME、 HIVE_HOME等环境变量
Sqoop与Hive结合
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --hive-import  
**Sqoop与HBase结合 **
sqoop import \     
    --connect jdbc:mysql://mysql.example.com/sqoop \     
    --username sqoop \     
    --password sqoop \     
    --table cities \     
    --hbase-table cities \     
    --column-family world 
参考:Apache Sqoop Cookboo
 
                    
                     
                    
                 
                    
                
 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号