Flume官网分享之一

292 阅读9分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Flume的介绍

什么是Flume

 可以理解flume是日志收集系统,Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受(可定制)的能力。 当前Flume有两个版本Flume 0.9X版本的统称Flume-og,Flume1.X版本的统称Flume-ng。由于Flume-ng经过重大重构,与Flume-og有很大不同,使用时请注意区分,经过架构重构后,Flume NG更像是一个轻量级的小工具,适应各种方式的日志收集,并支持failover和负载均衡。改动的另一原因是将 Flume 纳入 apache 旗下,cloudera Flume 改名为 Apache Flume。 Apache Flume是一个分布式,可靠且可用的系统,用于高效地收集,汇总和将来自多个不同源的大量日志数据移动到集中式数据存储区。Apache Flume的使用不仅限于日志数据聚合。 由于数据源是可定制的,Flume可用于传输大量的事件数据,包括但不限于网络流量数据,社交媒体生成的数据,电子邮件消息以及几乎所有可能的数据源。Apache Flume是Apache软件基金会的顶级项目。

Flume的结构

 - 数据流模型

Flume事件被定义为具有字节有效载荷和一组可选字符串属性的数据流单元。 Flume代理是一个(JVM)进程,它承载事件从外部源流向下一个目标(跳)的组件。Flume以agent为最小的独立运行单位。一个agent就是一个JVM。单agent由Source、Sink和Channel三大组件构成。

Flume源消耗由外部源(如Web服务器)传递给它的事件。外部源以Flume源识别的格式向Flume发送事件。例如,Avro Flume源可用于从Avro客户端或其他Flume客户端接收从Avro接收器发送事件的流中的Avro事件。使用Thrift Flume Source可以定义类似的流程,以接收来自Thrift Sink或Flume Thrift Rpc客户端的事件或使用Flume thrift协议生成的任何语言编写的Thrift客户端。当Flume源接收事件时,将其存储到一个或多个频道。渠道是一个被动的商店,保持事件,直到它被一个水槽水槽消耗。文件通道就是一个例子 - 它由本地文件系统支持。接收器从通道中删除事件并将其放入HDFS(通过Flume HDFS接收器)之类的外部存储库,或者将其转发到流中下一个Flume代理(下一个跃点)的Flume源。给定代理中的源和宿与运行在通道中的事件异步运行。

Flume的数据流由事件(Event)贯穿始终。事件是Flume的基本数据单位,它携带日志数据(字节数组形式)并且携带有头信息,这些Event由Agent外部的Source,比如上图中的Web Server生成。当Source捕获事件后会进行特定的格式化,然后Source会把事件推入(单个或多个)Channel中。你可以把Channel看作是一个缓冲区,它将保存事件直到Sink处理完该事件。Sink负责持久化日志或者把事件推向另一个Source。很直白的设计,其中值得注意的是,Flume提供了大量内置的Source、Channel和Sink类型。不同类型的Source,Channel和Sink可以自由组合。组合方式基于用户设置的配置文件,非常灵活。比如:Channel可以把事件暂存在内存里,也可以持久化到本地硬盘上。Sink可以把日志写入HDFS, HBase,甚至是另外一个Source等等。

 - 复杂流结构模型

  Flume允许用户在到达最终目的地之前通过多个代理程序建立多跳流。 它还允许扇入(fan-in)和扇出(fan-out)流,上下文路由和备份路由(故障转移),以用于失败的跳数。     ==注意==:同一个Source可以将数据存储到多个Channel,实际上是Replication。一个sink只能从一个Channel中读取数据Channel和Sink是一一对应的。==一个Channel只能对应一个Sink,一个Sink也只能对应一个Channel。     

 - Flume的可靠性

这些事件(events)在每个代理人(channel)的频道上进行。 然后将事件传递到流中的下一个代理或终端存储库(如HDFS)。 这些事件只有在存储在下一个代理通道或终端存储库中后才会从通道中删除。 这是Flume中单跳消息传递语义如何提供流的端到端可靠性。 Flume使用事务方式来保证事件的可靠传送。 sources和sinks分别在事务中封装由信道提供的事务中放置或提供的事件的存储/检索,这确保了该组事件在流程中可靠地传递(Source和Sink被封装进一个事务。事件被存放在Channel中直到该事件被处理,Channel中的事件才会被移除。这是Flume提供的点到点的可靠机制。)。 在多跳流的情况下,来自前一跳的接收器和来自下一跳的源两者的事务都在运行,以确保数据安全地存储在下一跳的信道中。

 - Flume的可恢复性

事件在Channel中进行,管理从故障恢复。 Flume支持由本地文件系统支持的持久文件通道。 还有一个内存通道,它将事件简单地存储在内存队列中,这个速度更快,但是当代理进程死亡时仍然留在内存通道中的任何事件都不能被恢复。

Flume名词的解释

 - Event:

Event是Flume数据传输的基本单元。Flume以事件的形式将数据从源头传送到最终的目的。Event由可选的header和载有数据的一个byte array 构成。可以是日志记录、 avro 对象等

 - Client:

Client 是一个将原始log包装成events并且发送他们到一个或多个agent的实体目的是从数据源系统中解耦Flume,==在flume的拓扑结构中不是必须的 #ec1d0e==。Client实例:flume log4j Appender,可以使用Client SDK(org.apache.flume.api)定制特定的Client。生产数据,运行在一个独立的线程。  - Agent:

 使用JVM 运行Flume。每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks。一个Agent包含 source ,channel,sink 和其他组件。它利用这些组件将events从一个节点传输到另一个节点或最终目的地,agent是flume流的基础部分。flume为这些组件提供了配置,声明周期管理,监控支持。    - Source:

从Client收集数据,传递给Channel。Source 负责接收event或通过特殊机制产生event,并将events批量的放到一个或多个Channel,包含==event驱动 #ec1d0e==和==轮询 #ec1d0e==两种类型。必须至少和一个channel关联。  - Channel:

连接 sources 和 sinks ,这个有点像一个队列,Channel有多种方式:有MemoryChannel, JDBC Channel, MemoryRecoverChannel, FileChannel。MemoryChannel可以实现高速的吞吐,但是==无法保证数据的完整 #ec1d0e==。MemoryRecoverChannel在官方文档的建议上已经建义使用FileChannel来替换。FileChannel保证数据的完整性与一致性。在具体配置FileChannel时,建议FileChannel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率。中转Event的一个临时存储,保存有source组件传递过来的Event,当sink成功的将event发送到下一个channel或最终目的,event从Channel移除,不同的channel提供的持久化水平是不一样的。  - Sink:

从Channel收集数据,运行在一个独立线程,Sink在设置存储数据时,可以向文件系统中,数据库中,hadoop中储数据,在日志数据较少时,可以将数据存储在文件系中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。负责将event传输到下一跳或最终目的,成功后将event从channel移除,必须作用一个确切的channel。  - Iterator:

作用于Source,按照预设的顺序在必要地方装饰和过滤events。  - channel selector:

允许Source基于预设的标准,从所有channel中,选择一个或者多个channel。  - sink processor:

多个sink 可以构成一个sink group,sink processor 可以通过组中所有sink实现负载均衡,也可以在一个sink失败时转移到另一个。

Flume内部原理

每个flume agent包含三个主要组件:source、channel、sink。  source是从一些其他产生数据的应用中接收数据的活跃组件,有自己产生数据的source,不过这些source通常用于测试目的,source可以监听一个或者多个网络端口,用于接收数据或者可以从本地文件系统读取数据,每个source必须至少连接一个channel,基于一些标准,一个source可以写入几个channel,复制事件到所有或某些channel。 
一般来说,channel是被动组件(虽然它们可以为了清理或者垃圾回收运行自己的线程),缓冲agent已经接收,但尚未写出到另一个agent或者存储系统的数据,channel的行为像==队列==,source写入到它们,sink从它们中读取,多个source可以安全地写入到相同channel,并且多个sink可以从相同的channel进行读取,可是一个sink只能从一个channel读取,如果多个sink从相同的channel读取,它可以保证只有一个sink将会从channel读取一个指定特定的事件, 
sink连续轮询各自的channel来读取和删除事件,sink将事件推送到下一阶段,或者最终目的地。一旦在下一阶段或其目的地中数据是安全的,sink通过事务提交通知channel,可以从channel中删除这些事件。