Flume学习笔记:02-Flume Agent内部原理和事务机制

Flume任务中Source、Channel、和Sink的对应关系

我们知道,Flume主要由3个组件组成,Source、Channel和Sink。在一个Flume的任务中,这3者的对应关系如下图所示:

flume_agent.png

  • 一个Source可以往多个Channel中写入数据
  • 多个Source也可以往一个Channel中写入数据
  • 一个Sink只能从一个Channel中读取数据
  • 多个Sink可以从一个Channel中读取数据

Flume Agent的内部原理

flume_agent2.png

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中。

flume_transaction.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值