Flume 系列 (二) 结构及运行原理

Flume结构及运行原理
一、Flume 特点
flume是一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统。支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(比如文本、HDFS、Hbase等)的能力 ,关于flume介绍,可以参考另外篇博文《Flume  初识》

二、Flume 概念及结构
Event: flume内部的数据单元,包含两部分,一个头结点,一个body结点,头结点是一个Map<String, String>,部署的agent结点可以通过现有的Interceptor或者自定义Interceptor往消息头里放置数据,如ip,hostname等标识消息来源于哪台服务器,event在flume内部做流转,是数据传输的载体
Agent: 一个独立的Flume进程,包含组件Source、 Channel、 Sink。
 
Source: 是数据的收集端,负责将数据捕获后进行特殊的格式化,将数据封装到事件(event) 里,然后将事件推入Channel中。 Flume提供了很多内置的Source, 支持 Avro, log4j, syslog 和 http post(body为json格式)。可以让应用程序同已有的Source直接打交道,如AvroSource, SyslogTcpSource,Directory Source。 
flume支持多种数据来源,如taildir监控一个文件的变化,spollDir监控一个文件夹的变化,jmsSource接收jms消息等,最常用的avroSource是构成flume分层架构的基础,source是一个接口,flume提供了多种消息接入方式,在sourceType枚举类中都有详细列出,特殊说明下,由于flume是面向接口编程,其中有一个Other的枚举,是占位符,使用者可以自定义source源,只要求在flume启动的时候可以加载到这个类即可(底层是通过反射获取到class的实例的)
Channel: 是一种短暂的存储容器,它将从source处接收到的event格式的数据缓存起来,直到它们被sinks消费掉,它在source和sink间起着一共桥梁的作用,channal是一个完整的事务,这一点保证了数据在收发的时候的一致性. 并且它可以和任意数量的source和sink链接. 支持的类型有: JDBC channel , File System channel , Memort channel等.
flume是基于pipeline的模式,channel的存在丰富了flume的数据传播途径,channel可以再source和sink之间做缓冲,动态调节数据的收集及发送(内部有一个xxxCounter会没接收到一个event或者发送一个event都会做记录),缓冲source和sink之间的压力,其二channel可以关联多个source,如一个source可以按照配置选择的将数据复制到各个管道,或者按照消息头自动分发到指定的管道,一个channel可以接多个sink,这个实现了同一份数据的多发发送池,实现了数据的复用及负载均衡等功能,channel内部流转的数据载体是event,flume channel支持多种数据缓冲实现方式,如fileChannel:用一个文件做数据缓存、memoryChannel:使用内存缓存,底层实现是一个LinkedBlockingDeque,一个双向阻塞列表,具体可参见ChannelType
Sink从Channel中取出事件,然后将数据发到别处,可以向文件系统、数据库、 hadoop存数据, 也可以是其他agent的Source。在日志数据较少时,可以将数据存储在文件系统中,并且设定一定的时间间隔保存数据。
flume的数据发送池Sink,主要负责数据的发送,从channel接收到event,然后发送到指定的数据接收方,flume提供多种sink实现,具体可参见SinkType,常用的有:loggerSink:这个主要用于flume的部署调试,它会将接收到的event事件直接用log4j输出出来,RollingFileSink:这个sink主要是将接收到的日志文件序列化到一个文件目录中,所以需要配置文件的地址,切分文件的频率等,avroSink:这个是flume分层架构中最常用的sink,一般和avroSource配对使用,avro是apache的一个子项目,用于数据的序列化,使用avroSource及avroSink时,需要在avroSource的agent节点服务器上监听一个端口,avroSink的agent把接收到的数据发送到该ip、port上即完成了flume的分层部署,avro仅是一个数据序列化工具,底层实现由一个RpcClient的东东来将数据在这source和sink之间传输(可以留一下启动日志,会自动创建一个RpcClient),当然,flume的编码是按照面向接口来的,所以和source一样支持自定义的sink
Flume提供了大量内置的Source、Channel和Sink类型。不同类型的Source,Channel和Sink可以自由组合。组合方式基于用户设置的配置文件,非常灵活。

三、Flume 运行原理
flume提供了很多辅助类用于驱动、分发内部event及整个flume系统的运转,基本如下
配置领域:
AgentConfiguration:这个看名字就知道是flume的配置元素领域内的东西,是的,使用者在flume-conf.properties中配置的数据解析成AgentConfiguration,是配置文件到面向对象的一个抽象
AbstractConfigurationProvider:该类看名字就是一个抽象的配置Provider类,内部有一个很重要的方法就是:getConfiguration(),该方法中通过如下几个private方法来加载flume的channel、source、sink、sinkGroups并将它们关联起来
        loadChannels(agentConf, channelComponentMap);
        loadSources(agentConf, channelComponentMap, sourceRunnerMap);
        loadSinks(agentConf, channelComponentMap, sinkRunnerMap);
flume还支持动态加载,PollingPropertiesFileConfigurationProvider(AbstractConfigurationProvider的一个具体实现)在flume启动的时候会启动一个线程FileWatcherRunnable,监控flume的配置文件变化,配置文件内部加载用的是google的EventBus来驱动的
驱动领域:
flume的source有如下两个子接口:PollableSource和EventDrivenSource,前者需要自己去轮循的访问数据源,当前是否可以加载到数据,如果有则加载进来转换成flume的event,实现类有taildir、spollDir、jsmSource、kafkaSource等,该接口新增了一个process方法用于轮循调用,后者是一个事件驱动的Source,该接口不需要主动去访问数据源,仅需要接收数据推动过来的event并转换成flume的event即可,实现类有:scribeSource(该数据源用来打通Facebook的scribe数据收集工具)、AvroSource等
SourceRunner:由于这两个source的存在,所以所以flume提供了两个sourceRunner来驱动source的运行,分别是PollableSourceRunner和EventDrivenSourceRunner,前者启动时自动启动一个PollingRunner线程用于定时轮循process方法
channelProcessor:该类用于source到channel之间的数据发送,实现了一个source可以关联到多个channel,简单点如这2个接口,source的定义:setChannelProcessor(ChannelProcessor channelProcessor)指定一个ChannelProcessor ,ChannelProcessor 关联到一个final的ChannelSelector,selector关联到Channel:setChannels(List<Channel> channels)
ChannelProcessor:关联到指定的ChannelSelector,ChannelSelector提供了两种selector方式,ReplicatingChannelSelector:将source的event复制到各个channel中,MultiplexingChannelSelector:根据头结点的header信息自动路由到对应的Channel中Transaction及BasicTransactionSemantics
flume的Channel内部保证一个event的发送在一个事务完成,如果发送失败或者接收失败则回滚,当成功时才从channel中删除掉该event
SinkProcessor:用过选择要发送的sink,什么意思呢?该类有两个实现:
LoadBalancingSinkProcessor:负载均衡方式:提供了roud_bin算法和random算法、以及固定order算法的实现方式,将Channel中的event发送到多个sink上
FailoverSinkProcessor:可以实现实现failover功能,具体流程类似LoadBalancingSinkProcessor,区别是FailoverSinkProcessor维护了一个PriorityQueue,用来根据权重选择sink
SinkRunner:该类用于驱动一个sink,启动是内部开了一个线程PollingRunner,定时的调用SinkProcessor
上述是所有的核心概念及代码作用,下面描述下flume的运行流程:
1.系统启动时通过配置领域可以按照客户定义的配置加载一个flume
2.SourceRunner和SinkProcessor同时启动,一个往Channel中生产event,一个从Channel中消费event,内部是一个生产者消费者模式
3.通过一些辅助类,实现Channel到source及sink的多路分发及分层架构

参考博文:https://www.cnblogs.com/zhangyinhua/p/7803486.html
https://www.cnblogs.com/adealjason/p/6240122.html
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值