一篇文章搞懂 Flume 的架构设计

827 阅读5分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

正文

  • Flume 的核心是把数据从数据源收集过来,再送到目的地。为了保证输送一定成功,在送到目的地之前,会先缓存数据,待数据真正到达目的地后,删除自己缓存的数据。

  • Flume分布式系统中最核心的角色是agent,flume采集系统就是由一个个agent所连接起来形成。

一个 Agent 可从客户端或前一个 Agent 接收数据,经过过滤(可选)、路由等操作后,传递给下一个或多个 Agent (完全分布式),直到抵达指定的目标系统。

用户可根据需要拼接任意多个 Agent 构成一个数据流水线。

Flume 将数据流水线中传递的数据称为Event,每个 Event 由头部和字节数组(数据内容)两部分构成。

其中,头部由一系列 key / value 对构成,可用于数据路由,字节数组封装了实际要传递的数据内容,

通常使用 Avro,Thrift,Protobuf 等对象序列化而成。

Flume 中 Event 可由专门的客户端程序产生,这些客户端程序将要发送的数据封装成 Event 对象, 并调用 Flume 提供的 SDK 发送给 Agent

接下来重点讲解 Agent 内部的组件构成,如图所示。

在这里插入图片描述

Agent 内部主要由三个组件构成,分别是 Source, Channel 和 Sink ,其作用和功能如下。

1 . Source

采集组件,用于跟数据源对接,以获取数据

Flume 数据流中接收 Event 的组件,通常从 Client 程序或上一个 Agent 接收数据,并写入一个或多个 Channel 。

为了方便用户使用, Flume 提供了很多 Source 实现,主要包括:

Avro Source

内置 AvroServer ,可接收 Avro 客户端发送的数据,并写入 Channel

Thrift Source

内置 ThriftServer ,可接收 Thrift 客户端发送的数据,并写入 Channel

Exec Source

执行指定的 shell ,并从该命令的标准输出中获取数据,写入 Channel 如“ tail -F 文件名”命令,

ExecSource 可实现对数据的实时收集,但考虑到该 Flume Agent 不运行或者指令执行出错时,将无法收集到日志数据,无法保证日志数据的完整性,因而在实际生产环境中很少被采用。

Spooling Directory Source

该 Source 可监控指定目录池下文件的变化,一旦发现有新的文件,会将之写入 Channel ,在使用该 Source 时,需要注意两点:

拷贝到监控目录下的文件不可以再修改;目录下不可包含子目录

使用该 Source 时,通常会指定一个目录作为监控目录,当需要传输数据时,将文件拷贝到该目录下,实现近似实时传输。

由于该 Source 可靠性和稳定性较好,被不少公司采用。

Kafka Source

内置 Kafka Consumer ,可从 Kafka Broker 中读取某个 topic 的数据,写入 Channel。

Syslog Source

分为 Syslog TCP Source 和 Syslog UDP Source 两种,分别可以接收 TCP 和 UDP 协议发过来的数据,并写入 Channel

HTTP Source

可接收 HTTP 协议发来的数据,并写入 Channel 当然,用户也可以根据自己的需要定制 Source 。

如何选择 Flume Source?

在实际生产环境中,存在两种数据源,一种是文件,可采用 ExecSource 或 Spooling Directory Source 收集数据,但考虑到前者无法保证数据完整性,后者实时性较差,通常会自己进行定制,既保证完整性,又具备较高的实时性。

taildirsource 便是一个非常优秀的解决方案,它能实时监控一个目录下文件的变化,实时读取新增数据,并记录断点,保证重启 Agent 后数据不丢失或被重复传输;

另一种是网络数据,这时候可采用 Avro / Thrift source ,并自己编写客户端程序传输数据给该 source 。

2. Channel

传输通道组件,缓存数据,用于从source将数据传递到sink

Channel 是一个缓存区,它暂存 Source 写入的 Event ,直到被 Sink 发送出去。

目前 Fume 主要提供了以下几种 Channel 实现

Memory Channel

在内存队列中缓存 Event 。

该 Channel 具有非常高的性能(指 Source 写入和 Sink 读取性能),但一旦断电,内存中数据会丢失,另外,内存不足时,可能导致 Agent ,崩溃。

File Channel

在磁盘文件中缓存 Event 。

该 Channel 弥补了 MemoryChannel 的不足,但性能会有一定的下降。

JDBC Channel

支持 JDBC 驱动,进而可将 Event 写入数据库中。

该 Channel 适用于对故障恢复要求非常高的场景。

Kafka Channel

在 Kafka 中缓存 Event 。

Kafka 提供了高容错性和扩展性,允许可靠地缓存更多数据,这为其他 Sink 重复读取 Channel 中的数据提供了可能(比如发现统计结果有误,重新收集 1 天前的数据进行处理)。

3. Sink

下沉组件,数据发送给最终存储系统或者下一级agent中

sink 负责从 Channel 中读取数据,并发送给下一个 Agent (的 Source )。

Flume 主要提供了以下几种 Sink 实现

HDFS Sink

这是最常用的一种 Sink ,负责将 Channel 中的数据写入 HDFS ,用户可根据时间或者数据量,决定何时交替形成一个新的文件。

HBase Sink

可将 Channel 中的数据写入 HBase ,支持同步和异步两种写人方式。

Avro / Thrift Sink

内置了 Avro / Thrift 客户端,可将 Event 数据通过 Avro / Thrift RPC 发送给指定的 Avro / Thrift Server

MorphlineSolr Sink / ElasticSearch Sink

将 Channel 中的 Event 数据写入 Solr / ElasticSearch 搜索引擎,在一些场景下,用户需要同时对数据进行离线分析和在线搜索,可同时使用 HDFS Sink 和该 Sink 将数据同时写入 HDFS 和搜索引擎。

Kafka Sink

将 Channel 中的数据写入 Kafka 中。

Flume 使用事务性的方式保证 Event 传递的可靠性。

Sink 必须在 Event 被存入 Channel 后,或者已经被成功传递给下一个 Agent 后,才能把 Event 从 Channel 中删除掉。

这样数据流里的 Event 无论是在一个 Agent 里还是多个 Agent 之间流转,都能保证可靠。

采集系统结构图

简单结构

  • 单个agent采集数据

在这里插入图片描述

复杂结构

  • 2个agent串联

在这里插入图片描述

  • 多个agent串联

在这里插入图片描述

  • 多个channel

在这里插入图片描述