0%

接收处理器

Flume Sink 挂了怎么办?接收处理器帮你兜底

Flume 跑在生产上,最怕两件事:Sink 挂了数据发不出去,和单个 Sink 扛不住流量积压

前几篇文章里,每个 Agent 都只配了一个 Sink。单点跑的没问题,但线上环境谁敢用单点?Sink 指向的 Kafka 集群抖动、HDFS 做安全模式、网络闪断,随便一个就能让采集链路瘫痪。

Flume 的 Sink Group + 接收处理器(Processor) 就是干这个的。这篇文章我讲清楚两种处理器怎么配、什么场景用哪个,以及我实际用下来的一些判断。

先搞清楚处理器是干什么的

一个 Agent 可以有多个 Sink,多个 Sink 组成一个 Sink Group。处理器(Processor)管的是:数据来了,往哪个 Sink 发?

Flume 官方提供三种接收处理器:

处理器类型 核心功能 适用场景
DefaultSinkProcessor 单 Sink 处理(不支持组) 简单场景,无需冗余或负载均衡
FailoverSinkProcessor 故障转移(按优先级切换)主 Sink 挂了切到备 Sink 需要高可用性的关键链路
LoadBalancingSinkProcessor 负载均衡(轮询或随机)多个 Sink 分摊流量 需要提升吞吐量的高并发场景

默认情况下,你只配了一个 Sink,用的就是 DefaultSinkProcessor,没冗余也没扩展。

故障转移(Failover)配置与原理

这个场景我遇到过:Kafka 集群要做滚动重启,每次重启一个 Broker,期间部分分区不可用。如果 Flume 只连一个 Kafka 集群,重启期间数据就发不出去。

用 Failover 可以配两个 Kafka Sink,指向不同的 Kafka 集群,主集群挂了自动切到备集群。

核心配置示例

以下配置实现两个 Kafka Sink 的故障转移,优先级高的 Sink 优先处理数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 定义 Sink Group(包含两个 Sink)  
agent1.sinkgroups = g1
agent1.sinkgroups.g1.sinks = kafkaSink1 kafkaSink2

# 2. 配置故障转移处理器
agent1.sinkgroups.g1.processor.type = failover
# 配置优先级(数值越大优先级越高)
agent1.sinkgroups.g1.processor.priority.kafkaSink1 = 10 # 高优先级
agent1.sinkgroups.g1.processor.priority.kafkaSink2 = 5 # 低优先级
# 故障 Sink 的惩罚时间(毫秒):暂时“隔离”故障 Sink 的时间
agent1.sinkgroups.g1.processor.maxpenalty = 30000

# 3. 配置第一个 Kafka Sink(高优先级)
agent1.sinks.kafkaSink1.type = org.apache.flume.sink.kafka.KafkaSink
agent1.sinks.kafkaSink1.kafka.bootstrap.servers = kafka1:9092,kafka2:9092

# 4. 配置第二个 Kafka Sink(低优先级,备用)
agent1.sinks.kafkaSink2.type = org.apache.flume.sink.kafka.KafkaSink
agent1.sinks.kafkaSink2.kafka.bootstrap.servers = kafka3:9092,kafka4:9092

# 5. 绑定 Channel 到 Sink Group
agent1.sinks.kafkaSink1.channel = memoryChannel
agent1.sinks.kafkaSink2.channel = memoryChannel

工作逻辑:

  1. 正常情况下,所有数据走 kafkaSink1(优先级 10 最高)
  2. kafkaSink1 连不上(超时、连接拒绝),处理器把它标记为”故障”
  3. 自动切换到 kafkaSink2(优先级 5)
  4. kafkaSink1 进入 30 秒”惩罚期”,期间不会被选
  5. 30 秒后尝试恢复,正常了重新启用

几个实操建议:

  • 优先级差值别太小。我一般设 5 以上的差距,避免两个 Sink 优先级太接近导致频繁判断。
  • maxpenalty 设多少? 取决于你的 Sink 恢复需要多久。Kafka 集群重启一般 30-60 秒,我设 30000(30 秒)。太短的话,Sink 还没恢复好就被拉回来试,浪费资源;太长的话,恢复后不能及时复用。
  • 别忘了监控。Flume 有 SinkProcessorFailoverCount 这个指标,记录了故障切换次数。如果这个数字频繁上涨,说明主 Sink 一直不稳定,得去排查原因,而不是放任它切来切去。

负载均衡(Load Balancing)配置与原理

这个场景更常见。比如你的日志量特别大,单个 HDFS Sink 写入速度跟不上,Channel 越积越多,最后 OOM。

解决办法:配两个(或更多)HDFS Sink,指向不同的 HDFS 集群或者不同的目录,流量分摊。

核心配置示例

以下配置实现两个 HDFS Sink 的负载均衡,采用轮询策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 定义 Sink Group(包含两个 HDFS Sink)  
agent1.sinkgroups = g1
agent1.sinkgroups.g1.sinks = hdfsSink1 hdfsSink2

# 2. 配置负载均衡处理器
agent1.sinkgroups.g1.processor.type = load_balance
# 选择负载均衡策略:round_robin(轮询)或 random(随机)
agent1.sinkgroups.g1.processor.selector = round_robin
# 是否启用回退机制(失败时自动切换到其他 Sink)
agent1.sinkgroups.g1.processor.backoff = true
# 失败重试间隔(指数退避)
agent1.sinkgroups.g1.processor.selector.maxTimeOut = 3000

# 3. 配置第一个 HDFS Sink(指向不同 HDFS 集群)
agent1.sinks.hdfsSink1.type = hdfs
agent1.sinks.hdfsSink1.hdfs.path = hdfs://hdfs-cluster1/flume-data/

# 4. 配置第二个 HDFS Sink(指向不同 HDFS 集群)
agent1.sinks.hdfsSink2.type = hdfs
agent1.sinks.hdfsSink2.hdfs.path = hdfs://hdfs-cluster2/flume-data/

# 5. 绑定 Channel 到 Sink Group
agent1.sinks.hdfsSink1.channel = memoryChannel
agent1.sinks.hdfsSink2.channel = memoryChannel
负载均衡策略

Flume 提供两种负载均衡策略,可以通过processor.selector属性指定:

策略 工作原理 适用场景
round_robin 按顺序轮流选择 Sink(如 Sink1 → Sink2 → Sink1…) 流量均匀的场景,避免单个 Sink 压力过大
random 随机选择 Sink 快速分散流量,适合突发流量场景

我一般用 round_robin,分配均匀、可预期。random 在流量分布不均匀的时候可能会导致某个 Sink 突然被大量命中,不好控制。

回退机制(Backoff)

当启用 backoff = true 时,

  1. 某个 Sink 如果写入失败了,处理器会暂时把它踢出可用列表
  2. 用指数退避算法(如初始 100ms,每次重试加倍)去重试;
  3. 若重试成功,重新将该 Sink 加入可用列表。

避免一个 Sink 出问题了还在持续给它分流量,浪费资源。

高级应用:组内负载均衡 + 组间故障转移

大一点的场景,可以两层嵌套:

  • 组内:多个 Sink 负载均衡,分摊流量
  • 组间:多个组之间故障转移,A 组全挂了切 B 组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 定义两个 Sink Group(每个组内负载均衡,组间故障转移)  
agent1.sinkgroups = group1 group2

# 2. 配置第一个 Sink Group(包含两个 Kafka Sink,负载均衡)
agent1.sinkgroups.group1.sinks = kafkaSink1 kafkaSink2
agent1.sinkgroups.group1.processor.type = load_balance
agent1.sinkgroups.group1.processor.selector = round_robin

# 3. 配置第二个 Sink Group(包含两个 HDFS Sink,负载均衡)
agent1.sinkgroups.group2.sinks = hdfsSink1 hdfsSink2
agent1.sinkgroups.group2.processor.type = load_balance
agent1.sinkgroups.group2.processor.selector = round_robin

# 主处理器:组间故障转移
# 4. 配置主 Processor(故障转移:优先使用 group1,失败时切换到 group2)
agent1.sinks = failoverSink
agent1.sinks.failoverSink.type = org.apache.flume.sink.FailoverSink
agent1.sinks.failoverSink.sinkgroups = group1 group2
agent1.sinks.failoverSink.priority.group1 = 10
agent1.sinks.failoverSink.priority.group2 = 5

这种配置的好处是:正常情况下流量分散到两个 Kafka Sink,吞吐翻倍;Kafka 集群出问题了,整组切到 HDFS 做降级存储,数据不丢。

最佳实践与性能优化

1. 故障转移配置建议

  • 优先级差异化:相邻 Sink 优先级差值≥5,避免因微小差异导致频繁切换;
  • 惩罚时间:根据 Sink 恢复时间设置 maxpenalty(如 Kafka 集群重启需 30-60 秒);
  • 监控告警:结合 Flume 内置指标(如 SinkFailedCounter)监控故障切换频率,避免频繁故障。

2. 负载均衡配置建议

  • 策略选择
    • 流量稳定场景用 round_robin,确保均匀分配;
    • 突发流量场景用 random,快速分散压力;
  • 回退机制:始终启用 backoff = true,避免向故障 Sink 持续发送数据;
  • Sink 数量:根据下游系统性能和数据量调整 Sink 数量(如 HDFS Sink 建议每 100MB/s 流量配置 1 个 Sink)。

3. 性能监控与调优

通过 JMX 或 Flume 内置指标监控 Sink Group 性能:

  • 吞吐量:监控 SinkEventDrainSuccessCount 指标,评估数据处理速率;
  • 失败率:监控 SinkEventDrainAttemptCountSinkEventDrainFailedCount,计算失败率;
  • 故障切换频率:统计 SinkProcessorFailoverCount,过高表示存在频繁故障。

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