官方网站http://flume.apache.org/
用户文档http://flume.apache.org/FlumeUserGuide.html
开发文档http://flume.apache.org/FlumeDeveloperGuide.html

一、数据流架构

Flume 传输的数据的基本单位是 Event,如果是文本文件,通常是一行记录,这也是事务的基本单位。Event 从 Source流向Channel,再到 Sink,本身为一个 byte 数组,并可携带 headers 信息。Event 代表着一个数据流的最小完整单元,从外部数据源来,向外部的目的地去。Flume 运行的核心是 Agent。它是一个完整的数据收集工具,含有三个核心组件,分别是 source、channel、sink。通过这些组件,Event 可以从一个地方流向另一个地方

source 接收外部源发送过来的数据。不同的 source,可以接受不同的数据格式。比如有目录池(spooling directory)数据源,可以监控指定文件夹中的新文件变化,如果目录中有文件产生,就会立刻读取其内容。

channel 是一个存储地,接收 source 的输出,直到有 sink 消费掉 channel 中的数据。channel 中的数据直到进入到下一个channel 中或者进入终端才会被删除。当 sink 写入失败后,可以自动重启,不会造成数据丢失,因此很可靠。

sink 会消费 channel 中的数据,然后送给外部源或者其他source。如数据可以写入到 HDFS 或者 HBase 中。flume 允许多个 agent 连在一起,形成前后相连的多级跳。

二、核心组件

source

Client端做为消费数据的来源,Flume 支持 Avrolog4jsysloghttp post(body 为 json 格式)。可以让应用程序同已有的Source直接互通,如 AvroSourceSyslogTcpSource。也可以自定义一个Source,以 IPC(进程间通信协议) 或 RPC(远程进程间通信协议) 的方式 接入, Avro Thrift 都可以(分别有NettyAvroRpcClient ThriftRpcClient 实现了RpcClient 接口),其中 Avro是默认的 RPC协议。具体代码级别的Client端数据接入,可以参考官方手册。对现有程序改动最小的使用方式是直接读取程序原来记录的日志文件,基本可以实现无缝接入,不需要对现有程序进行任何改动。 对于直接读取文件Source,有两种方式:

ExecSource:以运行 Linux 命令的方式,持续的输出最新的数据,如 tail -F 文件名 指令,在这种方式下,取的文件名必须是指定的。 ExecSource:可以实现对日志的实时收集,但是存在 Flume 不运行或者指令执行出错时,将无法收集到日志数据,无法保证日志数 据的完整性。

SpoolSource: 监测配置的目录下新增的文件,并将文件中的数据读取出来。需要注意两点:拷贝到 spool 目录下的文件不可以再打开编辑;spool 目录下不可包含相应的子目录。SpoolSource 虽然无法实现实时的收集数据,但是可以使用以分钟的方式分割文件,趋近于实时。如果应用无法实现以分钟切割日志文件的话,可以两种收集方式结合使用。 在实际使用的过程中,可以结合 log4j 使用,使用log4j 的时候,将 log4j 的文件分割机制设为1分钟一次,将文件拷贝到 spool 的监控目录。log4j 有一个 TimeRolling 的插件,可以把 log4j 分割文件到 spool 目录。基本实现了实时的监控。Flume 在传完文件之后,将会修改文件的后缀,变为 .COMPLETED(后缀也可以在配置文件中灵活指定)。

Channel

当前有几个 channel 可供选择,分别是 Memory Channel, JDBCChannel , File ChannelPsuedo Transaction Channel。比较常见的是前三种 channel。

MemoryChannel 可以实现高速的吞吐,但是无法保证数据的完整性。

MemoryRecoverChannel 在官方文档的建议上已经建义使用FileChannel来替换。

FileChannel 保证数据的完整性一致性 。在具体配置FileChannel时,建议FileChannel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率。File Channel 是一个持久化的隧道(channel),它持久化所有的事件,并将其存储到磁盘中。因此,即使 Java 虚拟机当掉,或者操作系统崩溃或重启,再或者事件没有在管道中成功地传递到下一个代理(agent),这一切都不会造成数据丢失。Memory Channel 是一个不稳定的隧道,其原因是由于它在内存中存储所有事件。如果 java进程死掉,任何存储在内存的事件将会丢失。另外,内存的空间收到RAM大小的限制,而File Channel这方面是它的优势,只要磁盘空间足够,它就可以将所有事件数据存储到磁盘上。

sink

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

三、核心概念

序号

对象

描述

1

Client

Client生产数据,运行在一个独立的线程

2

Event

一个数据单元,消息头和消息体组成。(Events可以是日志记录、 avro 对象等。)

3

Flow

Event从源点到达目的点的迁移的抽象

4

Agent

一个独立的Flume进程,包含组件Source、 Channel、 Sink。(Agent使用JVM 运行Flume。每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks。)

5

Source

数据收集组件。(source从Client收集数据,传递给Channel)

6

Channel

中转Event的一个临时存储,保存由Source组件传递过来的Event。(Channel连接 sources 和 sinks ,这个有点像一个队列。)

7

Sink

从Channel中读取并移除Event, 将Event传递到FlowPipeline中的下一个Agent(如果有的话)(Sink从Channel收集数据,运行在一个独立线程。)

四、Flume特点

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

flume的数据流由事件(Event)贯穿始终。事件是Flume的基本数据单位,它携带日志数据(字节数组形式)并且携带有头信息,这些Event由Agent外部的Source生成,当Source捕获事件后会进行特定的格式化,然后Source会把事件推入(单个或多个)Channel中。你可以把Channel看作是一个缓冲区,它将保存事件直到Sink处理完该事件。Sink负责持久化日志或者把事件推向另一个Source。

1.flume的可靠性 
当节点出现故障时,日志能够被传送到其他节点上而不会丢失。

Flume提供了三种级别的可靠性保障,从强到弱依次分别为:

end to end:收到数据agent首先将event写到磁盘上,当数据传送成功后,再删除,如果数据发送失败,可以重新发送。

Store on failure:这也是scribe采用的策略,当数据接收方crash时,将数据写到本地,待恢复后,继续发送

Besteffort:数据发送到接收方后,不会进行确认

2.flume的可恢复性

还是靠Channel。推荐使用FileChannel,事件持久化在本地文件系统里(性能较差)。

五、Flume适用模型

1.单一流程

2.多代理流程(多个agent顺序连接)

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

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

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

4.多路复用流(多级流)

Flume还支持多级流,什么多级流?

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

5.load balance

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