Cloudera 开发的分布式日志收集系统 Flume,是 hadoop 周边组件之一。其可以实时的将分布在不同节点、机器上的日志收集到不同的存储系统。Flume 初始的发行版本目前被统称为 Flume OG(original generation),属于 cloudera。但随着 Flume 功能的扩展,Flume OG 代码工程臃肿、核心组件设计不合理、核心配置不标准等缺点暴露出来,尤其是在 Flume OG 的最后一个发行版本 0.94.0 中,日志传输不稳定的现象尤为严重。为了解决这些问题,2011 年 10 月 22 号,cloudera 完成了 Flume-728,对 Flume 进行了里程碑式的改动:重构核心组件、核心配置以及代码架构,重构后的版本统称为 Flume NG(next generation);改动的另一原因是将 Flume 纳入 apache 旗下,cloudera Flume 改名为 Apache Flume。不少的技术文章在介绍Flume时,将OG与NG的架构混用使人迷糊,本文阐述 Flume OG 到 Flume NG 发生的革命性变化。
FLUM OG
FLUM OG 的特点是:
- FLUM OG 有三种角色的节点,如图 1:代理节点(agent)、收集节点(collector)、主节点(master)。
- agent 从各个数据源收集日志数据,将收集到的数据集中到 collector,然后由收集节点汇总存入 hdfs。
- master 负责管理 agent,collector 的活动。
- agent、collector 都称为 node,node 的角色根据配置的不同分为 logical node(逻辑节点)、physical node(物理节点)。对 logical nodes 和 physical nodes 的区分、配置、使用一直以来都是使用者最头疼的地方。
- agent、collector 由 source、sink 组成,代表在当前节点数据是从 source 传送到 sink。如图 2。
图 1. FLUM OG 架构图
图 2. OG 节点组成图
FLUM NG
对应于 OG 的特点,FLUM NG 的特点是:
- NG 只有一种角色的节点:代理节点(agent)。如图3
- 没有 collector、master 节点。这是核心组件最核心的变化。
- 去除了 physical nodes、logical nodes 的概念和相关内容。
- agent 节点的组成也发生了变化。如图 4,NG agent 由 source、sink、channel 组成。
图 3. FLUM NG 架构图
图 4. NG 节点组成图
从整体上讲,NG 在核心组件上进行了大规模的调整,核心组件的数目由 7 删减到 4。由于 Flume 的使用涉及到众多因素,如 avro、thrift、hdfs、jdbc、zookeeper 等,而这些组件和 Flume 的整合都需要关联到所有组件。所以核心组件的改革对整个 Flume 的使用影响深远:
- 大大降低了对用户的要求,如核心组件的变化使得 Flume 的稳定使用不再依赖 zookeeper,用户无需去搭建 zookeeper 集群;另外用户也不再纠结于 OG 中的模糊概念(尤其是 physical nodes、logical nodes,agent、collector)。
- 有利于 Flume 和其他技术、hadoop 周边组件的整合,比如在 NG 版本中,Flume 轻松实现了和 jdbc、hbase 的集成。
- 将 OG 版本中复杂、大规模、不稳定的标签移除,Flume 实现了向灵活、轻便的转变,而且在功能上更加强大、可扩展性更高,这一点主要表现在用户使用 Flume 搭建日志收集集群的过程中。
Flume NG中的核心概念:
- Event:一个数据单元,带有一个可选的消息头
- Flow:Event从源点到达目的点的迁移的抽象
- Client:生产数据,操作位于源点处的Event,将其发送到Flume Agent。
- Agent:一个独立的Flume进程,包含组件Source、Channel、Sink
- Source:从Client收集数据,传递给Channel。可以接收外部源发送过来的数据。不同的 source,可以接受不同的数据格式。比如有目录池(spooling directory)数据源,可以监控指定文件夹中的新文件变化,如果目录中有文件产生,就会立刻读取其内容。
- Channel:中转Event的一个临时存储,保存有Source组件传递过来的Event。
- Sink:会消费channel中的数据,然后送给外部源或者其他source。如数据可以写入到HDFS或者HBase中。
删减节点角色,脱离 zookeeper
- Zookeeper 是针对大型分布式系统的可靠协调系统,适用于有多类角色集群管理。比如在 hbase 中,对 HMaster、HRegionServer 的管理。
- 在 OG 版本中,Flume 的使用稳定性依赖 zookeeper。它需要 zookeeper 对其多类节点(agent、collector、master)的工作进行管理,尤其是在集群中配置多个 master 的情况下。当然,OG 也可以用内存的方式管理各类节点的配置信息,但是需要用户能够忍受在机器出现故障时配置信息出现丢失。所以说 OG 的稳定行使用是依赖 zookeeper 的。
- 而在 NG 版本中,节点角色的数量由 3 缩减到 1,不存在多类角色的问题,所以就不再需要 zookeeper 对各类节点协调的作用了,由此脱离了对 zookeeper 的依赖。
- 由于 OG 的稳定使用对 zookeeper 的依赖表现在整个配置和使用过程中,这就要求用户掌握对 zookeeper 集群的搭建及其使用(尤其是要熟悉 zookeeper 数据文件夹 data,Flume 节点配置信息存放在此文件夹中);掌握 Flume 中和 zookeeper 相关的配置。对初次接触 Flume 的用户来讲,这是非常痛苦的事。
用户配置变化
从用户角度来讲,配置过程无疑是整个集群搭建的核心步骤。Flume 的配置分为两个部分:安装和数据传输配置。
安装
OG 在安装时:
- 在 flume-env.sh 中设置$JAVA_HOME。
- 需要配置文件 flume-conf.xml。其中最主要的、必须的配置与 master 有关。集群中的每个 Flume 都需要配置 master 相关属性(如 flume.master.servers、flume.master.store、flume.master.serverid)。
- 如果想稳定使用 Flume 集群,还需要安装 zookeeper 集群,这需要用户对 zookeeper 有较深入的了解。
- 安装 zookeeper 之后,需要配置 flume-conf.xml 中的相关属性,如 flume.master.zk.use.external、flume.master.zk.servers。
- 在使用 OG 版本传输数据之前,需要启动 master、agent。
NG 在安装时:
- 只需要在 flume-env.sh 中设置$JAVA_HOME。
数据传输配置
OG 版本的配置途径有两个:
- shell 命令:需要用户掌握 Flume shell 命令;
- master console 页面:这是 OG 用户最常用的配置方式;弊端在于,除非用户熟悉复杂的各类 source,sink 配置函数以及格式(source:大约 25 个,sink:大约 46 个),否则在复杂的集群环境下,用户每次只能配置一个节点(指定 source、sink)来保证配置的准确性;
NG 的配置:
- 只需要一个配置文件,这个配置文件中存放 source、sink、channel 的配置。如图 5 中是配置文件 example.conf 里面的内容,其中 agent_foo 是 agent 名字。然后在启动 agent 时,使用一下命令指定这个配置文件:
核心组件-Source
Flume Source 支持的类型如下:
核心组件-Channel
当前有几个 channel 可供选择,分别是 Memory Channel, JDBC Channel , File Channel,Psuedo Transaction Channel。比较常见的是前三种 channel。
- MemoryChannel 可以实现高速的吞吐,但是无法保证数据的完整性。
- MemoryRecoverChannel 在官方文档的建议上已经建义使用FileChannel来替换。
- FileChannel保证数据的完整性与一致性。在具体配置FileChannel时,建议FileChannel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率
File Channel 是一个持久化的隧道(channel),它持久化所有的事件,并将其存储到磁盘中。因此,即使 Java 虚拟机当掉,或者操作系统崩溃或重启,再或者事件没有在管道中成功地传递到下一个代理(agent),这一切都不会造成数据丢失。Memory Channel 是一个不稳定的隧道,其原因是由于它在内存中存储所有事件。如果 java 进程死掉,任何存储在内存的事件将会丢失。另外,内存的空间收到 RAM大小的限制,而 File Channel 这方面是它的优势,只要磁盘空间足够,它就可以将所有事件数据存储到磁盘上。
Flume Channel 支持的类型:
核心组件-sink
Sink在设置存储数据时,可以向文件系统、数据库、hadoop存数据,在日志数据较少时,可以将数据存储在文件系中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。
Flume Sink支持的类型
flume 插件
- Interceptors拦截器: 用于source和channel之间,用来更改或者检查Flume的events数据
- channels Selectors管道选择器: 在多管道是被用来选择使用那一条管道来传递数据(events). 管道选择器又分为如下两种:
-
默认管道选择器: 每一个管道传递的都是相同的events
- 多路复用通道选择器: 依据每一个event的头部header的地址选择管道
-
- sink线程:用于激活被选择的sinks群中特定的sink,用于负载均衡.
如下图:
- 采集的日志会传入ChannelProcessor组件,其首先通过Interceptor进行日志过滤,过滤器可以过滤掉日志,也可以修改日志内容;
- 过滤完成后接下来会交给ChannelSelector进行处理,默认提供了两种选择器:复制或多路复用选择器;复制即把一个日志复制到多个Channel;而多路复用会根据配置的选择器条件,把符合条件的路由到相应的Channel;
- 在写多个Channel时可能存在存在失败的情况,对于失败的处理有两种:稍后重试或者忽略。重试一般采用指数级时间进行重试。
- Source生产日志给Channel、Sink从Channel消费日志;它俩完全是异步的,因此Sink只需要监听自己关系的Channel变化即可。
使用场景
根据官网文档,展示几种Flow Pipeline,各自适应的应用场景如下:
1、多个 agent 顺序连接
- 可以将多个Agent顺序连接起来,将最初的数据源经过收集,存储到最终的存储系统中。这是最简单的情况,一般情况下,应该控制这种顺序连接的Agent的数量,因为数据流经的路径变长了,如果不考虑failover的话,出现故障将影响整个Flow上的Agent收集服务。
2、多个Agent的数据汇聚到同一个Agent
- 这种情况应用的场景比较多,比如要收集Web网站的用户行为日志,Web网站为了可用性使用的负载均衡的集群模式,每个节点都产生用户行为日志,可以为每个节点都配置一个Agent来单独收集日志数据,然后多个Agent将数据最终汇聚到一个用来存储数据存储系统,如HDFS上。
3、多路(Multiplexing)Agent
- 这种模式,有两种方式,一种是用来复制(Replication),另一种是用来分流(Multiplexing)。Replication方式,可以将最前端的数据源复制多份,分别传递到多个channel中,每个channel接收到的数据都是相同的。
- 上面指定了selector的type的值为replication,其他的配置没有指定,使用的Replication方式,Source1会将数据分别存储到Channel1和Channel2,这两个channel里面存储的数据是相同的,然后数据被传递到Sink1和Sink2。
- Multiplexing方式,selector可以根据header的值来确定数据传递到哪一个channel,配置格式,如下所示:
- 上面selector的type的值为multiplexing,同时配置selector的header信息,还配置了多个selector的mapping的值,即header的值:如果header的值为Value1、Value2,数据从Source1路由到Channel1;如果header的值为Value2、Value3,数据从Source1路由到Channel2。
4、实现load balance功能
- Load balancing Sink Processor能够实现load balance功能,上图Agent1是一个路由节点,负责将Channel暂存的Event均衡到对应的多个Sink组件上,而每个Sink组件分别连接到一个独立的Agent上,示例配置,如下所示:
- flume内置的负载均衡的算法默认是:round_robin,轮询算法,按序选择
- backoff=true: 失败补偿机制
示意图:
- 负载均衡算法默认提供了两种:轮训和随机;其通过抽象一个类似ChannelSelector的SinkSelector进行选择,失败补偿机制和Failover中的算法类似,但是默认是关闭失败补偿的,需要配置backoff参数为true开启。
5、实现failover
- Failover Sink Processor能够实现failover功能,具体流程类似load balance,但是内部处理机制与load balance完全不同:Failover Sink Processor维护一个优先级Sink组件列表,只要有一个Sink组件不可用,Event就被传递到下一个组件。如果一个Sink能够成功处理Event,则会加入到一个Pool中,否则会被移出Pool并计算失败次数,设置一个惩罚因子,示例配置如下所示:
- priority越高,优先级越高,会优先使用该sink
示意图如下:
- Failover策略是给多个Sink定义优先级,假设其中一个失败了,则路由到下一个优先级的Sink;Sink只要抛出一次异常就会被认为是失败了,则从存活Sink中移除,然后指数级时间等待重试,默认是等待1s开始重试,最大等待重试时间是30s。
ng 搭建及参数说明
搭建步骤:
- 下载 flume-ng 安装包,当前最新版本为:1.7.0 (http://flume.apache.org/releases/index.html)
- Flume 发布了两类包:source 和 bin。Source 包用于开发工作,bin 包用于安装 Flume 搭建日志收集场景。
- 生成配置文件 example.conf。内容如图 6。整个配置分为四部分。表 1 是配置说明。
- 进入 bin 目录,使用一下命令启动 Flume,开始日志收集。
-
$ flume-ng agent -c /etc/flume-ng/conf -f /etc/flume-ng/conf/example.conf -Dflume.root.logger=DEBUG,console -n agent_ff
参数说明:
- -n 指定agent名称
- -c 指定配置文件目录
- -f 指定配置文件
- -Dflume.root.logger=DEBUG,console 设置日志等级
图 6. example.conf
表 1. flume-conf.xml
参考资料
- IBM, Flume NG:Flume 发展史上的第一次革命
- 分布式日志收集收集系统:Flume
- 官方网站:Apache Flume
- 用户文档:http://flume.apache.org/FlumeUserGuide.html
- 开发文档:http://flume.apache.org/FlumeDeveloperGuide.htm
- Flume-ng的原理和使用
- Flume NG 基本架构及原理
- flume介绍与原理(一)
- http://blog.javachen.com/2014/07/22/flume-ng.html
- http://jinnianshilongnian.iteye.com/blog/2261225