文章目录
Flume任务中Source、Channel、和Sink的对应关系
我们知道,Flume主要由3个组件组成,Source、Channel和Sink。在一个Flume的任务中,这3者的对应关系如下图所示:
- 一个Source可以往多个Channel中写入数据
- 多个Source也可以往一个Channel中写入数据
- 一个Sink只能从一个Channel中读取数据
- 多个Sink可以从一个Channel中读取数据
Flume Agent的内部原理
Flume Agent的任务处理流程
如上图所示:
-
1、Source将每一条数据封装成一个个Event,一次发送一批次的数据交给ChannelProcessor进行处理。
-
2、ChannelProcessor收到这些数据后交给InterceptorChain(拦截器链)进行处理
-
3、这些拦截器是串行处理(一个拦截器处理完毕后交给下一个拦截器进行处理)的,所有的拦截器都处理完毕后将处理后的数据返回给ChannelProcessor。
-
4、ChannelProcessor将数据交给ChannelSelector(通道选择器)进行处理。
-
5、ChannelSelecto
-
r经过指定的Channel选择策略决定这些数据将路由到哪一个Channel中,并告知ChannelProcessor(默认的策略是replicating,复制发送到所有的channel中)
-
6、ChannelProcessor通过数据的路由目标,将数据分发到目标Channel中。
-
7、SinkProcessor从Channel中拉取处数据,并通过指定的处理策略决定将数据分发到哪个Sink中。
-
8、Sink将数据写入到外部存储系统中或者下级Flume的Source中。至此,一个Flume Agent的任务流程处理完毕。
ChannelSelector的类型
可以通过agent.sources.XX.selector.type来指定ChannelSelector的类型。Flume有4种ChannelSelector类型:
- replicating 副本类型
- load_balancing 负载均衡策略
- multiplexing 多路复用类型
- — 自定义选择器类型
如果没有指定,则默认是replicating类型。
replicating类型
a1.sources=r1
a1.channels=c1,c2,c3
a1.sources.r1.selector.type=replicating
a1.sources.r1.selector.optional=c3
在上面的配置中,默认使用的channelSelector类型是replicating。配置了3个channel,其中通过selector.optional=c3指定c3是可选的。意味着如果往C3中写入数据发生异常时将被忽略。如果往C1、C2中写入失败,则会引发事务的回滚。
load_balancing 类型
如果指定selector.type为load_balancing时,还需要指定selector.policy,如下示例配置:
a1.sources=r1
a1.channels=c1,c2,c3
a1.sources.r1.selector.type=load_balancing
a1.sources.r1.selector.policy=round_robin
负载均衡类型选择器有两种channel的选择策略:
-
round_robin 轮询策略,轮询策略会逐一向每个Channel中发送数据。
-
random 随机发送策略,随机选择某个Channel,将数据分发给Channel。
multiplexing 类型
a1.sources=r1
a1.channels=c1 c2 c3 c4
a1.sources.r1.selector.type=multiplexing
a1.sources.r1.selector.header=state
a1.sources.r1.selector.mapping.China=c1
a1.sources.r1.selector.mapping.Americ=c2 c3
a1.sources.r1.selector.mapping.default=c4
如果配置的ChannelSelector类型为multiplexing,则需要指定selector.header的Key值。
如上述示例配置,selector.header的Key为state。在每个Event中的header中必须得有这个Key。
然后配置如果匹配到了某些值,分发到相应的Channel中。如配置中指定,如果state的值是China,则发送给c1,如果state的值是America,则发送给c2和c3,如果都没匹配上,则发送给c4.
自定义ChannelSelector
a1.sources = r1
a1.channels = c1
a1.sources.r1.selector.type = org.example.MyChannelSelector
除了系统自带的那几种类型选择器以外,还可以自定义ChannelSelector,配置如上所示。如何自定义ChannelSelector,将在后续的文章中详细介绍。
SinkProcessor的处理策略
Flume中有3中SinkProcessor类型,分别是:
- default 默认类型(一个Channel对应一个Sink)
- failover 故障转移策略
- load_balance 负载均衡策略
default
Default Sink processor仅允许定义一个Sink。用户不需要为单个Sink创建Sink group组。就是最简单的source-channel-sink模式,无需显式的指定processor.type。
a1.sources=r1
a1.channels=c1
a1.sinks=s1
failover 故障转移策略
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=failover
a1.sinkgroups.g1.processor.priority.k1=5
a1.sinkgroups.g1.processor.priority.k2=10
a1.sinkgroups.g1.processor.maxpenalty = 10000
如上述job配置了一组Sink,k1和k2。k2的优先级高于k1,那么K2就会先于k1成为activate,数据就会发往k2,k1就是standby状态。如果k2挂掉了,数据发送失败,则会切换到k1,k1此时就会成为activate状态。
a1.sinkgroups.g1.processor.maxpenalty = 10000,最大回退周期,这个参数指定的在指定的时间(毫秒)内如果优先级高的Sink k2恢复正常了也不会被考虑启动,直到过了设定的时间后才会重新优先将数据发送给优先级更高的k2.
Tips:所有的Sink的优先级的数字必须是唯一的
load_balancing Sink Processor负载均衡处理器
a1.sinkgroups = g1
a1.sinkgroups.g1.sinks = k1 k2
a1.sinkgroups.g1.processor.type = load_balance
a1.sinkgroups.g1.processor.backoff = true
a1.sinkgroups.g1.processor.selector = random
load_balance 负载均衡处理策略有两种数据处理模式:
- random 随机模式,数据随机的发往每一个Sink
- round_robin 轮询模式,数据轮询的发往每一个Sink,即先发往k1,然后下一批次发往k2,再下一批次发往k1,如此循环往复,保证数据均衡轮询的发送给每一个Sink。
Tips:目前Flume不支持自定义的Sink processor。
自定义Interceptor
自定义Interceptor在Flume学习笔记:03-Flume的自定义Interceptor有详细介绍,在此就不详细展开讲述了。
Flume的事务机制
在Flume中有两种独立的事务机制来确保数据不被丢失。一种是doPut事务,一种是doTake事务。如下图所示,数据的推送过程中如下:
doPut事务
-
数据从Source端提交给Channel,一次提交一个批次的数据到Channel,这时不是直接就发送给Channel的,而是先doPut将数据写入到一个putList队列中,
-
doCommit将数据推送到Channel中,如果没有足够的空位,则回滚到putList中,如果有足够的空位,则将数据合并到Channel中,这时数据才真正被写入到Channel中。
由此,经过doPut事务,保证Source到Channel的操作不会丢失数据。
doTake事务
数据从Channel到Sink端对于Channel而言也是被动的,由Sink主动从Channel中拉取数据。这个操作也不是直接将数据写入到Sink中的,而是实现了doTake事务,将数据先写入到takeList中,然后再写入到Sink的。
- doTake现将数据写入到临时缓冲区takeList队列中,并将数据发送到外部存储系统中。
- doCommit去检查数据发送是否成功,如果数据发送成功,则清空临时缓冲区takeList。
- 如果数据发送失败(如外部存储系统服务崩溃),则doRollback将数据回滚到channel中。