Flume

  • 一、Flume基础架构
  • 1.Agent
  • 2.Source
  • 3.Sink
  • 4.Channel
  • 5.Event
  • 二、配置文件解析
  • 三、启动指令解析
  • 1.启动flume方法
  • 2.指令参数说明
  • 四、Flume进阶
  • 1.Source 类型
  • 1.inode
  • 2.Taildir Source
  • 3.Spooling Directory Source
  • 2.Flume事务
  • 五、Flume Agent内部原理
  • 六、Flume 拓补结构
  • 1.简短串联
  • 2.复制和多路复用
  • 3.负载均衡和故障转移
  • 4.聚合
  • 七、自定义组件
  • 1.Interceptor
  • 2.Source
  • 3.Sink



Flume 是 Cloudera 提供(贡献给apache)的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传


输的系统。Flume 基于流式架构,灵活简单。Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS。

一、Flume基础架构

Flume 组成架构如下图所示。

flume的jmx监控接口获取 flume监控工具_flume的jmx监控接口获取

1.Agent

Agent 是一个 JVM 进程,它以事件的形式将数据从源头送至目的。
Agent 主要有 3 个部分组成,Source、Channel、Sink

2.Source

Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种
格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、taildir、
sequence generator、syslog、http、legacy。

3.Sink

Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个 Flume Agent。
Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、HBase、solr、自定义

4.Channel

Channel 是位于 Source 和 Sink 之间的缓冲区。
因此,Channel 允许 Source 和 Sink 运作在不同的速率上。Channel 是线程安全的,可以同时处理几个 Source 的写入操作和几个Sink 的读取操作。
Flume 自带两种 Channel:Memory Channel 和 File Channel。

Memory Channel 是内存中的队列。Memory Channel 在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么 Memory Channel 就不应该使用,因为程序死亡、机器宕机或者重启都会导致数据丢失。

File Channel 将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。

5.Event

传输单元,Flume 数据传输的基本单元,以 Event 的形式将数据从源头送至目的地。
Event 由 Header 和 Body 两部分组成,Header 用来存放该 event 的一些属性,为 K-V 结构,
Body 用来存放该条数据,形式为字节数组

flume的jmx监控接口获取 flume监控工具_大数据_02

二、配置文件解析

下图为使用netcat向端口44444发送信息,使用flume监听的配置文件。

flume的jmx监控接口获取 flume监控工具_Source_03

Tip:在 Flume 中,Event 的 Header 中存储的时间戳是事件进入 Flume 的时间,也就是事件被 Flume Agent 接收的时间。这个时间戳是 Flume Agent 接收事件的时间,而不是该事件发生的时间。

实际生产中,如果sink端使用了根据timestample的动态写入,通常需要编写flume的interceptor拦截器,将Header中的事件改为body中事件的发生时间。

三、启动指令解析

1.启动flume方法

第一种方法:

[root@hadoop102 flume]$ bin/flume-ng agent --conf conf/ --name a1 -conf-file 
job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console

第二种方法:

[root@hadoop102 flume]$ bin/flume-ng agent -c conf/ -n a1 
-f job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console

2.指令参数说明

参数(/两边参数都能使用)

说明

–conf/-c

表示配置文件存储在 conf/目录

–name/-n

表示给 agent 起名为 a1

–conf-file/-f

flume 本次启动读取的配置文件是在 job 文件夹下的 flume-telnet.conf文件

-Dflume.root.logger=INFO,console

-D 表示 flume 运行时动态修改 flume.root.logger参数属性值,并将控制台日志打印级别设置为 INFO 级别。日志级别包括:log、info、warn、error

四、Flume进阶

1.Source 类型

Exec source 适用于监控一个实时追加的文件,不能实现断点续传
Spooldir Source适合用于同步新文件,但不适合对实时追加日志的文件进行监听并同步;
Taildir Source适合用于监听多个实时追加的文件(监控目录),并且能够实现断点续传

注:Linux 中储存文件元数据的区域就叫做 inode,每个 inode 都有一个号码,操作系统用 inode 号码来识别不同的文件,
Unix/Linux 系统内部不使用文件名,而使用 inode 号码来识别文件。

1.inode

文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。

文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。

每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

inode包含文件的元信息,具体来说,
  * 文件的字节数
  * 文件拥有者的User ID
  * 文件的Group ID
  * 文件的读、写、执行权限
  * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  * 链接数,即有多少文件名指向这个inode
  * 文件数据block的位置

2.Taildir Source

Taildir Source类型的Source通过查看文件position File中的文件信息,判断文件是否发生变动,能够通过pos字段实现文件断点续传,通过if(inode||file)这两项指标的值检查文件,这在一些以日期命名的日志文件中存在一些问题。

Taildir Source 维护了一个 json 格式的 position File,其会定期的往 position File
中更新每个文件读取到的最新的位置,因此能够实现断点续传。Position File 的格式如下:
{“inode”:2496272,“pos”:12,“file”:“/opt/module/flume/files/file1.txt”}
{“inode”:2496275,“pos”:12,“file”:“/opt/module/flume/files/file2.txt”}
比如hive日志中每一天都会新生成一个hive.log,而前一天的hive.log会加上日期后缀,文件名会更改,这样导致flume重新采集上传,出现冗余

flume的jmx监控接口获取 flume监控工具_hadoop_04


如果采用只监控hive.log,不管后缀,不会有更名影响产生冗余,但是

inode肯定会变化,如果前一天晚上任务挂点,到了第二天看到,那么任务挂掉这段期间的数据就丢失了,因为每天新生成一个hive.log被监控,前一天的会更名,数据不会被采集了,导致数据丢失。这样一来就无法发挥出taildir断点续传的优点。

此时可以更改flume源码将只判断inode一个指标便能解决以上问题。

3.Spooling Directory Source

Spooling Directory Source将被监控上传过的文件打上.COMPLETED标签实现监听新文件,在使用 Spooling Directory Source 时,不要在监控目录中创建并持续修改文件;上传完成的文件会以.COMPLETED 结尾;被监控文件夹每 500 毫秒扫描一次文件变动。

2.Flume事务

flume的jmx监控接口获取 flume监控工具_hadoop_05

五、Flume Agent内部原理

flume的jmx监控接口获取 flume监控工具_Source_06


1)ChannelSelector

ChannelSelector 的作用就是选出 Event 将要被发往哪个 Channel。其共有两种类型,分别是 Replicating(复制)和 Multiplexing(多路复用)。

ReplicatingSelector 会将同一个 Event 发往所有的 Channel,Multiplexing 会根据相应的原则,将不同的 Event 发往不同的 Channel。

2)SinkProcessor

SinkProcessor 共 有 三 种 类 型 , 分 别 是 DefaultSinkProcessor 、LoadBalancingSinkProcessor 和 FailoverSinkProcessor

DefaultSinkProcessor 对 应 的 是 单 个 的 Sink , LoadBalancingSinkProcessor FailoverSinkProcessor 对应的是 Sink Group,LoadBalancingSinkProcessor 可以实现负载均衡的功能,FailoverSinkProcessor 可以错误恢复的功能。

六、Flume 拓补结构

1.简短串联

flume的jmx监控接口获取 flume监控工具_大数据_07


这种模式是将多个 flume 顺序连接起来了,从最初的 source 开始到最终 sink 传送的目的存储系统。此模式不建议桥接过多的 flume 数量, flume 数量过多不仅会影响传输速率,而且一旦传输过程中某个节点 flume 宕机,会影响整个传输系统。(适合轻量级RPC)

2.复制和多路复用

flume的jmx监控接口获取 flume监控工具_Source_08


Flume 支持将事件流向一个或者多个目的地。这种模式可以将相同数据复制到多个channel 中,或者将不同数据分发到不同的 channel 中,sink 可以选择传送到不同的目的地(不推荐用Flume该结构,可使用kafka)

3.负载均衡和故障转移

flume的jmx监控接口获取 flume监控工具_hadoop_09


Flume支持使用将多个sink逻辑上分到一个sink组,sink组配合不同的SinkProcessor

可以实现负载均衡和错误恢复的功能。

4.聚合

flume的jmx监控接口获取 flume监控工具_大数据_10


这种模式是我们最常见的,也非常实用,日常 web 应用通常分布在上百个服务器,大者甚至上千个、上万个服务器。产生的日志,处理起来也非常麻烦。用 flume 的这种组合方式能很好的解决这一问题,每台服务器部署一个 flume 采集日志,传送到一个集中收集日志的flume,再由此 flume 上传到 hdfs、hive、hbase 等,进行日志分析。

七、自定义组件

1.Interceptor

在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。此时会用到 Flume 拓扑结构中的 Multiplexing 结构,Multiplexing的原理是,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel中,所以我们需要自定义一个 Interceptor,为不同类型的 event 的 Header 中的 key 赋予不同的值。

a1.sources = r1
a1.channels = c1 c2 c3 c4
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = state 
a1.sources.r1.selector.mapping.CZ = c1
a1.sources.r1.selector.mapping.US = c2 c3
a1.sources.r1.selector.default = c4
a1.sources.r1.interceptors = i1 i2
a1.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.HostInterceptor$Builder
a1.sources.r1.interceptors.i1.preserveExisting = false
a1.sources.r1.interceptors.i1.hostHeader = hostname
a1.sources.r1.interceptors.i2.type = org.apache.flume.interceptor.TimestampInterceptor$Builder

消息体Header中的Map<key,value>中的key为上边的state,value为CZ和US;
根据消息体中的Key决定发送到哪个resource,根据value决定发送到哪个channel;
a1.sources.r1.interceptors = i1 i2
a1.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.HostInterceptor$Builder
指定拦截器i1和i2,并通过全类名绑定,拦截器需要写jar包并构造builder方法

2.Source

Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种
格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、sequence
generator、syslog、http、legacy。官方提供的 source 类型已经很多,但是有时候并不能
满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些 source。

官方也提供了自定义 source 的接口:
https://flume.apache.org/FlumeDeveloperGuide.html#source 根据官方说明自定义
MySource 需要继承 AbstractSource 类并实现 Configurable 和 PollableSource 接口。

3.Sink

Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储
或索引系统、或者被发送到另一个 Flume Agent。
Sink 是完全事务性的。在从 Channel 批量删除数据之前,每个 Sink 用 Channel 启动一个事务。批量事件一旦成功写出到存储系统或下一个 Flume Agent,Sink 就利用 Channel 提交事务。事务一旦被提交,该 Channel 从自己的内部缓冲区删除事件。
Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、null、HBase、solr、自定义。官方提供的 Sink 类型已经很多,但是有时候并不能满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些 Sink。

官方也提供了自定义 sink 的接口:
https://flume.apache.org/FlumeDeveloperGuide.html#sink 根据官方说明自定义
MySink 需要继承 AbstractSink 类并实现 Configurable 接口。