第一章 Flume概念
1.1 Flume定义
- Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。
- Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS
1.2 Flume架构
- Agent:Agent是一个JVM进程,它以事件的形式将数据从源头送至目的,主要有3个部分组成,Source、Channel、Sink。
- Source:负责接收数据到Flume Agent的组件。Source组件可以处理各种类型、各种格式的日志数据,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。
- Sink:Sink不断地轮询Channel中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个Flume Agent。Sink组件目的地包括hdfs、logger、avro、thrift、ipc、file、HBase、solr、自定义。
- Channel:Channel是位于Source和Sink之间的缓冲区。因此,Channel允许Source和Sink运作在不同的速率上。Channel是线程安全的,可以同时处理几个Source的写入操作和几个Sink的读取操作。Flume自带两种Channel:Memory Channel和File Channel。
- Memory Channel是内存中的队列。Memory Channel在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么Memory Channel就不应该使用,因为程序死亡、机器宕机或者重启都会导致数据丢失。
- File Channel将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。
- Evnet:传输单元,Flume数据传输的基本单元,以Event的形式将数据从源头送至目的地。Event由Header和Body两部分组成,Header用来存放该event的一些属性,为K-V结构,Body用来存放该条数据,形式为字节数组。
- interceptors:在Flume中允许使用拦截器对传输中的event进行拦截和处理!拦截器必须实现org.apache.flume.interceptor.Interceptor接口。拦截器可以根据开发者的设定修改甚至删除event!Flume同时支持拦截器链,即由多个拦截器组合而成,通过指定拦截器链中拦截器的顺序,event将按照顺序依次被拦截器进行处理。
- Channel Selectors:Channel Selectors用于source组件将event传输给多个channel的场景。常用的有replicating(默认)和multiplexing两种类型。replicating负责将event复制到多个channel,而multiplexing则根据event的属性和配置的参数进行匹配,匹配成功则发送到指定的channel。
- Sink Processors:用户可以将多个sink组成一个整体(sink组),Sink Processors可用于提供组内的所有sink的负载平衡功能,或在时间故障的情况下实现从一个sink到另一个sink的故障转移。
第二章 Flume快速入门
2.1 Flume安装
- 保证有JAVA_HOME
- 解压apache-flume-1.7.0-bin.tar.gz到对应目录下
- 将目录配置到环境变量中方便使用
export FLUME_HOME=/opt/software/flume
export PATH=$FLUME_HOME/bin:$PATH
2.2 使用Flume
- 启动agent
flume-ng agent -n agent的名称 -f agent配置文件 -c 其他配置文件所在的目录 -Dproperty=value
2.3 编写agent的配置文件
- agent的配置文件的本质是一个Properties文件,格式为 属性名=属性值
- 在配置文件中需要编写:
- 定义当前配置文件中agent的名称,再定义source,sink,channel它们的别名
- 指定source和channel和sink等组件的类型
- 指定source和channel和sink等组件的配置,配置参数名和值都需要参考flume到官方用户手册
- 指定source和channel的对应关系,以及sink和channel的对应关系。连接组件!
2.4 入门案例一
- 需求:使用Flume监听一个端口,收集该端口数据,并打印到控制台
- 需求分析
- 通过netcat工具向本机的44444端口发送数据(端口可以随意指定,后面配置文件中也要改)
- Flume监控本机的44444端口,通过Flume的source端读取数据
- Flume将获取的数据通过Sink端写到控制台
#a1是agent的名称,a1中定义了一个叫r1的source,如果有多个,使用空格间隔
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#组名名.属性名=属性值
a1.sources.r1.type=netcat
a1.sources.r1.bind=master
a1.sources.r1.port=44444
#定义sink
a1.sinks.k1.type=logger
a1.sinks.k1.maxBytesToLog=100
#定义chanel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
#连接组件 同一个source可以对接多个channel,一个sink只能从一个channel拿数据!
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1
- 使用的组件类型
- netcat source:作用就是监听某个tcp端口手动的数据,将每行数据封装为一个event。工作原理类似于nc -l 端口
- 配置:
必须属性:
type – The component type name, needs to be netcat
bind – Host name or IP address to bind to
port – Port # to bind to
- logger sink:使用logger(日志输出器)将event输出到文件或控制台,使用info级别记录event。
- 配置:
必须属性:
type – The component type name, needs to be logger
可选属性:
maxBytesToLog 16 Maximum number of bytes of the Event body to log
- memery channel:
- 配置
必须属性:
type – The component type name, needs to be memory
可选属性:
capacity 100 The maximum number of events stored in the channel
transactionCapacity 100 The maximum number of events the channel will take from a source or give to a sink per transaction
2.5 入门案例二
- 需求:实时监控hive日志,并上传到HDFS中
- 需求分析:
- Hive实时更新日志,Hive日志文件HIVE_HOME/logs/hive.log
- Flume监控文件
- 写入到HDFS
#a1是agent的名称,a1中定义了一个叫r1的source,如果有多个,使用空格间隔
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#组名名.属性名=属性值
a1.sources.r1.type=netcat
a1.sources.r1.bind=master
a1.sources.r1.port=44444
#定义sink
a1.sinks.k1.type=logger
a1.sinks.k1.maxBytesToLog=100
#定义chanel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
#连接组件 同一个source可以对接多个channel,一个sink只能从一个channel拿数据!
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1
[hadoop@master myagents]$ cat execsource-hdfssink.conf
#a1是agent的名称,a1中定义了一个叫r1的source,如果有多个,使用空格间隔
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#组名名.属性名=属性值
a1.sources.r1.type=exec
a1.sources.r1.command=tail -f /opt/software/apache-hive-1.2.1-bin/logs/hive.log
#定义chanel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
#定义sink
a1.sinks.k1.type = hdfs
#一旦路径中含有基于时间的转义序列,要求event的header中必须有timestamp=时间戳,如果没有需要将useLocalTimeStamp = true
a1.sinks.k1.hdfs.path = hdfs://master:9000/flume/%Y%m%d/%H/%M
#上传文件的前缀
a1.sinks.k1.hdfs.filePrefix = logs-
#以下三个和目录的滚动相关,目录一旦设置了时间转义序列,基于时间戳滚动
#是否将时间戳向下舍
a1.sinks.k1.hdfs.round = true
#多少时间单位创建一个新的文件夹
a1.sinks.k1.hdfs.roundValue = 1
#重新定义时间单位
a1.sinks.k1.hdfs.roundUnit = minute
#是否使用本地时间戳
a1.sinks.k1.hdfs.useLocalTimeStamp = true
#积攒多少个Event才flush到HDFS一次
a1.sinks.k1.hdfs.batchSize = 100
#以下三个和文件的滚动相关,以下三个参数是或的关系!以下三个参数如果值为0都代表禁用!
#60秒滚动生成一个新的文件
a1.sinks.k1.hdfs.rollInterval = 10
#设置每个文件到128M时滚动
a1.sinks.k1.hdfs.rollSize = 134217700
#每写多少个event滚动一次
a1.sinks.k1.hdfs.rollCount = 0
#连接组件 同一个source可以对接多个channel,一个sink只能从一个channel拿数据!
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1
- 使用组件类型
- EXECSource:execsource会在agent启动时,运行一个linux命令,运行linux命令的进程要求是一个可以持续产生数据的进程。将标准输出的数据封装为event,通常情况下,如果指定的命令退出了,那么source也会退出并且不会再封装任何的数据,所以使用这个source一般推荐类似cat ,tail -f 这种命令,而不是date这种只会返回一个数据,并且执行完就退出的命令。
- Execsouce的缺点
- execsource和异步的source一样,无法在source向channel中放入event故障时,及时通知客户端,暂停生成数据,容易造成数据丢失。
- 解决方案: 需要在发生故障时,及时通知客户端。如果客户端无法暂停,必须有一个数据的缓存机制。如果希望数据有强的可靠性保证,可以考虑使用SpoolingDirSource或TailDirSource或自己写Source自己控制。
- 配置:
必须配置:
type – The component type name, needs to be exec
command – The command to execute
- HDFSSink:hdfssink将event写入到HDFS,目前只支持生成两种类型的文件: text | sequenceFile,这两种文件都可以使用压缩,写入到HDFS的文件可以自动滚动(关闭当前正在写的文件,创建一个新文件)。基于时间、events的数量、数据大小进行周期性的滚动。支持基于时间和采集数据的机器进行分桶和分区操作,HDFS数据所上传的目录或文件名可以包含一个格式化的转义序列,这个路径或文件名会在上传event时,被自动替换,替换为完整的路径名,使用此Sink要求本机已经安装了hadoop,或持有hadoop的jar包。
- 配置:
必须配置:
type – The component type name, needs to be hdfs
hdfs.path – HDFS directory path (eg hdfs://namenode/flume/webdata/)