Hadoop学习笔记:分布式数据收集系统Flume和Sqoop

背景

Hadoop提供了一个中央化的存储系统,有利于进行集中式的数据分析与数据共享。Hadoop对存储格式没有要求,包括用户访问日志、产品信息和网页数据等。但是,数据分散在各个离散的设备上或保存在传统的存储设备和系统中,我们需要将数据存入Hadoop。常见数据来源包括网页信息、用户操作日志等非结构化数据和传统关系型数据库(像MySQL、Oracled等)中的结构化数据,例如商品信息、用户信息等。如何将分散的、多样化的数据源中的数据收集整理后可靠的迁移到Hadoop系统中,并且要支持数据源的动态扩展,通过并行处理提高性能是需要解决的问题。

Flume(分布式非结构化数据收集系统)

Flume是由Cloudera公司开源的分布式、可靠、高可用的海量日志数据采集系统,数据源和数据存储系统支持定制和扩展。Flume属于一种中间件,屏蔽了数据源和数据存储系统的异构性。Flume有如下特点:

  • 高可靠性,保证数据不丢失
  • 高可扩展性,各组件数目可以扩展
  • 高性能,吞吐率很高,能满足海量数据收集的需求
  • 可管理,可以动态增加和删除组件
  • 文档丰富,社区活跃,已经成为Hadoop生态系统的标配

Flume NG基本架构

Flume分Flume OG和Flume NG两个版本,Flume NG架构有所简化,代码更精简。
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第1张图片
Flume可以将数据从任一地方搬运到任一其他地方,不一定是HDFS。Agent是Flume中类似数据搬运工的组件,从上面的架构中看,四个Client(机器或是应用程序)中的数据写入Agent,如果前一层Agent数量太多,就把Agent汇总到后一层Agent再传递,Agent数量太多会对HDFS的冲击太大,而且会产生大量的小文件。
Agent的内部由Source(负责获取数据,是数据的源头)、Channel(类似缓冲区)和Sink(从Channel拿数据发给后端)组成。Agent是一个生产者和消费者模型,如果生产者和消费者数据量不对等,会产生数据堆积,所以引入缓冲区Channel。Source、Channel和Sink支持插拔,Flume提供了很多类型的Source、Channel和Sink,可以根据实际情况进行配置,整体开发量比较小。

Flume NG核心概念

  • Event
    Event是Flume数据传输的基本单元,Flume以事件的形式将数据从源头传送到最终的目的。Event由可选的Header和载有数据的一个Byte Array构
    成。一个Event代表一条数据,数据可以是文本等各种格式。Event载有的数据对Flume是不透明的。Header是容纳了Key-Value字符串对的无序集合,比如设置图片的Topic,图像类、风景类等,Key在集合内是唯一的。Header可以在上下文路由中使用扩展。Byte Array可以是一个文本。
  • Client
    Client将原始数据包装成多个Event后发送到一个或多个Agent。目的是从数据源系统中解耦Flume。Client是一个客户端,是API接口,可以调用接口把数据写到Agent里。Client在Flume的拓扑结构中不是必须的。Client实体可以使用Client SDK (org.apache.flume.api)定制。Flume log4j Appender是一种Client实体。
  • Agent
    Agent是Flume中最重要的组件,一个Agent包含Source, Channel, Sink和其他组件,它利用这些组件将Event从一个节点传输到另一个节点或最终
    目的,Agent是Flume流的基础部分,Flume为这些组件提供了配置、生命周期管理、监控支持。
    1、Source
    Source负责接收Event或通过特殊机制产生Event,并将Event批量的放到一个或多个Channel中。Source包含Event驱动和轮询2种类型。
    Source分以下类型:
    1)与系统集成的Source: Syslog, Netcat
    2)自动生成事件的Source: Exec
    3)监听文件夹下文件变化:Spooling Directory Source,
    Taildir Source
    4)用于Agent和Agent之间通信的IPC Source: Avro、Thrift
    Source必须至少和一个channel关联。
    监听文件夹下文件变化是比较常用的类型:
    Spooling Directory Source:
    监听一个文件夹下新产生的文件,将文件中每行数据包装成一个Event发送至 Channel。已经产生的文件不能进行任意修改,不然会停止处理,建议将文件(唯一文件名)写到临时目录,之后再转移到监听目录下。
    Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第2张图片代码示例
a1.channels = ch-1 
a1.sources = src-1
a1.sources.src-1.type = spooldir 
a1.sources.src-1.channels = ch-1 
a1.sources.src-1.spoolDir = /var/log/apache/flumeSpool 
a1.sources.src-1.fileHeader = true

配置文件中配置Agent为a1。Channel和Source可以设置多个,所以Agent属性是channels和sources,Source要设置是对应哪个Channel。

Taildir Source
监听文件内容,一旦写入一行新数据,则读取。支持断点续读,定期将最新读取数据的偏移量写入json文件,根据文件修改时间决定读取优先级,最新的文件优先读取,读取完的文件不会做任何处理(比如删除,重命名等),目前仅支持文本文件。
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第3张图片代码示例

a1.sources = r1
a1.channels = c1
a1.sources.r1.type = TAILDIR
a1.sources.r1.channels = c1
a1.sources.r1.positionFile = /var/log/flume/taildir_position.json a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1 = /var/log/test1/example.log a1.sources.r1.headers.f1.headerKey1 = value1 
a1.sources.r1.filegroups.f2 = /var/log/test2/.*log.* a1.sources.r1.headers.f2.headerKey1 = value2 a1.sources.r1.headers.f2.headerKey2 = value2-2 
a1.sources.r1.fileHeader = true

用filegroups参数可以支持多个目录

Exec
可执行任意Unix命令 ,无容错性。

a1.sources = r1
a1.channels = c1
a1.sources.r1.type = exec 
a1.sources.r1.command = tail -F /var/log/secure 
a1.sources.r1.channels = c1

Avro
Avro是一个RPC框架,由多个Client和一个Server组成,Client和Server的开发语言可以不一样。
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第4张图片启动一个avro server,监听端口号
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第5张图片代码示例

a1.sources = r1 
a1.channels = c1 
a1.sources.r1.type = avro 
a1.sources.r1.channels = c1 
a1.sources.r1.bind = 0.0.0.0 
a1.sources.r1.port = 4141

2、Channel
Channel位于Source和Sink之间,用于缓存Event。当Sink成功将Event发送到下一跳的Channel或最终目的,Event从Channel移除。Sink发出去一条数据,就从Channel里删除一条数据,一个Channel可以和任何数量的Source和Sink工作,提供较弱的顺序保证,支持事务,具有并发控制,不会重复推送数据到一个Sink。

不同的Channel提供的持久化水平也是不一样的:
Memory Channel:
允许数据丢失,性能高,牺牲数据可靠性
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第6张图片代码示例

a1.channels = c1
a1.channels.c1.type = memory 
a1.channels.c1.capacity = 10000 
a1.channels.c1.transactionCapacity = 10000 
a1.channels.c1.byteCapacityBufferPercentage = 20 
a1.channels.c1.byteCapacity = 800000

容量是根据内存设置,不设置容量,当数据往Sink发送不及时,会撑爆内存。容量分条数(capacity)设置和容量(byte capacity)设置两部分,有一个先满足就不往里写了。

File Channel:
基于WAL(预写式日志Write-Ahead Logging)实现,数据不会丢失,牺牲性能,数据可靠性高
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第7张图片代码示例

a1.channels = c1
a1.channels.c1.type = file 
a1.channels.c1.checkpointDir = /mnt/flume/checkpoint 
a1.channels.c1.dataDirs = /mnt/flume/data

支付File的Channel支持断点续读,由checkpoint文件实现。

JDBC Channel:
基于嵌入Database实现,使用率不高

2、Sink
Sink负责将Event传输到下一跳或最终目的,成功完成后将Event从Channel移除。Sink必须作用于一个确切的channel。
Sink的类型:
1)存储Event到最终目的的终端Sink. 比如: HDFS, HBase
HDFS Sink
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第8张图片

a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S  
#会自动转换为当时的日期和时间,精确到秒
a1.sinks.k1.hdfs.filePrefix = events- 
#设置使用什么作为文件前缀
a1.sinks.k1.hdfs.round = true #如果文件比较大,需要设置Round=true
a1.sinks.k1.hdfs.roundValue = 10 
a1.sinks.k1.hdfs.roundUnit = minute
#10分钟写入一个文件,下一个10分钟写入另外一个文件
a1.sinks.k1.hdfs.codeC=gzip, bzip2, lzo, lzop, snappy 
#codec是写入文件的压缩方式,使用哪个就选哪个,选一个就可以了,不要全选
a1.sinks.k1.hdfs.fileType=SequenceFile, DataStream,CompressedStream
#filetype是文件的存储格式,使用哪个就选哪个,选一个就可以了,不要全选

HBase Sink
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第9张图片

a1.sinks = k1
a1.sinks.k1.type = hbase
a1.sinks.k1.table = foo_table
a1.sinks.k1.columnFamily = bar_cf
a1.sinks.k1.serializer = org.apache.flume.sink.hbase.RegexHbaseEventSerializer a1.sinks.k1.channel = c1

Hive Sink
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第10张图片Hive 创建table weblogs
在这里插入图片描述

a1.channels = c1
a1.channels.c1.type = memory
a1.sinks = k1
a1.sinks.k1.type = hive
a1.sinks.k1.channel = c1
a1.sinks.k1.hive.metastore = thrift://127.0.0.1:9083 a1.sinks.k1.hive.database = logsdb
a1.sinks.k1.hive.table = weblogs
a1.sinks.k1.hive.partition = asia,%{country},%y-%m-%d-%H-%M a1.sinks.k1.useLocalTimeStamp = false
a1.sinks.k1.round = true
a1.sinks.k1.roundValue = 10
a1.sinks.k1.roundUnit = minute
a1.sinks.k1.serializer = DELIMITED
a1.sinks.k1.serializer.delimiter = "\t" a1.sinks.k1.serializer.serdeSeparator = '\t' a1.sinks.k1.serializer.fieldnames =id,,msg

2)自动消耗的Sink. 比如: Null Sink
3)用于Agent间通信的IPC Sink: Avro

  • Interceptor
    作用于Source,按照预设的顺序在必要地方装饰和过滤Event。
  • Channel Selector
    允许Source基于预设的标准,从所有Channel中,选择一个或多
    个Channel。
  • Sink Processor:
    多个Sink可以构成一个Sink Group。Sink Processor可以通过组中
    所有Sink实现负载均衡;也可以在一个Sink失败时转移到另 一个。

Flume 常用实例

实例1
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第11张图片场景:从四台机器的文件夹下取数据传输到HDFS的/data/logs目录下,Source使用pooldir,为了提高性能,使用Memory Channel,Sink使用HDFS Sink。
命名:
Agent: LogAgent
Source: mysource
Channel: mychannel
Sink: mysink
代码:

 LogAgent.sources = mysource 
 LogAgent.channels = mychannel 
 LogAgent.sinks = mysink
LogAgent.sources.mysource.type = spooldir 
LogAgent.sources.mysource.channels = mychannel LogAgent.sources.mysource.spoolDir =/tmp/logs
LogAgent.sinks.mysink.channel = mychannel
LogAgent.sinks.mysink.type = hdfs
LogAgent.sinks.mysink.hdfs.path = hdfs://master:8020/data/logs/%Y/%m/%d/ %H/
LogAgent.sinks.mysink.hdfs.batchSize = 1000 
#设置一批写1000条数据
#文件滚动就是当源文件比较大的时候,如何生成新的文件,使得新的文件不要太大
#也不要太小,两种方式:1)按照大小;2)按照条数。
LogAgent.sinks.mysink.hdfs.rollSize = 0 
#文件滚动大小,设置为0说明不按照文件大小滚动
LogAgent.sinks.mysink.hdfs.rollCount = 10000 
#文件滚动的条数,这里设置按照一个文件超过10000行后生成另外一个新文件
LogAgent.sinks.mysink.hdfs.useLocalTimeStamp = true
LogAgent.channels.mychannel.type = memory LogAgent.channels.mychannel.capacity = 10000

进入Flume的安装文件夹运行:
1)调试模式:

bin/flume-ng agent -n LogAgent -c conf -f conf/ logagent.properties -Dflume.root.logger=DEBUG,console

2)运行模式:

bin/flume-ng agent -n LogAgent -c conf -f conf/ logagent.properties 

3)后台模式:

bin/flume-ng agent -n LogAgent -c conf -f conf/ logagent.properties -Dflume.root.logger=DEBUG,console &

LogAgent是Agent的命名,-f标识是配置文件,conf/flume-conf.properties是配置文件。

实例2
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第12张图片
第一层(Tier 1)配置实例

a1.channels = c1 
a1.sources = r1 
a1.sinks = k1 k2 
#配置两个SINK可以让下发速度更快一些
a1.sinkgroups = g1
a1.sinkgroups.g1.processor.type = LOAD_BALANCE 
a1.sinkgroups.g1.processor.selector = ROUND_ROBIN 
a1.sinkgroups.g1.processor.backoff = true
a1.channels.c1.type = FILE
a1.sources.r1.channels = c1 
a1.sources.r1.type = AVRO 
a1.sources.r1.bind = 0.0.0.0 
a1.sources.r1.port = 41414
a1.sinks.k1.channel = c1 
a1.sinks.k1.type = AVRO 
a1.sinks.k1.hostname = a21.example.org 
a1.sinks.k1.port = 41414
a1.sinks.k2.channel = c1 
a1.sinks.k2.type = AVRO 
a1.sinks.k2.hostname = a22.example.org 
a1.sinks.k2.port = 41414

第二层(Tier 2)配置实例

a2.channels = c1 
a2.sources = r1 
a2.sinks = k1
a2.channels.c1.type = FILE
a2.sources.r1.channels = c1 
a2.sources.r1.type = AVRO 
a2.sources.r1.bind = 0.0.0.0 
a2.sources.r1.port = 41414
a2.sinks.k1.channel = c1
a2.sinks.k1.type = HDFS
a2.sinks.k1.hdfs.path = hdfs://namenode.example.org 
a2.sinks.k1.hdfs.fileType = DataStream

Sqoop(分布式结构化数据收集系统)

关系数据库与Hadoop之间传递数据使用Sqoop(SQL-to-Hadoop),它是连接传统关系型数据库和Hadoop 的桥梁,它可以把关系型数据库的数据导入到 Hadoop 系统 ( 如 HDFSHBase 和 Hive) 中,也可以把数据从 Hadoop 系统里抽取并导出到关系型数据库里。它使用批处理方式进行数据传输,并且利用MapReduce加快数据传输速度。它具有以下优势:

  • 高效、可控地利用资源,任务并行度,超时控制
  • 数据类型映射与转换支持自动进行,也支持用户自定义
  • 支持多种数据库(MySQL、Oracle、PostgreSQL)

Sqoop的架构

Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第13张图片

Sqoop Import(将数据从关系型数据库导入Hadoop中)

步骤1:Sqoop与数据库Server 通信,获取数据库表的元数据 信息;
步骤2:Sqoop启动一个Map- Only的MR作业,利用元数据信息并行将数据写入Hadoop。
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第14张图片

 sqoop import \
--connect jdbc:mysql://mysql.example.com/sqoop \ 
--username sqoop \
--password sqoop \
--table cities

–connnect: 指定JDBC URL
–username:mysql数据库的用户名
–password:mysql数据库的密码
–table:要读取的数据库表

执行后会在HDFS上创建一个和数据库表名一样的文件夹,拷贝到HDFS上的文件默认是文本文件,每列用逗号隔开。
例如:
bin/hadoop fs -cat cities/part-m-*
1,USA,Palo Alto
2,Czech Republic,Brno
3,USA,Sunnyvale

Sqoop Export(将数据从Hadoop导入关系型数据库导中)

步骤1:Sqoop与数据库Server 通信,获取数据库表的元数据信息;
步骤2:并行导入数据:将Hadoop上文件划分成若干个split;每个split由一个Map Task进行数据导入。
Hadoop学习笔记:分布式数据收集系统Flume和Sqoop_第15张图片

sqoop export \
--connect jdbc:mysql://mysql.example.com/sqoop \ 
--username sqoop \
--password sqoop \
--table cities \
--export-dir cities

–connnect: 指定JDBC URL
–username:mysql数据库的用户名
–password:mysql数据库的密码
–table:要导入的数据库表
–export-dir:数据在HDFS上存放目录

Sqoop 与其他系统结合

sqoop import \
--connect jdbc:mysql://mysql.example.com/sqoop \ 
--username sqoop \
--password sqoop \
--table cities \
--hive-import

sqoop import \
--connect jdbc:mysql://mysql.example.com/sqoop \ 
--username sqoop \
--password sqoop \
--table cities \
--hbase-table cities \
--column-family world

你可能感兴趣的:(Hadoop)