Flume
- 一、Flume基础架构
- 1.Agent
- 2.Source
- 3.Sink
- 4.Channel
- 5.Event
- 二、配置文件解析
- 三、启动指令解析
- 1.启动flume方法
- 2.指令参数说明
- 四、Flume进阶
- 1.Source 类型
- 1.inode
- 2.Taildir Source
- 3.Spooling Directory Source
- 2.Flume事务
- 五、Flume Agent内部原理
- 六、Flume 拓补结构
- 1.简短串联
- 2.复制和多路复用
- 3.负载均衡和故障转移
- 4.聚合
- 七、自定义组件
- 1.Interceptor
- 2.Source
- 3.Sink
Flume 是 Cloudera 提供(贡献给apache)的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传
输的系统。Flume 基于流式架构,灵活简单。Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS。
一、Flume基础架构
Flume 组成架构如下图所示。
1.Agent
Agent 是一个 JVM 进程,它以事件的形式将数据从源头送至目的。
Agent 主要有 3 个部分组成,Source、Channel、Sink
2.Source
Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种
格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、taildir、
sequence generator、syslog、http、legacy。
3.Sink
Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个 Flume Agent。
Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、HBase、solr、自定义
4.Channel
Channel 是位于 Source 和 Sink 之间的缓冲区。
因此,Channel 允许 Source 和 Sink 运作在不同的速率上。Channel 是线程安全的,可以同时处理几个 Source 的写入操作和几个Sink 的读取操作。
Flume 自带两种 Channel:Memory Channel 和 File Channel。Memory Channel 是内存中的队列。Memory Channel 在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么 Memory Channel 就不应该使用,因为程序死亡、机器宕机或者重启都会导致数据丢失。
File Channel 将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。
5.Event
传输单元,Flume 数据传输的基本单元,以 Event 的形式将数据从源头送至目的地。
Event 由 Header 和 Body 两部分组成,Header 用来存放该 event 的一些属性,为 K-V 结构,
Body 用来存放该条数据,形式为字节数组
二、配置文件解析
下图为使用netcat向端口44444发送信息,使用flume监听的配置文件。
Tip:在 Flume 中,Event 的 Header 中存储的时间戳是事件进入 Flume 的时间,也就是事件被 Flume Agent 接收的时间。这个时间戳是 Flume Agent 接收事件的时间,而不是该事件发生的时间。
实际生产中,如果sink端使用了根据timestample的动态写入,通常需要编写flume的interceptor拦截器,将Header中的事件改为body中事件的发生时间。
三、启动指令解析
1.启动flume方法
第一种方法:
[root@hadoop102 flume]$ bin/flume-ng agent --conf conf/ --name a1 -conf-file
job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console
第二种方法:
[root@hadoop102 flume]$ bin/flume-ng agent -c conf/ -n a1
-f job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console
2.指令参数说明
参数(/两边参数都能使用) | 说明 |
–conf/-c | 表示配置文件存储在 conf/目录 |
–name/-n | 表示给 agent 起名为 a1 |
–conf-file/-f | flume 本次启动读取的配置文件是在 job 文件夹下的 flume-telnet.conf文件 |
-Dflume.root.logger=INFO,console | -D 表示 flume 运行时动态修改 flume.root.logger参数属性值,并将控制台日志打印级别设置为 INFO 级别。日志级别包括:log、info、warn、error |
四、Flume进阶
1.Source 类型
Exec source 适用于监控一个实时追加的文件,不能实现断点续传;
Spooldir Source适合用于同步新文件,但不适合对实时追加日志的文件进行监听并同步;
Taildir Source适合用于监听多个实时追加的文件(监控目录),并且能够实现断点续传。
注:Linux 中储存文件元数据的区域就叫做 inode,每个 inode 都有一个号码,操作系统用 inode 号码来识别不同的文件,
Unix/Linux 系统内部不使用文件名,而使用 inode 号码来识别文件。
1.inode
文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。
文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。
inode包含文件的元信息,具体来说,
* 文件的字节数
* 文件拥有者的User ID
* 文件的Group ID
* 文件的读、写、执行权限
* 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
* 链接数,即有多少文件名指向这个inode
* 文件数据block的位置
2.Taildir Source
Taildir Source类型的Source通过查看文件position File中的文件信息,判断文件是否发生变动,能够通过pos字段实现文件断点续传,通过if(inode||file)这两项指标的值检查文件,这在一些以日期命名的日志文件中存在一些问题。
Taildir Source 维护了一个 json 格式的 position File,其会定期的往 position File
中更新每个文件读取到的最新的位置,因此能够实现断点续传。Position File 的格式如下:
{“inode”:2496272,“pos”:12,“file”:“/opt/module/flume/files/file1.txt”}
{“inode”:2496275,“pos”:12,“file”:“/opt/module/flume/files/file2.txt”}
比如hive日志中每一天都会新生成一个hive.log,而前一天的hive.log会加上日期后缀,文件名会更改,这样导致flume重新采集上传,出现冗余
如果采用只监控hive.log,不管后缀,不会有更名影响产生冗余,但是
inode肯定会变化,如果前一天晚上任务挂点,到了第二天看到,那么任务挂掉这段期间的数据就丢失了,因为每天新生成一个hive.log被监控,前一天的会更名,数据不会被采集了,导致数据丢失。这样一来就无法发挥出taildir断点续传的优点。
此时可以更改flume源码将只判断inode一个指标便能解决以上问题。
3.Spooling Directory Source
Spooling Directory Source将被监控上传过的文件打上.COMPLETED标签实现监听新文件,在使用 Spooling Directory Source 时,不要在监控目录中创建并持续修改文件;上传完成的文件会以.COMPLETED 结尾;被监控文件夹每 500 毫秒扫描一次文件变动。
2.Flume事务
五、Flume Agent内部原理
1)ChannelSelector
ChannelSelector 的作用就是选出 Event 将要被发往哪个 Channel。其共有两种类型,分别是 Replicating(复制)和 Multiplexing(多路复用)。
ReplicatingSelector 会将同一个 Event 发往所有的 Channel,Multiplexing 会根据相应的原则,将不同的 Event 发往不同的 Channel。
2)SinkProcessor
SinkProcessor 共 有 三 种 类 型 , 分 别 是 DefaultSinkProcessor 、LoadBalancingSinkProcessor 和 FailoverSinkProcessor
DefaultSinkProcessor 对 应 的 是 单 个 的 Sink , LoadBalancingSinkProcessor FailoverSinkProcessor 对应的是 Sink Group,LoadBalancingSinkProcessor 可以实现负载均衡的功能,FailoverSinkProcessor 可以错误恢复的功能。
六、Flume 拓补结构
1.简短串联
这种模式是将多个 flume 顺序连接起来了,从最初的 source 开始到最终 sink 传送的目的存储系统。此模式不建议桥接过多的 flume 数量, flume 数量过多不仅会影响传输速率,而且一旦传输过程中某个节点 flume 宕机,会影响整个传输系统。(适合轻量级RPC)
2.复制和多路复用
Flume 支持将事件流向一个或者多个目的地。这种模式可以将相同数据复制到多个channel 中,或者将不同数据分发到不同的 channel 中,sink 可以选择传送到不同的目的地(不推荐用Flume该结构,可使用kafka)
3.负载均衡和故障转移
Flume支持使用将多个sink逻辑上分到一个sink组,sink组配合不同的SinkProcessor
可以实现负载均衡和错误恢复的功能。
4.聚合
这种模式是我们最常见的,也非常实用,日常 web 应用通常分布在上百个服务器,大者甚至上千个、上万个服务器。产生的日志,处理起来也非常麻烦。用 flume 的这种组合方式能很好的解决这一问题,每台服务器部署一个 flume 采集日志,传送到一个集中收集日志的flume,再由此 flume 上传到 hdfs、hive、hbase 等,进行日志分析。
七、自定义组件
1.Interceptor
在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。此时会用到 Flume 拓扑结构中的 Multiplexing 结构,Multiplexing的原理是,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel中,所以我们需要自定义一个 Interceptor,为不同类型的 event 的 Header 中的 key 赋予不同的值。
a1.sources = r1
a1.channels = c1 c2 c3 c4
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = state
a1.sources.r1.selector.mapping.CZ = c1
a1.sources.r1.selector.mapping.US = c2 c3
a1.sources.r1.selector.default = c4
a1.sources.r1.interceptors = i1 i2
a1.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.HostInterceptor$Builder
a1.sources.r1.interceptors.i1.preserveExisting = false
a1.sources.r1.interceptors.i1.hostHeader = hostname
a1.sources.r1.interceptors.i2.type = org.apache.flume.interceptor.TimestampInterceptor$Builder
消息体Header中的Map<key,value>中的key为上边的state,value为CZ和US;
根据消息体中的Key决定发送到哪个resource,根据value决定发送到哪个channel;
a1.sources.r1.interceptors = i1 i2
a1.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.HostInterceptor$Builder
指定拦截器i1和i2,并通过全类名绑定,拦截器需要写jar包并构造builder方法
2.Source
Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种
格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、sequence
generator、syslog、http、legacy。官方提供的 source 类型已经很多,但是有时候并不能
满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些 source。
官方也提供了自定义 source 的接口:
https://flume.apache.org/FlumeDeveloperGuide.html#source 根据官方说明自定义
MySource 需要继承 AbstractSource 类并实现 Configurable 和 PollableSource 接口。
3.Sink
Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储
或索引系统、或者被发送到另一个 Flume Agent。
Sink 是完全事务性的。在从 Channel 批量删除数据之前,每个 Sink 用 Channel 启动一个事务。批量事件一旦成功写出到存储系统或下一个 Flume Agent,Sink 就利用 Channel 提交事务。事务一旦被提交,该 Channel 从自己的内部缓冲区删除事件。
Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、null、HBase、solr、自定义。官方提供的 Sink 类型已经很多,但是有时候并不能满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些 Sink。
官方也提供了自定义 sink 的接口:
https://flume.apache.org/FlumeDeveloperGuide.html#sink 根据官方说明自定义
MySink 需要继承 AbstractSink 类并实现 Configurable 接口。