一、Flume 是什么
1.1 定义
Flume 是 Cloudera 提供的一个 高可用、高可靠,分布式 的 海量日志采集、聚合和传输的系统。Flume 基于流式架构。
1.2 为什么要用 Flume
因为传统上使用 hdfs 的 put 把数据从本地传到 hdfs 这种方式实时性太差,而 flume 可以实现实时监控某个文件、文件夹或端口。
二、Flume 的原理
2.1 架构图
Agent:
Agent 是一个 JVM 进程,它以事件的形式把数据从源头发送至目的地。
Event:
Event 是 Flume 的数据传输的基本单元,其组成是 <K,V> 形式,K 是 header,V 是 body。
Put事务:
doPut:把批数据写道 putList 中
doCommit:检查 channel 内存队列是否足够合并
doRollback channel:channel 内存队列空间不足,回滚数据
Take 事务:
doTake:把数据抓取到缓冲区 takeList
doCommit:如果数据全部写入成功,则清楚临时缓冲区 takeList
doRollback:数据发送过程中如果出现异常,roolback 把缓冲区 takeList 中的数据归还给 channel 内存队列
2.2 三大组件
Source:
Source 是负责接收数据到 Flume Agent 的组件。Source 可以处理各种类型、各种格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、tailDir、netcat 等。
exec:在启动时执行给定的 Unix 命令,并且期望该进程在标准输出上产生数据(stderr 默认不输出,除非把 logStdErr 设置成 true)。
tailDir:实时监听数据,并且通过一个 position 文件记录每次读到的位置来实现不丢失数据的功能
spooling directory:监听指定文件夹中是否添加新文件,如果添加进去文件则会在新文件后面加一个后缀名来标识,然后如果该文件在改动的话,则会被忽略,所以不能往改文件夹里放同名文件。
Channel:
Channel 是位于 Source 和 Sink 之间的缓冲区,因为接收数据源的速度可能和写出数据的速度不一致,所以加了 Channl 作为缓冲区。
Channel 有两种类型,一种是 file channel,一种是 memory channel,file channel 速度慢但安全,memory channel 速度快但不安全。
Sink:
Sink 不断轮询 Channel 中的事件并且批量地移除它们,并将这些事件批量写写入到目的地。
Sink 是完全事务性的。在从 Channel 批量删除事务之前,每个 Sink 用 Channel 启动一个事务。批量事件一旦成功写入到目的地,Sink 就利用 Channel 提交一个事务,事务一旦被提交,Channel 从自己的内部缓冲区删除事件。
2.3 Flume 拓扑
注意:没有一个 sink 接收多个 channel 的,因为这样会乱掉。
1、(Flume 到 Flume)的串联结构(其它拓扑的基础):
2、一个 Source 对应多个 Channel(这个地方可以有两种实现方式,副本机制和多路选择机制)
3、一个 Channel 对应多个 Sink (负载均衡或故障转移):
4、一个 Source 对应多个 Sink(聚合):
2.5 Agent 内部原理
三、Flume 进阶
3.1 故障转移
Flume 故障转移的策略是:比如一个 Channel 连接了多个 Sink,这几个 Sink 一开始会有一个优先级,比如说 k1: 10,k2:5,k3:1,一开始 Channel 会把数据写到 k1 里,如果 k1 宕机了,那么会往 c2 里写;配置故障转移的时候还有一个参数是 maxPenalty(默认是 30 秒),如果在写入 k2 的过程中 k1 又恢复了,但是如果是在 30 秒内回复的,那么则依然往 k2 里写,在 30 秒之后再往 k1 里写。
3.2 自定义拦截器
3.3 自定义 Source
3.4 自定义 Sink