深入解析Flume:高效日志收集与传输系统的奥秘
[01.Flume概述01.png](https://www.teamczyx.com/newpic/2024091775692/2525284403.png)
Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume 基于流式架构,灵活简单。
Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS。
Flume作用
- 从固定目录下采集日志信息到目的地(HDFS,HBase,Kafka);
- 实时采集日志信息(tAIdir)到目的地;
- 支持级联(多个Flume对接起来),合并数据;
- 支持按照用户定制采集数据。
说明
Flume 使用 java 编写,其需要运行在 java1.6 或更高版本之上。
二、演进过程
Flume 最初是 Cloudera 开发的日志收集系统,受到了业界的认可与广泛应用,后来逐步演化成支持任何流式数据收集的通用系统。
Flume目前存在两个版本:
- Flume OG(Original generation)
- Flume NG (Next/New generation)
其中 Flume OG 对应的是 Apache Flume 0.9.x 之前的版本,早期随着 Flume 功能的扩展,Flume OG 代码工程臃肿、核心组件设计不合理、核心配置不标准等缺点暴露出来,尤其是在 Flume OG 的最后一个发行版本 0.9.4. 中,日志传输不稳定的现象尤为严重。为了解决这些问题,2011 年 10 月 22 号,Cloudera 完成了 Flume-728,对 Flume 进行了里程碑式的改动,重构后的版本统称为 Flume NG(next generation)。同时此次改动后,Flume 也纳入了 apache 旗下。
Flume NG在OG的架构基础上做了调整,去掉了中心化组件 master 以及服务协调组件 Zookeeper,使得架构更加简单和容易部署。Flume NG 和 OG 是完全不兼容的,但沿袭了 OG 中的很多概念,包括Source,Sink等。
三、Flume基础架构
[01.Flume概述02.png](https://www.teamczyx.com/newpic/2024091775700/2003528372.png)
Agent
Flume运行的核心是 Agent。Flume以agent为最小的独立运行单位。一个agent就是一个JVM。它是一个完整的数据收集工具,含有三个核心组件,分别是:source、 channel、 sink。通过这些组件, Event 可以从一个地方流向另一个地方。
Source
source是数据的收集端,负责将数据捕获后进行特殊的格式化,将数据封装到事件(event) 里,然后将事件推入Channel中。
Source直接读取文件方式:
- ExecSource: 以运行 Linux 命令的方式,持续的输出最新的数据,如指令,在这种方式下,取的文件名必须是指定的。
ExecSource 可以实现对日志的实时收集,但是存在Flume不运行或者指令执行出错时,将无法收集到日志数据,无法保证日志数据的完整性。
- SpoolSource:监测配置的目录下新增的文件,并将文件中的数据读取出来。
需要注意两点:拷贝到 spool 目录下的文件不可以再打开编辑;spool 目录下不可包含相应的子目录。
SpoolSource 虽然无法实现实时的收集数据,但是可以使用以分钟的方式分割文件,趋近于实时。
如果应用无法实现以分钟切割日志文件的话, 可以两种收集方式结合使用。 在实际使用的过程中,可以结合 log4j 使用,使用 log4j的时候,将 log4j 的文件分割机制设为1分钟一次,将文件拷贝到spool的监控目录。
log4j 有一个 TimeRolling 的插件,可以把 log4j 分割文件到 spool 目录。基本实现了实时的监控。Flume 在传完文件之后,将会修改文件的后缀,变为 .COMPLETED(后缀也可以在配置文件中灵活指定)。
Flume Source 支持的类型:
Source类型 |
说明 |
avro source |
支持Avro协议(实际上是Avro RPC),内置支持 |
thrift source |
支持Thrift协议,内置支持 |
exec source |
基于Unix的command在标准输出上生产数据 |
jms source |
从JMS系统(消息、主题)中读取数据,ActiveMQ已经测试过 |
spooling directory source |
监控指定目录内数据变更 |
twitter 1% firehose source |
通过API持续下载Twitter数据,试验性质 |
netcat source |
监控某个端口,将流经端口的每一个文本行数据作为Event输入 |
sequence generator source |
序列生成器数据源,生产序列数据 |
syslog source |
读取syslog数据,产生Event,支持UDP和TCP两种协议 |
http source |
基于HTTP POST或GET方式的数据源,支持JSON、BLOB表示形式 |
legacy source |
兼容老的Flume OG中Source(0.9.x版本) |
kafka source |
从kafka中获取数据 |
Sink
Sink不断地轮询Channel中的事件,并将这些事件批量写入到存储或索引系统、或者被发送到另一个Flume Agent。
Sink在设置存储数据时,可以向文件系统、数据库、hadoop存数据,在日志数据较少时,可以将数据存储在文件系中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。
Flume Sink支持的类型:
Sink类型 |
说明 |
HDFS Sink |
数据写入HDFS |
Logger Sink |
数据写入日志文件 |
Avro Sink |
数据被转换成Avro Event,然后发送到配置的RPC端口上 |
Thrift Sink |
数据被转换成Thrift Event,然后发送到配置的RPC端口上 |
IRC Sink |
数据在IRC上进行回放 |
File Roll Sink |
存储数据到本地文件系统 |
Null Sink |
丢弃到所有数据 |
HBase Sink |
数据写入HBase数据库 |
Morphline Solr Sink |
数据发送到Solr搜索服务器(集群) |
ElasticSearch Sink |
数据发送到Elastic Search搜索服务器(集群) |
Kite Dataset Sink |
写数据到Kite Dataset,试验性质的 |
Custom Sink |
自定义Sink实现 |
channel
Channel 是位于 Source 和 Sink 之间的缓冲区。因此,Channel 允许 Source 和 Sink 运作在不同的速率上。Channel 是线程安全的,可以同时处理几个 Source 的写入操作和几个Sink 的读取操作。当Sink成功地将events发送到下一跳的channel或最终目的端,events从Channel移除。
不同的Channel提供的持久化水平也是不一样的:
- Memory Channel:不会持久化。消息存放在内存中,提供高吞吐,但不提供可靠性;可能丢失数据。
- File Channel:对数据持久化;基于WAL(预写式日志Write-Ahaad Log)实现。但是配置较为麻烦,需要配置数据目录和checkpoint目录;不同的file channel均需要配置一个checkpoint目录。
- JDBC Channel:基于嵌入式Database实现。内置derby数据库,对event进行了持久化,提供高可靠性;可以取代同样持久特性的file channel。
Channels支持事物,提供较弱的顺序保证,可以连接任何数量的Source和Sink。
Event
传输单元,Flume 数据传输的基本单元,以 Event 的形式将数据从源头送至目的地。
Event 由 Header 和 Body 两部分组成,Header 用来存放该 event 的一些属性,为 K-V 结构,Body 用来存放该条数据,形式为字节数组。
[01.Flume概述03.png](https://www.teamczyx.com/newpic/2024091775701/3188894094.png)
四、可靠性
Flume 的核心是把数据从数据源收集过来,再送到目的地。为了保证输送一定成功,在送到目的地之前,会先缓存数据,待数据真正到达目的地后,删除自己缓存的数据。
Flume 使用事务性的方式保证传送Event整个过程的可靠性。Sink 必须在 Event 被存入 Channel 后,或者,已经被传达到下一站agent里,又或者,已经被存入外部数据目的地之后,才能把 Event 从 Channel 中 remove 掉。这样数据流里的 event 无论是在一个 agent 里还是多个 agent 之间流转,都能保证可靠,因为以上的事务保证了 event 会被成功存储起来。而 Channel 的多种实现在可恢复性上有不同的保证。也保证了 event 不同程度的可靠性。比如 Flume 支持在本地保存一份文件 channel 作为备份,而memory channel 将 event 存在内存 queue 里,速度快,但丢失的话无法恢复。
|