一、概述

1.1 Flume体系结构

image.png
image.png

Source组件

(1)avro source:监听 Avro 端口来接收外部 avro 客户端的事件流。avro-source
接收到的是经过avro序列化后的数据,然后反序列化数据继续传输。如果是avro
source的话,源数据必须是经过avro序列化后的数据。利用 Avro source可以实现多
级流动、扇出流、扇入流等效果。接收通过flume提供的avro客户端发送的日 志信
息。
image.png
(2)exec source:可以将命令产生的输出作为source。如ping
192.168.234.163、tail -f hive.log。
(3)netcat source:一个NetCat Source用来监听一个指定端口,并接收监听到的
数据
(4)spooling directory source:将指定的文件加入到“自动搜集”目录中。flume会
持续监听这个目录,把文件当做source来处理。注意:一旦文件被放到目录中后,
便不能修改,如果修改,flume会报错。此外,也不能有重名的文件。
(5)Taildir Source(1.7):监控指定的多个文件,一旦文件内有新写入的数据,
就会将其写入到指定的sink内,本来源可靠性高,不会丢失数据。其不会对于跟踪的
文件有任何处理,不会重命名也不会删除,不会做任何修改。目前不支持Windows
系统,不支持读取二进制文件,支持一行一行的读取文本文件。

Channel组件

(1)memory channel:缓存到内存中(最常用,会丢失数据)
(2)file channel:缓存到文件中(数据不丢失)
(3)JDBC channel:通过JDBC缓存到关系型数据库中
(4)kafka channel:缓存到kafka中

Sink组件

(1)logger sink:将信息显示在标准输出(控制台输出)上,主要用于测试
(2)avro sink:Flume events发送到sink,转换为Avro events,并发送到配置好的hostname/port。从配置好的channel按照配置好的批量大小批量获取events
(3)null sink:将接收到events全部丢弃
(4)HDFS sink:将 events 写进HDFS。支持创建文本和序列文件,支持两种文件
类型压缩。文件可以基于数据的经过时间、大小、事件的数量周期性地滚动。(下图)
image.png
(5)Hive sink:该sink streams 将包含分割文本或者JSON数据的events直接传送
到Hive表或分区中。使用Hive 事务写events。当一系列events提交到Hive时,它们
马上可以被Hive查询到
(6)HBase sink:保存到HBase中
(7)kafka sink:保存到kafka中

1.2 Flume拓扑结构

(1)串行模式

(2)复制模式(单Souce多Channel、Sink模式)

(3)负载均衡模式(单Source、Channel多Sink)

(4)聚合模式

这种模式最常见的,也非常实用,日常web应用通常分布在上百个服务器,大者甚至上千个、上万个服务器。产生的日志,处理起来也非常麻烦。用这种组合方式能很好的解决这一问题,每台服务器部署一个flume采集日志,传送到一个集中收集日志的总flume(它的source就是前面多个sink的输出),再由此flume上传到hdfs、hive、hbase、消息队列中

1.3 Flume内部原理

  • 总体数据流向:Souce => Channel => Sink
  • Channel: 处理器、拦截器、选择器

image.png
日志处理流程:

image.png

二、高级特性

2.1 拦截器

2.1.1 时间添加戳拦截器

这个拦截器会向每个event的header中添加一个时间戳属性进去,key默认是 “timestamp ”(也可以通过下面表格中的header来自定义),value就是当前的毫秒 值(其实就是用System.currentTimeMillis()方法得到的)。如果event已经存在同名的属性,可以选择是否保留原始的值 preserveExisting=true保留。
配置效果:
image.png
image.png

2.2.2 Host添加拦截器

这个拦截器会把当前Agent的 hostname 或者 IP 地址写入到Event的header中,key 默认是“host”(也可以通过配置自定义key),value可以选择使用hostname或者IP 地址。
配置效果:
image.png
image.png

2.2 选择器

2.2.1 复制选择器

默认的选择器。
image.png
image.png
上面这个例子中,c3配置成了可选的。向c3发送数据如果失败了会被忽略。c1和c2 没有配置成可选的,向c1和c2写数据失败会导致事务失败回滚。

2.2.2 多路复用选择器

image.png
image.png

2.2.3 自定义选择器

2.3 Sink组逻辑处理器

可以把多个sink分成一个组, Sink组逻辑处理器可以对这同一个组里的几个sink进行 负载均衡 或者 其中一个sink发生故障后将输出Event的任务转移到其他的sink上。
N个sink将Event输出到对应的N个目的地的,通过 Sink组逻辑处理器 可以把这N个 sink配置成负载均衡或者故障转移的工作方式。

故障转移方式

  • 故障转移是这N个sink同一时间只有一个在工作,其余的作为备用,工作的sink 挂掉之后备用的sink顶上
  • 故障转移组逻辑处理器维护了一个发送Event失败的sink的列表,保证有一个sink是 可用的来发送Event。

工作原理:
将故障sink降级到一个”失败”池中,在池中为它们分配冷却期 (超时时间),在重试之前随顺序故障而增加。 Sink成功发送事件后,它将恢复到实时池。sink具有与之相关的优先级,数值越大,优先级越高。 如果在发送Event时 Sink发生故障,会继续尝试下一个具有最高优先级的sink。 例如,在优先级为80的sink之前激活优先级为100的sink。如果未指定优先级,则根据配置中的顺序来选取。
image.png
image.png

负载均衡方式

  • 负载均衡是将channel里面的Event,按照配置的负载机制(比如轮询)分别发 送到sink各自对应的目的地
  • 负载均衡Sink 选择器提供了在多个sink上进行负载均衡流量的功能。 它维护一个活 动sink列表的索引来实现负载的分配。 支持轮询( round_robin )【默认值】和随 机( random )两种选择机制分配负载。
  • 工作时,此选择器使用其配置的选择机制选择下一个sink并调用它。 如果所选sink无法正常工作,则处理器通过其配置的选择机制选择下一个可用sink。 此实现不会将 失败的Sink列入黑名单,而是继续乐观地尝试每个可用的Sink。

image.png
backoff参数:控制失败的sink是否加入黑名单,一段时间内不会调用。
负载均衡示意图:多sink模式
image.png

2.4 事务机制与可靠性

简单理解
Source 到 Channel 过程中,数据在 Flume 中会被封装成 Event 对象,也就是一 批 Event ,把这批 Event 放到一个事务中,把这个事务也就是这批event一次性的放 入Channel 中。同理,Take事务的时候,也是把这一批event组成的事务统一拿出来 到sink放到HDFS上。

2.4.1 Put事务

指的是在Source到Channel之间。

  • 事务开始的时候会调用一个 doPut 方法, doPut 方法将一批数据(batchsize)放在putList(设置大小) 中,统一发送给channel
    • 发送前,检查 Channel 的容量能否放得下,否则会doRollback
    • 设置数据批大小,batchsize
    • 设置putList的大小, Channel 的参数 transaction capacity
    • Channel 的另一个参数 capacity 指 的是 Channel 的容量(要大于putlist的大小)
  • 调用 doCommit 方法,把putList中所有 的 Event 放到 Channel 中,成功放完之后就清空putList;

    2.4.2 Take事务

    完全事务性。
    指的是Channel到Sink之间。

  • doTake方法会将channel中的event剪切到takeList中。

  • 当takeList中存放了batch size 数量的event之后,就会调用doCommit方法,
    • 针对HDFS Sink,手动调用IO流的flush方法,将IO流缓冲区的数据写入到 HDFS磁盘中;(环形缓冲区刷写机制)
    • 清空takeList中的数据

image.png

Q1:当数据flush到HDFS的时候,数据flush了一半之后出问题了,这意味着已经有 一半的数据已经发送到HDFS上面了,现在出了问题,会出现什么后果?

答:数据重复问题。同样需要调用doRollback方法 来进行回滚,回滚并没有“一半”之说,它只会把整个takeList(并被清空)中的数据返回给 channel,然后继续进行数据的读写。这样开启下一个事务的时候容易造成数据重复 的问题。
所以。Flume在数据进行采集传输的时候,有可能会造成数据的重复,但不会丢失数据

Q2:Flume在数据传输的过程中是否可靠,还需要考虑具体使用Source、Channel、Sink 的类型。

image.png