0%

flume简介

Flume 到底是个啥?一文讲透这个日志采集工具

做数据平台,第一步就是日志采集。要是数据都进不来,后面再牛的架构都是白搭。

Flume 是 Apache 旗下的分布式日志采集工具,主打高可用、高可靠、易扩展。说白了,就是帮你在海量日志场景下,把数据从 A 点搬到 B 点,还不丢数据。

这篇文章我按自己的理解,把 Flume 的核心概念、组件架构捋一遍,尽量讲清楚它到底怎么工作的。本文基于 Flume 1.9.0(可通过官网或包管理工具安装,安装后需在 flume-env.sh 中配置 JAVA_HOME)。

1
2
3
4
5
6
>flume-ng version 
Flume 1.9.0
Source code repository: https://git-wip-us.apache.org/repos/asf/flume.git
Revision: d4fcab4f501d41597bc616921329a4339f73585e
Compiled by fszabo on Mon Dec 17 20:45:25 CET 2018
From source with checksum 35db629a3bda49d23e9b3690c80737f9

先说清楚它到底干啥的

Flume 的核心就一件事:从数据源采数据,传给存储系统。比如你的应用服务器每天产生几十个 GB 的日志,你想把这些日志弄到 HDFS 或 Kafka 里,Flume 就是干这个的。

它的优势,我用自己的话说:

  • 高可用:节点挂了能自动恢复,不至于整个采集链路瘫痪

  • 高可靠:通过持久化机制保证数据不丢,这个后面会细说

  • 分布式:可以横向扩展,日志量大了就加机器

  • 灵活:支持自定义数据源、传输逻辑和存储目标,大部分场景都能覆盖

Flume 的核心架构:一个 Agent 三个组件

Flume 的最小工作单元叫 Agent(代理)。一个 Agent 由三个组件构成:Source(数据源)、Channel(通道)、Sink(接收器)

多个 Agent 可以串起来,形成一条数据流 pipeline,实现跨节点的数据传输。比如:A 服务器采集 → 发给 B 服务器聚合 → 再发给 C 服务器写入 HDFS。

flume

工作流程就三步:

  1. Source 从数据源(如日志文件、Kafka、网络端口)采集数据,封装为 Event(事件) 发给 Channel;
  2. Channel 是个临时缓冲区,把 Event 先存起来,等 Sink 来取,确保数据不丢失;
  3. Sink 从 Channel 里取 Event,写到目标存储系统(如 HDFS、Kafka)或下一个 Agent 的 Source。

几个必须搞懂的核心概念

事件Event

Event 是 Flume 里数据传输的最小单位,你可以把它理解成一个快递包裹。每个 Event 包含两部分:

  • Header:键值对形式的元信息,比如时间戳、数据来源,用于后续的路由和过滤
  • Body:真正的业务数据,是字节数组格式,比如一条日志的文本内容

举个例子,一条用户行为日志到了 Flume 里,长这样:

1
2
Header: {timestamp=1620000000000, source=app-log}  
Body: "user_id=123;action=click;page=home"(字节数组形式)

事件源Source

Source 是数据流入 Flume 的 “入口”,负责从数据源采集数据并转换为 Event 发送到 Channel。Flume 支持丰富的内置 Source,覆盖大多数常见场景:

常用 Source 类型
类型 适用场景 示例配置场景
spooldir 监控目录下的新增文件(如日志文件) 采集应用服务器的本地日志文件
netcat 监听网络端口接收数据 实时接收网络设备推送的日志
kafka 从 Kafka 主题消费数据 对接 Kafka 进行数据中转
exec 执行命令并采集输出(如 tail -F 实时跟踪日志文件新增内容
http 通过 HTTP 请求接收数据 接收应用程序主动上报的事件
特点与扩展
  • 支持多 Channel 输出:一个 Source 可将 Event 发送到多个 Channel(通过 Channel Selector 控制);
  • 可自定义 Source:若内置类型不满足需求,可通过实现 org.apache.flume.Source 接口开发自定义 Source。

source类型

通道Channel

Channel 是 Flume 可靠性的核心。Source 把数据放进去,Sink 再从里面取,Channel 在中间暂存,确保数据不丢。

常用 Channel 类型

类型 存储方式 可靠性 性能 适用场景
Memory Channel 内存 低(易丢失) 非核心数据、对性能要求高的场景
File Channel 本地磁盘 高(持久化) 核心数据、需保证不丢失的场景
JDBC Channel 关系型数据库 需事务支持或跨节点共享数据的场景

Channel Selector(通道选择器)

当一个 Source 对接多个 Channel 时,Selector 决定 Event 发到哪些 Channel。有两种策略:

  • Replicating(默认):复制一份发到所有 Channel,相当于广播
  • Multiplexing:根据 Event Header 里的某个字段值,路由到不同的 Channel

示例配置(Multiplexing)

1
2
3
4
5
6
7
8
9
10
11
12
a1.sources = r1
# 多个channel
a1.channels = c1 c2 c3 c4
a1.sources.r1.selector.type = multiplexing
# 根据 Header 中的 "state" 属性路由
a1.sources.r1.selector.header = state
# state=CZ → 发送到 c1
a1.sources.r1.selector.mapping.CZ = c1
# state=US → 发送到 c2 和 c3
a1.sources.r1.selector.mapping.US = c2 c3
# 无匹配时默认发送到 c4
a1.sources.r1.selector.default = c4

通道类型

接收器Sink

Sink 是数据流出 Flume 的 “出口”,负责从 Channel 读取 Event 并传输到目标存储系统或下一个 Agent。同样,Flume 内置了多种选择:

常用 Sink 类型
类型 目标存储 适用场景
hdfs HDFS 文件系统 海量日志数据持久化存储
kafka 写入 Kafka 主题 对接 Kafka 供下游消费
logger 输出到 Flume 日志(控制台) 调试或临时数据查看
file_roll 写入本地文件 小规模数据本地存储
hbase 写入 HBase 表 需随机读写或实时查询的场景
avro 发送到另一个 Flume Agent 的 Source 跨节点数据传输(多级 Agent 串联)
Sink Group(接收器组)

如果你想提高写入吞吐量,可以把多个 Sink 组成一个组,用轮询或故障转移策略分配任务。比如配三个 hdfs Sink 并行写 HDFS,写入速度翻倍:

  • 支持 round_robin(轮询)或 failover(故障转移)策略;
  • 示例:多个 hdfs Sink 组成 Group,并行写入 HDFS 提升效率。

sink类型

Flume 的灵活性与扩展能力

Flume 的强大不仅在于内置组件,更在于其可扩展性:

  • 拦截器(Interceptor):在 Event 从 Source 到 Channel 之前,你可以加一道”加工工序”。常见的用法是:给每条日志加一个时间戳、过滤掉无效日志、或者从 Body 里提取某个字段放到 Header 里做路由;
  • 序列化器(Serializer):自定义 Event 写入目标系统的格式(如将 Body 转换为 JSON 或 Parquet 格式);
  • 自定义组件:通过接口开发自定义 Source、Channel、Sink,适配特殊业务场景。

欢迎关注我的其它发布渠道