Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS。
一、Flume 组成架构
1、Agent: Agent是一个JVM进程,它以事件的形式将数据从源头送至目的地,是Flume数据传输的基本单元。
Agent主要有3个部分组成,Source、Channel、Sink。
1.1、Source: Source是负责接收数据到Flume Agent的组件。Source组件可以处理各种类型、各种格式的日志数据,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。
1.2、Channel: Channel是位于Source和Sink之间的缓冲区。因此,Channel允许Source和Sink运作在不同的速率上。Channel是线程安全的,可以同时处理几个Source的写入操作和几个Sink的读取操作。
Flume自带两种Channel:Memory Channel
和File Channel
。
1.2.1、Memory Channel 是内存中的队列。Memory Channel在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么Memory Channel就不应该使用,因为程序死亡、机器宕机或者重启都会导致数据丢失。
1.2.1、File Channel 将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。
1.3、Sink: Sink不断地轮询Channel中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个Flume Agent。
Sink是完全事务性的。在从Channel批量删除数据之前,每个Sink用Channel启动一个事务。批量事件一旦成功写出到存储系统或下一个Flume Agent,Sink就利用Channel提交事务。事务一旦被提交,该Channel从自己的内部缓冲区删除事件。
Channel Selectors: 有两种类型Replicating Channel Selector
和Mulitpexing Channel Selector
。
Replicating Channel Selector:会将source过来的events发往所有的channel;
Mulitpexing Channel Selector:可以配置发往哪些Channel。
1.4、Event
传输单元,Flume数据传输的基本单元,以事件的形式将数据从源头送至目的地。
二、Flume 拓扑结构
三、Flume拦截器
用户Source读取events发送到Sink的时候,在events header中加入一些有用的信息,或者对events的内容进行过滤,完成初步的数据清洗。
拦截器分为:ETL拦截器和区分类型拦截器。
实现步骤:
a)实现 Interceptor;
b)重写四个方法
initialize
初始化
public Event intercept(Event event)
处理单个 Event
public List<Event> intercept(List<Event> events)
处理多个 Event,在这个方法中调用 Event intercept(Event event)
close()
方法
c)静态内部类,实现 Interceptor.Builder
四、Flume的事务机制
Flume的事务机制(类似数据库的事务机制):Flume使用两个独立的事务分别负责从Soucrce到Channel(Put 事务),以及从Channel到Sink(Take 事务)的事件传递。比如spooling directory source 为文件的每一行创建一个事件,一旦事务中所有的事件全部传递到Channel且提交成功,那么Soucrce就将该文件标记为完成。同理,事务以类似的方式处理从Channel到Sink的传递过程,如果因为某种原因使得事件无法记录,那么事务将会回滚。且所有的事件都会保持到Channel中,等待重新传递。
Flume 参数调优
- Source
增加Source个(使用Tair Dir Source时可增加FileGroups个数)可以增大Source的读取数据的能力。例如:当某一个目录产生的文件过多时需要将这个文件目录拆分成多个文件目录,同时配置好多个Source 以保证Source有足够的能力获取到新产生的数据。
batchSize参数决定Source一次批量运输到Channel的event条数,适当调大这个参数可以提高Source搬运Event到Channel时的性能。
- Channel
type 选择memory时Channel的性能最好,但是如果Flume进程意外挂掉可能会丢失数据。type选择file时Channel的容错性更好,但是性能上会比memory channel差。
使用file Channel时dataDirs配置多个不同盘下的目录可以提高性能。
Capacity 参数决定Channel可容纳最大的event条数。transactionCapacity 参数决定每次Source往channel里面写的最大event条数和每次Sink从channel里面读的最大event条数。transactionCapacity需要大于Source和Sink的batchSize参数。
- Sink
增加Sink的个数可以增加Sink消费event的能力。Sink也不是越多越好够用就行,过多的Sink会占用系统资源,造成系统资源不必要的浪费。
batchSize参数决定Sink一次批量从Channel读取的event条数,适当调大这个参数可以提高Sink从Channel搬出event的性能。
HDFS Sink小文件过多
(1)HDFS 存入大量小文件,有什么影响?
元数据层面:每个小文件都有一份元数据,其中包括文件路径,文件名,所有者,所属
组,权限,创建时间等,这些信息都保存在 Namenode 内存中。所以小文件过多,会占用
Namenode 服务器大量内存,影响 Namenode 性能和使用寿命
计算层面:默认情况下 MR 会对每个小文件启用一个 Map 任务计算,非常影响计算性
能。同时也影响磁盘寻址时间。
(2)HDFS 小文件处理
官方默认的这三个参数配置写入 HDFS 后会产生小文件,hdfs.rollInterval
、hdfs.rollSize
、hdfs.rollCount
基于以上 hdfs.rollInterval=3600 , hdfs.rollSize=134217728 , hdfs.rollCount =0 ,
hdfs.roundValue=3600,hdfs.roundUnit= second 几个参数综合作用,效果如下:
(1)tmp 文件在达到 128M 时会滚动生成正式文件
(2)tmp 文件创建超 3600 秒时会滚动生成正式文件
举例:在 2018-01-01 05:23 的时侯 sink 接收到数据,那会产生如下 tmp 文件:/atguigu/20180101/atguigu.201801010520.tmp
即使文件内容没有达到 128M,也会在 06:23 时滚动生成正式文件