目录

  • 简介
  • 一、概述
  • 1.1、工作方式
  • 1.2、优势
  • 1.3、特征
  • 1.4、核心组件概述
  • 1.4.1、Source
  • 1.4.2、Channel
  • 1.4.3、sink
  • 二、Flume 的体系结构
  • 2.1、Source
  • 2.2、Channel
  • 2.3、Sink
  • 三、Flume的部署类型
  • 3.1、单一流程
  • 3.2、多代理流程(多个agent顺序连接)
  • 3.3、流的合并(多个Agent的数据汇聚到同一个Agent)
  • 3.4、多路复用流(多级流)
  • 3.5、load balance功能
  • 四、Flume的日志收集输出(精华所在)
  • 4.1、netcat source,logger sink
  • 4.2、exec source,logger sink
  • 4.3、spooldir source,logger sink
  • 4.4、spooldir source,hdfs sink
  • 4.5、获取数据时添加拦截器过滤数据
  • 4.6、spooldir source,KafkaSink


简介

Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力

一、概述

1.1、工作方式

Flume-og 采用了多 Master 的方式。为了保证配置数据的一致性,Flume 引入了 ZooKeeper,用于保存配置数据,ZooKeeper 本身可保证配置数据的一致性和高可用,另外,在配置数据发生变化时,ZooKeeper 可以通知 Flume Master 节点。Flume Master 间使用 gossip 协议同步数据。

Flume-ng 最明显的改动就是取消了集中管理配置的 Master 和 Zookeeper,变为一个纯粹的传输工具。Flume-ng 另一个主要的不同点是读入数据和写出数据由不同的工作线程处理(称为 Runner)。 在 Flume-og 中,读入线程同样做写出工作(除了故障重试)。如果写出慢的话(不是完全失败),它将阻塞 Flume 接收数据的能力。这种异步的设计使读入线程可以顺畅的工作而无需关注下游的任何问题。

1.2、优势

  1. Flume 可以将应用产生的数据存储到任何集中存储器中,比如 HDFS,HBase
  2. 当收集数据的速度超过将写入数据的时候,也就是当收集信息遇到峰值时,这时候收集的信息非常大,甚至超过了系统的写入数据能力,这时候,Flume 会在数据生产者和数据收容器间做出调整,保证其能够在两者之间提供平稳的数据
  3. 提供上下文路由特征
  4. Flume 的管道是基于事务,保证了数据在传送和接收时的一致性
  5. Flume 是可靠的,容错性高的,可升级的,易管理的,并且可定制的

1.3、特征

  1. Flume 可以高效率的将多个网站服务器中收集的日志信息存入 HDFS/HBase 中
  2. 使用 Flume,我们可以将从多个服务器中获取的数据迅速的移交给 Hadoop 中
  3. 除了日志信息,Flume 同时也可以用来接入收集规模宏大的社交网络节点事件数据,比如facebook,twitter,电商网站如亚马逊,flipkart 等
  4. 支持各种接入资源数据的类型以及接出数据类型
  5. 支持多路径流量,多管道接入流量,多管道接出流量,上下文路由等
  6. 可以被水平扩展

1.4、核心组件概述

  • Client:客户端,数据产生的地方,如Web服务器
  • Event:事件,指通过 Agent 传输的单个数据包,如日志数据通常对应一行数据
  • Flow:Event 从源点到达目的点的迁移的抽象
  • Agent:一个独立的 JVM 进程,Agent 使用JVM 运行 Flume

Agent 主要由:source,channel,sink 三个组件组成

1.4.1、Source

从数据发生器接收数据,并将接收的数据以 Flume 的 event 格式传递给一个或者多个通道channel,Flume 提供多种数据接收的方式,比如 Avro,Thrift,twitter1% 等

1.4.2、Channel

channel 是一种短暂的存储容器,它将从 source 处接收到的 event 格式的数据缓存起来,直到它们被 sinks 消费掉,它在 source 和 sink 间起着桥梁的作用,channel 是一个完整的事务,这一点保证了数据在收发的时候的一致性;并且它可以和任意数量的 source 和 sink 链接,支持的类型有:JDBC channel,File System channel,Memory channel 等

1.4.3、sink

sink 将数据存储到集中存储器比如 Hbase 和 HDFS,它从 channels 消费数据(events)并将其传递给目标地,目标地可能是另一个 sink,也可能 HDFS,HBase

二、Flume 的体系结构

Flume 运行的核心是 Agent,Flume 以 agent 为最小的独立运行单位;一个 agent 就是一个JVM;它是一个完整的数据收集工具,含有三个核心组件,分别是 source,channel,sink;通过这些组件,Event 可以从一个地方流向另一个地方,如下图所示

flume tail日志文件 flume收集日志的多种方式_大数据

2.1、Source

Source 是数据的收集端,负责将数据捕获后进行特殊的格式化,将数据封装到事件(event)里,然后将事件推入 Channel 中

Flume 提供了各种 source 的实现,如果内置的 Source 无法满足需要,Flume 还支持自定义 Source

Flume 常用 Source 如下

  • exec source:执行 Linux 指令,并消费指令返回的结果,如tail -f
  • spooling directory source:从磁盘文件夹中获取文件数据,可避免重启或者发送失败后数据丢失,还可用于监控文件夹新文件
  • http source:用于接收HTTP的Get和Post请求
  • avro source:监听Avro端口,并从外部Avro客户端接收events
  • kafka source:从 Kafka 接收数据
  • netcat source:从 NetCat 服务器接收数据

exec source
执行 Linux 指令,并消费指令返回的结果

属性

缺省值

描述

type

-

exec

command

-

tail -f xxx.log

shell

-

选择系统Shell程序,如/bin/sh

batchSize

20

发送给channel的最大行数

command 可执行脚本for i in /path/*.txt; do echo $i; done遍历目录

spooling directory source
从磁盘文件夹中获取文件数据,可避免重启或者发送失败后数据丢失,还可用于监控文件夹新文件

属性

缺省值

描述

type

-

spooldir

spoolDir

-

需读取的文件夹

fileSuffix

.COMPLETED

文件读取完成后添加的后缀

deletePolicy

never

文件完成后删除策略:never和immediate

http source
用于接收HTTP的Get和Post请求

属性

缺省值

描述

type

-

http

port

-

监听端口

bind

0.0.0.0

绑定IP

handler

org.apache.flume.source.http.JSONHandler

数据处理程序类全名

avro source
监听 Avro 端口,并从外部 Avro 客户端接收 events

属性

缺省值

描述

type

-

avro

port

-

监听端口

bind

-

绑定IP

threads

-

最大工作线程数量

2.2、Channel

Channel是连接Source和Sink的组件,大家可以将它看做一个数据的缓冲区(数据队列),它可以将事件暂存到内存中也可以持久化到本地磁盘上, 直到Sink处理完该事件

Flume 对于 Channel,则提供了 Memory Channel、JDBC Chanel、File Channel,etc

MemoryChannel:event保存在本地文件中,可靠性高,但吞吐量低于Memory Channel

FileChannel:保证数据的完整性与一致性。在具体配置不现的 FileChannel 时,建议 FileChannel 设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率

JDBC Channel:event保存在关系数据中,一般不推荐使用

2.3、Sink

Flume Sink 取出 Channel 中的数据,进行相应的存储文件系统,数据库,或者提交到远程服务器

Flume 也提供了各种 sink 的实现,包括 HDFS sink、Logger sink、Avro sink、File Roll sink、Null sink、HBase sink,Kafka sink,Hive sink

Flume Sink 在设置存储数据时,可以向文件系统中,数据库中,hadoop 中储数据,在日志数据较少时,可以将数据存储在文件系中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到 Hadoop 中,便于日后进行相应的数据分析

flume tail日志文件 flume收集日志的多种方式_hadoop_02


avro sink

作为 avro 客户端向 avro 服务端发送 avro 事件

属性

缺省值

描述

type

-

avro

port

-

监听端口

hostname

-

服务端IP地址

batch-size

100

批量发送事件数量

HDFS sink
将事件写入Hadoop分布式文件系统(HDFS)

属性

缺省值

描述

type

-

hdfs

hdfs.path

-

hdfs 目录

hfds.filePrefix

FlumeData

文件前缀

hdfs.fileSuffix

-

文件后缀

HBase sink

属性

缺省值

描述

type

-

hbase

table

-

要写入的 Hbase 表名

columnFamily

-

要写入的 Hbase 列族

zookeeperQuorum

-

对应hbase.zookeeper.quorum

znodeParent

/hbase

zookeeper.znode.parent

serializer

org.apache.flume.sink.hbase.SimpleHbaseEventSerializer

一次事件插入一列

serializer.payloadColumn

-

列名col1

三、Flume的部署类型

3.1、单一流程

指一个 Agent JVM 进程,如下图

flume tail日志文件 flume收集日志的多种方式_大数据

3.2、多代理流程(多个agent顺序连接)

多个 Agent 顺序连接起来,将最初的数据源经过收集,存储到最终的存储系统中。这是最简单的情况,一般情况下,应该控制这种顺序连接的 Agent 的数量,因为数据流经的路径变长了,如果不考虑 failover 的话,出现故障将影响整个Flow上的Agent收集服务。

flume tail日志文件 flume收集日志的多种方式_linux_04

3.3、流的合并(多个Agent的数据汇聚到同一个Agent)

这种情况应用的场景比较多,比如要收集 Web 网站的用户行为日志,Web 网站为了可用性使用的负载集群模式,每个节点都产生用户行为日志,可以为每 个节点都配置一个 Agent 来单独收集日志数据,然后多个 Agent 将数据最终汇聚到一个用来存储数据存储系统,如HDFS上

flume tail日志文件 flume收集日志的多种方式_hadoop_05

3.4、多路复用流(多级流)

Flume 还支持多级流,举个例子,当syslog, java, nginx、 tomcat 等混合在一起的日志流开始流入一个 agent 后,可以 agent 中将混杂的日志流分开,然后给每种日志建立一个自己的传输通道

flume tail日志文件 flume收集日志的多种方式_flume tail日志文件_06

3.5、load balance功能

下图 Agent1 是一个路由节点,负责将 Channel 暂存的 Event 均衡到对应的多个 Sink 组件上,而每个 Sink 组件分别连接到一个独立的 Agent 上

flume tail日志文件 flume收集日志的多种方式_hadoop_07

四、Flume的日志收集输出(精华所在)

4.1、netcat source,logger sink

创建 flume 文件netcat-flume-logger.conf

a1.sources=r1
a1.channels=c1
a1.sinks=k1

a1.sources.r1.type=netcat
a1.sources.r1.bind=localhost
a1.sources.r1.port=7777

a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=1000

a1.sinks.k1.type=logger
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1

参数解析:

  • source.xxx.type:数据来源类型
  • source.xxx.bind:来源地址
  • source.xxx.port:自定义端口号
  • channels.xxx.type:通道数据中的 event 类型
  • channels.xxx.capacity:通道容量
  • channels.xxx.transactionCapacity:通道的吞吐量
  • sink.xxx.type:sink 存储数据方式
  • source.xxx.channels:连接数据收集端(source)和通道(channels)
  • sink.xxx.channels:连接通道(channels)和数据消费端(sink)

启动 flume 文件命令

flume-ng agent \
--name a1 \
--conf /opt/flume/conf/ \
--conf-file /opt/data/flumedir/confs/netcat-flume-logger.conf \
-Dflume.root.logger=INFO,console
// 可简写成以下格式
flume-ng agent \
-n a1 \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/netcat-flume-logger.conf \
-Dflume.root.logger=INFO,console

参数说明:

  • --name或者-n:进程名字,即上面的 a1
  • --conf-file或者-f:创建的 flume 文件路径,建议使用绝对路径
  • --conf或者-c:Flume 安装目录下配置文件 conf 目录的路径,建议使用绝对路径,可省略
  • Dflume.root.logger=INFO,console:设置日志级别,可省略

启动 netcat 客户端查看结果:

telnet localhost 7777

777为自定义端口号,不固定,也可定义为其他的,例如:5555等
在控制台输入,客户端会同步显示出控制台输入的内容
同样也可以在客户端输入回车后,控制台也可以看到结果
运行结果如下:

flume tail日志文件 flume收集日志的多种方式_hadoop_08

4.2、exec source,logger sink

创建 flume 文件file-flume-logger.conf

a2.sources=r1
a2.channels=c1
a2.sinks=k1

a2.sources.r1.type=exec
a2.sources.r1.command=tail -f /opt/data/flumedir/tmp/a.txt

a2.channels.c1.type=memory
a2.channels.c1.capacity=1000
a2.channels.c1.transactionCapacity=1000

a2.sinks.k1.type=logger
a2.sources.r1.channels=c1
a2.sinks.k1.channel=c1

参数说明:

  • exec:表示单个文件作为数据源
  • source.xxx.command=tail -f path:文件路径

启动 flume 文件命令

flume-ng agent \
-n a2 \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/file-flume-logger.conf \
-Dflume.root.logger=INFO,console

4.3、spooldir source,logger sink

spooldir source 是最常用的数据源

获取指定件夹下所有指定名称的文件;以下示例均使用文件夹作为数据源,仅修改输出方式

创建events-flume-logger.conf

events.sources=eventsSource
events.channels=eventsChannel
events.sinks=eventsSink

events.sources.eventsSource.type=spooldir
events.sources.eventsSource.spoolDir=/opt/data/flumedir/dataSourceFile/events
events.sources.eventsSource.deserializer=LINE
events.sources.eventsSource.deserializer.maxLineLength=10000
events.sources.eventsSource.includePattern=events_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv

events.channels.eventsChannel.type=file
events.channels.eventsChannel.checkpointDir=/opt/data/flumedir/checkPointFile/events
events.channels.eventsChannel.dataDirs=/opt/data/flumedir/dataChannelFile/events

events.sinks.eventsSink.type=logger
events.sources.eventsSource.channels=eventsChannel
events.sinks.eventsSink.channel=eventsChannel

参数说明:

  • spooldir:指定数据源为文件夹下所有指定内容
  • sources.xxx.spoolDir:指定数据来源文件夹路径(启动 agent 前必须存在)
  • source.xxx.deserializer:指定序列化方式(LINE 表示为逐行读取)
  • source.xxx.maxLineLength:指定每行的最大字符数
  • source.xxx.includePattern:指定数据来源文件夹下文件名的类型,正则匹配
  • channels.xxx.type=file:指定通道类型为文件,即通道中的 event 落盘,保证数据安全
  • channels.xxx.checkpointDir:指定通道检查点文件夹目录(绝对路径)
  • channels.xxx.dataDirs:指定通道中数据落盘的文件夹路径(绝对路径)

启动 flume 文件命令

flume-ng agent \
-n events \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/events-flume-logger.conf \
-Dflume.root.logger=INFO,console

注意来源文件夹必须存在,检查点文件夹和通道落盘文件夹可以不存在,启动 flume 时会自动创建
将需要读取的文件拷贝到指定路径下即可输出到 flume 客户端;
flume 获取后的文件夹会改名,在原来名字后面加上后缀.COMPLETED 结果如下:

flume tail日志文件 flume收集日志的多种方式_flume tail日志文件_09

4.4、spooldir source,hdfs sink

从文件夹获取数据,输出方式为上传到 HDFS

创建文件userFriend-flume-hdfs.conf

user_friend.sources=userFriendSource
user_friend.channels=userFriendChannel
user_friend.sinks=userFriendSink

user_friend.sources.userFriendSource.type=spooldir
user_friend.sources.userFriendSource.spoolDir=/opt/data/flumedir/dataSourceFile/test
user_friend.sources.userFriendSource.deserializer=LINE
user_friend.sources.userFriendSource.deserializer.maxLineLength=320000
user_friend.sources.userFriendSource.includePattern=userFriend_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv

user_friend.channels.userFriendChannel.type=file
user_friend.channels.userFriendChannel.checkpointDir=/opt/data/flumedir/checkPointFile/test
user_friend.channels.userFriendChannel.dataDirs=/opt/data/flumedir/dataChannelFile/test

user_friend.sinks.userFriendSink.type=hdfs
user_friend.sinks.userFriendSink.hdfs.fileType=DataStream
user_friend.sinks.userFriendSink.hdfs.filePrefix=userFriend
user_friend.sinks.userFriendSink.hdfs.fileSuffix=.csv
user_friend.sinks.userFriendSink.hdfs.path=hdfs://192.168.8.99:9000/flume/test/%Y-%m-%d
user_friend.sinks.userFriendSink.hdfs.useLocalTimeStamp=true
user_friend.sinks.userFriendSink.hdfs.batchSize=640
user_friend.sinks.userFriendSink.hdfs.rollInterval=20
user_friend.sinks.userFriendSink.hdfs.rollCount=0
user_friend.sinks.userFriendSink.hdfs.rollSize=120000000

user_friend.sources.userFriendSource.channels=userFriendChannel
user_friend.sinks.userFriendSink.channel=userFriendChannel

参数说明:

  • sink.xxx.type=hdfs:指定 sink 存储方式为 HDFS
  • sink.xxx.hdfs.fileType:指定保存到 HDFS 文件系统上的文件类型
  • sink.xxx.hdfs.filePrefix:指定保存到 HDFS 文件系统上的文件名前缀
  • sink.xxx.hdfs.fileSuffix:指定保存到 HDFS 文件系统上的文件名后缀
  • sink.xxx.hdfs.path:指定保存在 HDFS 上的路径
  • sink.xxx.hdfs.useLocalTimeStamp:是否使用本地时间戳,默认为 false 不使用
  • sink.xxx.hdfs.batchSize:批量发送事件数量(发送给 channel 的最大行数)
  • sink.xxx.hdfs.rollInterval:按时间生成 HDFS 文件
  • sink.xxx.hdfs.rollCount:按写入的 event 的个数触发 roll,生成新的 HDFS 文件
  • sink.xxx.hdfs.rollSize:按文件大小触发 roll,生成新的 HDFS 文件

启动 flume 文件命令

flume-ng agent \
-n user_friend \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/userFriend-flume-hdfs.conf \
-Dflume.root.logger=INFO,console

运行结果如下:

flume tail日志文件 flume收集日志的多种方式_linux_10

4.5、获取数据时添加拦截器过滤数据

在获取数据的同时简单过滤一些不需要的数据

创建user-flume-hdfs.conf

users.sources=userSource
users.channels=userChannel
users.sinks=userSink

users.sources.userSource.type=spooldir
users.sources.userSource.spoolDir=/opt/data/flumedir/dataSourceFile/user
users.sources.userSource.includePattern=user_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv
users.sources.userSource.deserializer=LINE
users.sources.userSource.maxLineLength=10000
users.sources.userSource.interceptors=head_filter
users.sources.userSource.interceptors.head_filter.type=regex_filter
users.sources.userSource.interceptors.head_filter.regex=^user_id*
users.sources.userSource.interceptors.head_filter.excludeEvents=true

users.channels.userChannel.type=file
users.channels.userChannel.checkpointDir=/opt/data/flumedir/checkPointFile/user
users.channels.userChannel.dataDirs=/opt/data/flumedir/dataChannelFile/user

users.sinks.userSink.type=hdfs
users.sinks.userSink.hdfs.fileType=DataStream
users.sinks.userSink.hdfs.filePrefix=users
users.sinks.userSink.hdfs.fileSuffix=.csv
users.sinks.userSink.hdfs.path=hdfs://hadoop:9000/flume/test/users/%Y-%m-%d
users.sinks.userSink.hdfs.useLocalTimeStamp=true
users.sinks.userSink.hdfs.batchSize=640
users.sinks.userSink.hdfs.rollCount=0
users.sinks.userSink.hdfs.rollSize=120000000
users.sinks.userSink.hdfs.rollInterval=20

users.sources.userSource.channels=userChannel
users.sinks.userSink.channel=userChannel

参数说明:

  • sources.xxx.interceptors=head_filter:指定拦截器名称
  • sources.xxx.interceptors.head_filter.type=regex_filter:指定拦截器类型
  • sources.xxx.interceptors.head_filter.regex=^user_id*:过滤掉以 user_id 开头的行(常用于过滤第一行)
  • sources.xxx.interceptors.head_filter.excludeEvents=true:正则过滤拦截(false表示过滤掉不是以 user_id 开头的行)

启动 flume 文件命令

flume-ng agent \
-n users \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/user-flume-hdfs.conf \
-Dflume.root.logger=INFO,console

4.6、spooldir source,KafkaSink

创建events-flume-kafka.conf

events.sources=eventsSource
events.channels=eventsChannel
events.sinks=eventsSink

events.sources.eventsSource.type=spooldir
events.sources.eventsSource.spoolDir=/opt/data/flumedir/dataSourceFile/events
events.sources.eventsSource.deserializer=LINE
events.sources.eventsSource.deserializer.maxLineLength=320000
events.sources.eventsSource.includePattern=events_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv
events.sources.eventsSource.interceptors=head_filter
events.sources.eventsSource.interceptors.head_filter.type=regex_filter
events.sources.eventsSource.interceptors.head_filter.regex=^event_id*
events.sources.eventsSource.interceptors.head_filter.excludeEvents=true

events.channels.eventsChannel.type=file
events.channels.eventsChannel.checkpointDir=/opt/data/flumedir/checkPointFile/events
events.channels.eventsChannel.dataDirs=/opt/data/flumedir/dataChannelFile/events

events.sinks.eventsSink.type=org.apache.flume.sink.kafka.KafkaSink
events.sinks.eventsSink.batchSize=640
events.sinks.eventsSink.brokerList=192.168.8.99:9092
events.sinks.eventsSink.topic=events

events.sources.eventsSource.channels=eventsChannel
events.sinks.eventsSink.channel=eventsChannel

创建 Kafka Topic

kafka-topics.sh --create \
--zookeeper 192.168.8.99:2181 \
--partitions 1 \
--replication-factor 1 \
--topic events

启动 flume 文件命令

flume-ng agent \
-n events \
-c /opt/flume/conf/ \
-f /opt/data/flumedir/confs/events-flume-kafka.conf \
-Dflume.root.logger=INFO,console