Flume原理篇

1 Flume简介

      Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。
      当前Flume有两个版本,Flume0.9x版本之前的统称为Flume OG (Flume original generation),Flume1.x版本被统称为Flume NG (Flume next generation)。

2 Flume OG

2.1 Flume OG的设计目标

(1)可靠性:当节点出现故障时,日志能够被传送到其他节点上而不丢失。Flume提供了三种级别的可靠性保障,从强到弱依次为:end-to-end(收到数据Agent首先将event写到磁盘上,当数据传送成功后,再删除;如果数据发送失败,可以重新发送);store on failure(这也是scribe采用的策略,当数据接收方crash时,将数据写到本地,待恢复后,继续发送);best effort(数据发送到接收方后,不会进行确认)。
(2)可扩展性:Flume采用了三层架构,分别为Agent、Collector和Storage,每一层均可以水平扩展。其中,所有Agent和Collector由Master统一管理,这使得系统容易监控和维护,且Master允许有多个(使用Zookeeper进行管理和负载均衡),这就避免了单点故障问题。
(3)可管理性:所有Agent和Collector由Master统一管理,这使得系统便于维护。多Master情况,Flume利用Zookeeper和gossip,保证动态配置数据的一致性。用户可以在Master上查看每个数据源或者数据流执行情况,且可以对每个数据源配置和动态加载。Flume提供了web和shell scrip command两种形式对数据源进行管理。
(4)功能可扩展性:用户可以根据需要添加自己的Agent、Collector或者Storage。此外,Flume自带了很多组件,包括各种Agent(file,syslog等),Collector和Storeage(file、HDFS等)

2.2 Flume OG架构 Flume原理篇

(1)Agent
      Agent用于采集数据,Agent是Flume中产生数据流的地方,同时Agent会产生的数据流传输到Collector。通常由source和sink两部分组成:
      ① source用于获取数据,可从文本文件、syslog和HTTP等获取数据;
      ② sink将source获得的数据进一步传输给后面的Collector。
(2)Collector
      Collector用于对数据进行聚合(数据收集器),往往会产生一个更大的数据流,然后加载到storage(存储)中,比如HDFS和HBase等。
引入Collector的原因:
      ① 对Agent数据进行汇总,避免产生过多小文件;
      ② 避免多个Agent连接对Hadoop造成过大的压力;
      ③ 中间件,屏蔽Agent和Hadoop间的异构性。
(3)Master
      ① 管理协调Agent和Collector的配置信息;
      ② Flume集群的控制器;
      ③ 跟踪数据流的最后确认信息,并通知Agent;
      ④ 通常需配置多个Master以防止单点故障;
      ⑤ 借助Zookeeper管理多个Master。
(4)Agent和Collector对应关系
      ① 可手动指定,也可自动匹配;
      ② 自动匹配的情况下,Master会平衡Collector之间的负载。 Flume原理篇
(5)三种可靠性级别
      ① agentE2ESink[(“machine”[,port])]:Agent收到确认信息才认为数据发送成功,否则重试。
      ② agentDFOSink[(“machine”[,port])](推荐):当Agent发现在Collector操作失败,Agent写入到本地硬盘上,当Collector恢复后,再重新发送数据。
      ③ agentBESink[(“machine”[,port])]:效率最好,Agent不写入到本地任何数据,如果在Collector发现处理失败,直接删除消息。

3 Flume NG

      由原来的Flume OG到现在的Flume NG,进行了架构重构,并且现在NG版本完全不兼容原来的OG版本。经过架构重构后,Flume NG更像是一个轻量的小工具,非常简单,容易适应各种方式日志收集,并支持故障转换(failover)和负载均衡。对于Flume NG,它摒弃了Collector、Master和Zookeeper。此时一个Agent的包括Source、Channel和Sink,完全由一个分布式系统变成了传输工具。不同机器之间的数据传输不再是OG那样由Agent->Collector,而是由一个Agent端的Sink流向另一个Agent的Source。

3.1 Flume NG的核心概念

(1)Client:生产数据,运行在一个独立的线程。
(2)Source:从Client收集数据,传递给Channel。可以接收外部源发送过来的数据。不同的Source,可以接受不同的数据格式。比如有目录池(spooling directory)数据源,可以监控指定文件夹中的新文件变化,如果目录汇中有文件产生,就会立刻读取其内容。
(3)Channel:是一个存储池,接收Source的输出,直到有Sink消费掉Channel中的数据。Channel中的数据直到进入到下一个Channel中或者进入终端才会被删除。当Sink写入失败后,可以自动重启,不会造成数据丢失,因此很可靠。
(4)Sink:会消费Channel中的数据,然后送给外部源或者其他Source。如数据可以写入到HDFS或者HBase中。
(5)Agent:使用JVM运行Flume。每台机器运行一个Agnet,但是可以在一个Agent中包含多个Source和Sink。
(6)Events:Flume NG传输的数据的基本单位是event,如果是文本文件,通常是一行记录,这也是事务的基本单位。

3.2 Flume NG相对于Flume OG的主要变化

(1)Source和Sink使用Channel进行连接。
(2)两个主要Channel:memory Channel,非持久性支持,速度快;file Channel持久性支持。
(3)不再区分逻辑和物理node,所有节点统称为Agent,每个Agent都能运行0个或多个Source和Sink。
(4)不再需要Master节点和Zookeeper的依赖,配置文件简单化。
(5)插件化,一部分面对用户、工具或者系统开发人员。
(6)使用Thrift、Avro Flume Source可以从Flume 0.9.4发送events到Flume 1.x。

3.3 Flume NG架构

(1)Flume NG节点组成图 Flume原理篇
(2)Flume NG双节点组成图
Flume原理篇
(3)Flume NG多层架构 Flume原理篇

3.3.1 Client

(1)Client是一个将原始log包装成events并且发送它们到一个或者多个Agent的实体。
(2)Client在Flume的拓扑结构中不是必须的,它的目的是从数据源系统中解耦Flume。

3.3.2 Event

(1)Event是Flume数据传输的基本单元。
(2)Flume以事件的形式将数据从源头传输到最终的目的。
(3)Event 由可选的header和载有数据的一个byte array构成。
      ① 载有的数据对Flume是不透明的;
      ② Header 是容纳了key-value字符串对的无序集合,key在集合内是唯一的;
      ③Header 可以在上下文路由中使用扩展。

3.3.3 Agent

(1)一个Agent包含Source、Channel、Sink和其他组件。
(2)它利用这些组件将events从一个节点传输到另一个节点或最终目的地。
(3)Agent是Flume流的基础部分。
(4)Flume 为这些组件提供了配置、生命周期管理、监控支持。

3.3.4 Source

      Flume支持Avro、log4j、syslog和http post(body为json格式)。可以让应用程序同已有的Source直接打交道,如AvroSource,SyslogTcpSource。也可以写一个Source,以IPC或RPC的方式接入自己的应用,Avro和Thrift都可以(分别有 NettyAvroRpcClient 和 ThriftRpcClient 实现了 RpcClient接口),其中 Avro 是默认的 RPC 协议。具体代码级别的 Client 端数据接入,可以参考官方手册。对现有程序改动最小的使用方式是使用是直接读取程序原来记录的日志文件,基本可以实现无缝接入,不需要对现有程序进行任何改动。 对于直接读取文件 Source,有两种方式:
      (1)ExecSource:以运行Linux命令的方式,持续的输出最新的数据,如tail –f文件名指令,在这种方式下,取的文件名必须是指定的。ExecSource可以实现对日志的实时收集,但是存在Flume不运行或者指令执行出错时,将无法收集到日志数据,无法保证日志数据的完整性。
      (2)SpoolSource:监测配置的目录下新增的文件,并将文件中的数据读取出来。需要注意两点:拷贝到spool目录下的文件不可以再打开编辑;spool目录下不可包含相应的子目录。SpoolSource虽然无法实现实时的收集数据,但是可以使用以分钟的方式分割文件,趋近于实时。如果应用无法实现以分钟切割日志文件的话, 可以两种收集方式结合使用。在实际使用的过程中,可以结合 log4j 使用,使用 log4j的时候,将 log4j 的文件分割机制设为1分钟一次,将文件拷贝到spool的监控目录。log4j 有一个 TimeRolling 的插件,可以把 log4j 分割文件到 spool 目录。基本实现了实时的监控。Flume 在传完文件之后,将会修改文件的后缀,变为 .COMPLETED(后缀也可以在配置文件中灵活指定)
关于Source的要点:
      (1)Source负责接收event或通过特殊机制产生event,并将events批量的放到一个或多个Channel。
      (2)Source包含event驱动和轮询两种类型。
      (3)Source 有不同的类型。
            ① 与系统集成的Source:Syslog,NetCat。
            ② 自动生成事件的Source:Exec
            ③ 用于Agent和Agent之间的通信的IPC Source:Avro、Thrift。
      (4)Source必须至少和一个Channel关联。

3.3.5 Channel

      当前有几个 channel 可供选择,分别是 Memory Channel (volatile), JDBC Channel (基于嵌入Database实现), File Channel (基于预写日志系统(Write-Ahead Logging,WAL)实现),Psuedo Transaction Channel。比较常见的是前三种 channel。
      (1)MemoryChannel可以实现高速的吞吐,但是无法保证数据的完整性。
      (2)MemoryRecoverChannel在官方文档的建议上已经建议使用FileChannel来替换。
      (3)FileChannel保证数据的完整性与一致性。在具体配置FileChannel时,建议FileChannel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率。
      File Channel 是一个持久化的隧道(Channel),它持久化所有的事件,并将其存储到磁盘中。因此,即使 Java 虚拟机当掉,或者操作系统崩溃或重启,再或者事件没有在管道中成功地传递到下一个代理(Agent),这一切都不会造成数据丢失。Memory Channel 是一个不稳定的隧道,其原因是由于它在内存中存储所有事件。如果 java 进程死掉,任何存储在内存的事件将会丢失。另外,内存的空间收到 RAM大小的限制,而 File Channel 这方面是它的优势,只要磁盘空间足够,它就可以将所有事件数据存储到磁盘上。
关于Channel的要点:
      (1)Channel位于Source和Sink之间,用于缓存进来的event。
      (2)当Sink成功的将event发送到下一跳的Channel或最终目的地,event才Channel中移除。
      (4)不同的Channel提供的持久化水平也是不一样的:
            ① Memory Channel:volatile。
            ② File Channel:基于WAL实现。
            ③ JDBC Channel:基于嵌入Database实现。
      (4)Channel支持事物,提供较弱的顺序保证。
      (5)Channel可以和任何数量的Source和Sink工作。

3.3.6 Sink

      Sink在设置存储数据时,可以向文件系统、数据库、Hadoop存数据,在日志数据较少时,可以将数据存储在文件系统中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。
关于Sink的要点:
      (1)Sink负责将event传输到下一跳或最终目的,成功完成后将event从Channel移除。
      (2)有不同类型的Sink:
            ① 存储event到最终目的的终端Sink。比如HDFS,HBase。
            ② 自动消耗的Sink。比如:Null Sink。
            ③ 用于Agent间通信的IPC sink:Avro。
      (3)Sink必须作用于一个确切的Channel。
      从整体上讲,NG 在核心组件上进行了大规模的调整,核心组件的数目由 7 删减到 4。由于 Flume 的使用涉及到众多因素,如 avro、thrift、hdfs、jdbc、zookeeper 等,而这些组件和 Flume 的整合都需要关联到所有组件。所以核心组件的改革对整个 Flume 的使用影响深远:
      (1)大大降低了对用户的要求,如不再依赖 zookeeper,用户无需去搭建 zookeeper 集群。
      (2)用户也不再纠结于OG中的模糊概念(尤其是 physical nodes、logical nodes,agent、collector)。
      (3)有利于 Flume 和其他技术、hadoop周边组件的整合,比如在NG版本中,Flume轻松实现了和jdbc、hbase的集成。
      (4)将 OG 版本中复杂、大规模、不稳定的标签移除,Flume 实现了向灵活、轻便的转变,而且在功能上更加强大、可扩展性更高。

参考文章:
[1]《Hadoop权威指南》
[2] https://www.biaodianfu.com/flume.html
[3] https://www.cnblogs.com/qiaoyihang/p/6166145.html
[4] https://blog.****.net/chch998/article/details/80876667