Flume介绍
1、概述
- Flume最早是Cloudera提供的日志收集系统,后贡献给Apache
- Flume是一个高可用的,高可靠的 、健壮性,分布式的海量日志采集、聚合和传输的系统
- Flume支持在日志系统中定制各类数据发送方,用于收集数据(source)
- Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力(sink)。
2、版本
- Flume0.9X:又称Flume-og,老版本的flume,需要引入zookeeper集群管理,性能也较低(单线程工作)
- Flume1.X:又称Flume-ng。新版本需要引入zookeeper,和flume-og不兼容
3、Flume的特性
- 可靠性:事务型的数据传递,保证数据的可靠性。一个日志交给flume来处理,不会出现此日志丢失或未被处理的情况
- 可恢复性:通道可以以内存或文件的方式实现,内存更快,但不可恢复。文件较慢但提供了可恢复性
4、event事件
一、Flume总体架构图
二、event 事件
- event的相关概念:Flume的核心是把数据从数据源(source)收集过来,在将收集到的数据送到指定的目的地(sink)。为了保证输送的过程一定成功,在送到目的地(sink)之前,会先缓存数据(channel),待数据真正到达目的地(sink)后,flume在删除自己缓存的数据。
- 在整个数据的传输的过程中,流动的是event,即事务保证是在event级别进行的。event将传输的数据进行封装,是flume传输数据的基本单位,如果是文本文件,通常是一行记录,event也是事务的基本单位。event从source,流向channel,再到sink,本身为一个字节数组,并可携带headers(头信息)信息。event代表着一个数据的最小完整单元,从外部数据源来,向外部的目的地去。简而言之,在Flume中,每一条日志就会封装成一个event对象
- 一个完整的event包括:event headers、event body、event信息(即文本文件中的单行记录),如下所以:
其中event信息就是flume收集到的日记记录。
三、Flume的运行机制
- flume运行的核心就是agent,agent本身是一个Java进程
- agent里面包含3个核心的组件:source—>channel—>sink,类似生产者、仓库、消费者的架构
- source:source组件是专门用来收集数据的,可以处理各种类型、各种格式的日志数据,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy、自定义等
- channel:source组件把数据收集来以后,临时存放在channel中,即channel组件在agent中是专门用来存放临时数据的——对采集到的数据进行简单的缓存,可以存放在memory、jdbc、file等等
- sink:sink组件是用于把数据发送到目的地的组件,目的地包括hdfs、logger、avro、thrift、ipc、file、null、hbase、solr、自定义。
- 一个完整的工作流程:source不断的接收数据,将数据封装成一个一个的event,然后将event发送给channel,chanel作为一个缓冲区会临时存放这些event数据,随后sink会将channel中的event数据发送到指定的地方—-例如HDFS等
- 注:只有在sink将channel中的数据成功发送出去之后,channel才会将临时event数据进行删除,这种机制保证了数据传输的可靠性与安全性。
四、Flume的复杂流动
多个agent的数据流(多级流动)
数据流合并(扇入流)
在做日志收集的时候一个常见的场景就是,大量的生产日志的客户端发送数据到少量的附属于存储子系统的消费者agent。例如,从数百个web服务器中收集日志,它们发送数据到十几个负责将数据写入HDFS集群的agent。
这个可在Flume中可以实现,需要配置大量第一层的agent,每一个agent都有一个avro sink,让它们都指向同一个agent的avro source(强调一下,在这样一个场景下你也可以使用thrift source/sink/client)。在第二层agent上的source将收到的event合并到一个channel中,event被一个sink消费到它的最终的目的地。
数据流复用(扇出流)
Flume支持多路输出event流到一个或多个目的地。这是靠定义一个多路数据流实现的,它可以实现复制和选择性路由一个event到一个或者多个channel。
上面的例子展示了agent foo中source扇出数据流到三个不同的channel,这个扇出可以是复制或者多路输出。在复制数据流的情况下,每一个event被发送所有的三个channel;在多路输出的情况下,一个event被发送到一部分可用的channel中,它们是根据event的属性和预先配置的值选择channel的。 这些映射关系应该被填写在agent的配置文件中。
一、安装步骤
此处还是用之前搭建的虚拟机进行安装
1. 安装JDK1.6以上,建议JDK1.7或者JDK1.8
2. 下载/上传flume的安装包
3. 解压安装
tar -xvf apache-flume-1.6.0-bin.tar.gz
4. 在conf目录下,创建一个配置文件,比如:template.conf(名字可以不固定,后缀也可以不固定),添加如下配置:
复制粘贴即可,先测试一下,一会详解配置属性含义
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
5. 进入flume的bin目录执行: ./flume-ng agent -n a1 -c …/conf -f …/conf/template.conf -Dflume.root.logger=INFO,console
6. 新打开一个窗口通过nc来访问:
输入nc如果是这样的话
这是没有安装nc,需要安装一下
yum install -y nc
下面开始测试一下flume
nc localhost 44444
hello
nihao
123456789
通过nc请求flume已经返回OK
看一下之前启动flume的窗口,已经收到了
或者通过外部http请求访问对应的ip和端口,比如:http://192.168.199.11:44444/123123
在虚拟机这边,会出现如下提示:
二、启动命令
参数 描述
agent 运行一个Flume Agent
–conf,-c 指定配置文件放在什么目录
–conf-file,-f 指定配置文件,这个配置文件必须在全局选项的–conf参数定义的目录下
–name,-n Agent的名称,注意:要和配置文件里的名字一致。
-Dproperty=value 设置一个JAVA系统属性值。常见的:-Dflume.root.logger=INFO,console
参数 | 描述 |
---|---|
agent | 运行一个Flume Agent |
–conf,-c | 指定配置文件放在什么目录 |
–conf-file,-f | 指定配置文件,这个配置文件必须在全局选项的–conf参数定义的目录下 |
–name,-n | Agent的名称,注意:要和配置文件里的名字一致。 |
-Dproperty=value | 设置一个JAVA系统属性值。常见的:-Dflume.root.logger=INFO,console |
示例:./flume-ng agent -n a1 -c …/conf -f …/conf/template.conf -Dflume.root.logger=INFO,console
通过以上的介绍我们知道有三个重要组件分别为source、channel、sink以下先详解每一个组件,在结合组件做实例
一、source 详解总共6个
1、Avro Source详解(使用率极高)
一、概述
- 监听Avro 端口来接收外部avro客户端的事件流
- avro-source接收到的是经过avro序列化后的数据,然后反序列化数据继续传输。
- 源数据必须是经过avro序列化后的数据
- 利用Avro source可以实现多级流动、扇出流、扇入流等效果
- 可以接收通过flume提供的avro客户端发送的日志信息
二、可配选项说明
配置项 | 说明 |
---|---|
channels | 绑定通道 |
type | avro |
bind | 需要监听的主机名或IP |
port | 要监听的端口 |
threads | 工作线程最大线程数 |
selector.* | 选择器配置 |
interceptors.* | 拦截器配置 |
三、简单示例
- 在conf文件夹下新建配置文件:avrosource.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 执行启动指令,如果出现如下提示,证明启动成功
./flume-ng agent -n a1 -c ../conf -f ../conf/avrosource.conf -Dflume.root.logger=INFO,console
4. 在flume根目录创建mydata文件夹,在mydata内创建1.txt,写一个Hello然后保存退出
6. 在bin目录执行agent-avro客户端指令:./flume-ng avro-client -H 0.0.0.0 -p 44444 -F …/mydata/1.txt -c …/conf/
可以看到文件内的hello反序列化到Flume中
2、Exec Source详解(使用率中)
一、概述
- 可以将命令产生的输出作为源来进行传递,例如捕获ping命令
二、可配置选项说明
配置项 | 说明 |
---|---|
channels | 绑定的通道 |
type | exec |
command | 要执行的命令 |
selector.* | 选择器配置 |
interceptors.* | 拦截器列表配置 |
三、示例:
- 在conf文件夹下新建配置文件:execsource.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=exec
a1.sources.r1.command=ping www.baidu.com
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
-
进入到bin目录执行指令:./flume-ng agent --conf …/conf --conf-file …/conf/execsource.conf --name a1 -Dflume.root.logger=INFO,console
-
结果为ping 百度返回的结果
3、Spooling Directory Source详解(使用率高)
一、概述
- flume会持续监听指定的目录,把放入这个目录中的文件当做source来处理
- 注意:一旦文件被放到“自动收集”目录中后,便不能修改,如果修改,flume会报错
- 此外,也不能有重名的文件,如果有,flume也会报错。
二、可配置选项说明
配置项 | 说明 |
---|---|
channels | 绑定通道 |
type | spooldir |
spoolDir | 读取文件的路径,即"搜集目录" |
selector.* | 选择器配置 |
interceptors.* | 拦截器配置 |
三、示例
- 在conf文件夹下新建配置文件:spodire.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=spooldir
a1.sources.r1.spoolDir=/home/data
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 在home下创建data文件夹
- 根据指定的配置文件,启动flume
./flume-ng agent --conf ../conf --conf-file ../conf/spodire.conf --name a1 -Dflume.root.logger=INFO,console
- 向指定的文件目录下传送一个日志文件,发现flume的控制台打印相关的信息。此外,会发现被处理的文件,会追加一个后缀:completed,表示已处理完。
我们刚刚有创建一个1.txt。所以直接复制过去即可
cp /home/software/apache-flume-1.6.0-bin/mydata/1.txt data/
4、NetCat Source详解(使用率高)
一、概述
1. 一个NetCat Source用来监听一个指定端口,并接收监听到的数据
2. 接收的数据是字符串形式
二、可配置选项说明
配置项 | 说明 |
---|---|
channels | 绑定通道 |
type | netcat |
port | 指定要绑定到的端口号 |
selector.* | 选择器配置 |
interceptors.* | 拦截器配置 |
三、示例
- 在conf文件夹下新建配置文件:netcat.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 进入flume的bin目录执行:
./flume-ng agent --conf ../conf --conf-file ../conf/netcat.conf --name a1 -Dflume.root.logger=INFO,console
- 通过nc来访问
nc localhost 44444
hello
5、Squence Generator Source详解(使用率低)
一、概述
- 一个简单的序列发生器,不断的产生事件,值是从0开始每次递增1
- 主要用来测试
二、可配置选项说明
配置项 | 说明 |
---|---|
channels | 绑定的通道 |
type | seq |
selector.* | 选择器配置 |
interceptors.* | 拦截器配置 |
batchSize | 递增步长, 默认是1 |
三、示例
- 在conf文件夹下新建配置文件:squence.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=seq
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3.启动flume
./flume-ng agent --conf ../conf --conf-file ../conf/squence.conf --name a1 -Dflume.root.logger=INFO,console
可以直接看到
6、HTTP Source详解(使用率高)
一、概述
- 此Source接受HTTP的GET和POST请求作为Flume的事件
- GET方式只用于试验,所以实际使用过程中以POST请求居多
- 如果想让flume正确解析Http协议信息,比如解析出请求头、请求体等信息,需要提供一个可插拔的"处理器"来将请求转换为事件对象,这个处理器必须实现HTTPSourceHandler接口。
- 这个处理器接受一个 HttpServletRequest对象,并返回一个Flume Envent对象集合。
二、常用Handler
JSONHandler
1. 可以处理JSON格式的数据,并支持UTF-8 UTF-16 UTF-32字符集
2. 该handler接受Event数组,并根据请求头中指定的编码将其转换为Flume Event
3. 如果没有指定编码,默认编码为UTF-8
4. 格式:
[
{
“headers” : {
“timestamp” : “434324343”,
“host” : “random_host.example.com”
}
“body” : “random_body”
},
{
“headers” : {
“namenode” : “namenode.example.com”,
“datanode” : “random_datanode.example.com”
},
“body” : “really_random_body”
}
]
BlobHandler
1. BlobHandler是一种将请求中上传文件信息转化为event的处理器
2. BlobHandler适合大文件的传输
三、可配置选项说明
配置项 | 说明 |
---|---|
channels | 绑定的通道 |
type | http |
selector.* | 选择器配置 |
interceptors.* | 拦截器配置 |
port | 端口 |
四、示例:
- 在conf文件夹下新建配置文件:httpsource.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 执行启动命令
./flume-ng agent --conf ../conf --conf-file ../conf/httpsource.conf --name a1 -Dflume.root.logger=INFO,console
- 执行curl 命令,模拟一次http的Post请求:curl -X POST -d ‘[{“headers”:{“a”:“a1”,“b”:“b1”},“body”:“hello flume”}]’ http://0.0.0.0:8888
一、channel详解
1、Memory Channel(使用率极高)
一、概述
1. 事件将被存储在内存中(指定大小的队列里)
2. 非常适合那些需要高吞吐量且允许数据丢失的场景下
二、可配置选项说明
配置项 | 说明 |
---|---|
type | memory |
capacity | 100 事件存储在信道中的最大数量建议实际工作调节:10万首先估算出每个event的大小,然后再服务的内存来调节 |
transactionCapacity | 100 每个事务中的最大事件数建议实际工作调节:1000~3000 |
三、上面的示例一直使用的都是memory所以此处不再演示
2、File Channel(使用率低)
一、概述
- 将数据临时存储到计算机的磁盘的文件中
- 性能比较低,但是即使程序出错数据不会丢失
二、可配置选项说明
配置项 | 说明 |
---|---|
type | file |
dataDirs | 指定存放的目录,逗号分隔的目录列表,用以存放日志文件。使用单独的磁盘上的多个目录可以提高文件通道效率。 |
三、示例
- 在conf文件夹下新建配置文件:filechannel.conf
- 添加如下内容:
a1.sources=r1
a1.channels=c1
a1.sinks=s1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
a1.sinks.s1.type=logger
a1.channels.c1.type=file
a1.channels.c1.dataDirs=/home/filechannel
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3可以在/home/filechannel下看到文件
使用nc发送数据,可以看到文件大小的变化
3、JDBC Channel
- 事件会被持久化(存储)到可靠的数据库里
- 目前只支持嵌入式Derby数据库。但是Derby数据库不太好用,所以JDBC Channel目前仅用于测试,不能用于生产环境。
4、内存溢出 Channel
- 优先把Event存到内存中,如果存不下,在溢出到文件中
- 目前处于测试阶段,还未能用于生产环境
一、sink详解
1、Logger Sink
一、概述
- 记录指定级别(比如INFO,DEBUG,ERROR等)的日志,通常用于调试
- 要求,在 --conf(-c )参数指定的目录下有log4j的配置文件
- 根据设计,logger sink将body内容限制为16字节,从而避免屏幕充斥着过多的内容。如果想要查看调试的完整内容,那么你应该使用其他的sink,也许可以使用file_roll sink,它会将日志写到本地文件系统中。
二、可配置项说明
配置项 | 说明 |
---|---|
channel | 绑定通道 |
type | logger |
三、示例
这里就不过多叙述了。上门的示例都是使用的logger
#配置Agent a1 的组件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
2、File_roll Sink
一、概述
1. 在本地系统中存储事件
2. 每隔指定时长生成文件保存这段时间内收集到的日志信息
二、可配置选项说明
配置项 | 说明 |
---|---|
channel | 绑定通道 |
type | file_roll |
sink.directory | 文件被存储的目录 |
sink.rollInterval | 30 记录日志到文件里,每隔30秒生成一个新日志文件。如果设置为0,则禁止滚动,从而导致所有数据被写入到一个文件中。 |
三、示例
- 在conf文件夹下新建配置文件:file.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=file_roll
a1.sinks.s1.sink.directory=/home/rolldata
a1.sinks.s1.sink.rollInterval=60
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 创建指定的文件目录 /home/rolldata
- 启动测试
./flume-ng agent --conf ../conf --conf-file ../conf/file.conf --name a1 -Dflume.root.logger=INFO,console
然后用nc命令发送数据到Flume,在/home/rolldata 下可以看到生成的文件。编辑文件可以看到具体的内容
3、HDFS Sink
一、概述
- 此Sink将事件写入到Hadoop分布式文件系统HDFS中
- 目前它支持创建文本文件和序列化文件,并且对这两种格式都支持压缩
- 这些文件可以分卷,按照指定的时间或数据量或事件的数量为基础
- 它还通过类似时间戳或机器属性对数据进行 buckets/partitions 操作
- HDFS的目录路径可以包含将要由HDFS替换格式的转移序列用以生成存储事件的目录/文件名
- 使用这个Sink要求haddop必须已经安装好,以便Flume可以通过hadoop提供的jar包与HDFS进行通信
二、可配置选项说明
配置项 | 说明 |
---|---|
channel | 绑定的通道 |
type | hdfs |
hdfs.path | HDFS 目录路径 (hdfs://namenode/flume/webdata/) |
hdfs.inUseSuffix .tmp | Flume正在处理的文件所加的后缀 |
hdfs.rollInterval | 文件生成的间隔事件,默认是30,单位是秒 |
hdfs.rollSize | 生成的文件大小,默认是1024个字节 ,0表示不开启此项 |
hdfs.rollCount | 每写几条数据就生成一个新文件,默认数量为10每写几条数据就生成一个新文件, |
hdfs.fileType | SequenceFile/DataStream/CompressedStream 文件格式,默认值:SequenceFile。当使用DataStream时候,文件不会被压缩,不需要设置hdfs.codeC;当使用CompressedStream时候,必须设置一个正确的hdfs.codeC值; |
hdfs.retryInterval | 80 Time in seconds between consecutive attempts to close a file. Each close call costs multiple RPCround-trips to the Namenode, so setting this too low can cause a lot of load on the name node. If set to 0 or less, the sink will not attempt to close the file if the first attempt fails, and may leave the file open or with a ”.tmp” extension. 关闭文件的时间间隔 |
.
三、示例
- 在conf文件夹下新建配置文件:hdfs.conf
- 添加如下内容:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://test1:9000/flume
a1.sinks.s1.hdfs.fileType=DataStream
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3.启动测试
./flume-ng agent --conf ../conf --conf-file ../conf/hdfs.conf --name a1 -Dflume.root.logger=INFO,console
注意。这里因为我之前的文章介绍过安装hadoop。所以此处不在表述。我hadoop配置的是hdfs://test1:9000 如果你和我不一样请按照你的填写
使用nc进行测试,可以看到。自动创建了flume路径,并把内容存储到了hdfs上
四、存在问题
- 报错是因为flume缺少相关hadoop的依赖jar包,找到以下的jar包,放到flume的lib目录下即可。
commons-configuration-1.6.jar
hadoop-auth-2.5.2.jar
hadoop-common-2.5.2.jar
hadoop-hdfs-2.5.2.jar
hadoop-mapreduce-client-core-2.5.2.jar
但是一个一个找特别麻烦,所以解决办法是将hadoop的jar包都拷贝到flume的lib目录下:执行:scp common/* common/lib/* hdfs/* hdfs/lib/* mapreduce/* mapreduce/lib/* tools/lib/* 192.168.199.11:/home/software/apache-flume-1.6.0-bin/lib/
如果还是不行,请查看具体的错误进行解决
4、Avro Sink
一、概述
- 将源数据进行利用avro进行序列化之后写到指定的节点上
- 是实现多级流动、扇出流(1到多) 扇入流(多到1) 的基础。
二、可配置选项说明
配置项 | 说明 |
---|---|
channel | 绑定的通道 |
type | avro |
hostname | 要发送的主机 |
port | 要发往的端口号 |
三、多级流动
概述
- 让01机的flume通过netcat source源接收数据,然后通过avro sink 发给02机
- 02机的flume利用avro source源收数据,然后通过avro sink 传给03机
- 03机通过avro source源收数据,通过logger sink 输出到控制台上
实现步骤 - 准备三个节点,并安装好flume(关闭每台机器的防火墙)
- 复制flume到另外两台机器上,在另外两台机器上执行下面的命令
scp远程复制,-r递归复制整个目录,使用root用户从192.168.199.11上覆制/home/software/apache-flume-1.6.0-bin到本地的/home/software/
scp -r [email protected]:/home/software/apache-flume-1.6.0-bin /home/software/
- 配置每台flume的配置文件,我这里统一使用avros.conf
01机的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
02机的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.13
a1.sinks.s1.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
03机的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 启动测试
启动顺序为03》02》01,启动后可以分别在03和02上看到有连接进来
./flume-ng agent --conf ../conf --conf-file ../conf/avros.conf --name a1 -Dflume.root.logger=INFO,console
因为01是源头。所以没有连接进来。我们开始在01上使用nc发送数据进行测试
在03上已经收到数据,完成多级流动了
四、扇出流
从01分别发送到02、03上面
创建配置文件:outdata.conf
01机的配置文件
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
02,03配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
启动测试,先启动02、03、在启动01.可以看到02、03有连接进来
./flume-ng agent --conf ../conf --conf-file ../conf/outdata.conf --name a1 -Dflume.root.logger=INFO,console
使用nc测试,可以看到数据被发送到了02和03.
五、扇入流
从02、03发送到01上面
创建配置文件:indata.conf
02,03的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.11
a1.sinks.s1.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
01机的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
先启动01.在启动02、03可以在01看到
有两个连接进来。现在分别在02和03发送数据可以到01了
扇入流完成
复制模式
一、概述
- Selector 默认是复制模式(replicating),即把source复制,然后分发给多个sink
二、 可配置选项说明
配置项 | 说明 |
---|---|
selector.type | replicating 表示复制模式,source的selector如果不配置,默认就是这种模式在复制模式下,当source接收到数据后,会复制多分,分发给每一个avro sink |
selector.optional | 标志通道为可选,可选写入失败会被忽略。 |
三、示例
a1.sources = r1
a1.channels = c1 c2 c3
a1.source.r1.selector.type = replicating(这个是默认的)
a1.source.r1.channels = c1 c2 c3
#c3是可选的,向c3写入失败会被忽略。但是向c1,c2写入失败会出错
a1.source.r1.selector.optional = c3
和扇出是一样的。所以此处不再写具体示例
多路复用模式
一、概述
- 在这种模式下,用户可以指定转发的规则。selector根据规则进行数据的分发
二、可配置选项说明
配置项 | 说明 |
---|---|
selector.type | multiplexing 表示路由模式 |
selector.header | 指定要监测的头的名称 |
selector.mapping.* | 匹配规则 |
selector.default | 如果未满足匹配规则,则默认发往指定的通道 |
三、示例
01机利用http source接收数据,根据路由规则,发往02,03机。02,03通过avro source接收数据,通过logger sink 打印数据
创建配置文件:selector.conf
01机配置示例
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.selector.type=multiplexing
a1.sources.r1.selector.header=state
a1.sources.r1.selector.mapping.cn=c1
a1.sources.r1.selector.mapping.us=c2
a1.sources.r1.selector.default=c2
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
2. 02,03配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
接下来开始测试
分别在01机器上输入
curl -X POST -d '[{"headers":{"state":"us","b":"b1"},"body":"hello us"}]' http://localhost:8888
curl -X POST -d '[{"headers":{"state":"cn","b":"b1"},"body":"hello cn"}]' http://localhost:8888
curl -X POST -d '[{"headers":{"state":"11111111","b":"b1"},"body":"hello 11111111"}]' http://localhost:8888
02收到
03收到,因为03配置了default=c2,所以默认数据是往这里发送的
Interceptor 拦截器
Timestamp Interceptor
一、概述
- 这个拦截器在事件头中插入以毫秒为单位的当前处理时间
- 头的名字为timestamp,值为当前处理的时间戳
- 如果在之前已经有这个时间戳,则保留原有的时间戳
二、可配置项说明
配置项 | 说明 |
---|---|
type | timestamp |
preserveExisting | false 如果时间戳已经存在是否保留 |
三、配置示例
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=timestamp
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
在01机创建timestamp.conf文件
02和03保持之前多路复用模式启动状态不变,可以看到02和03接收到的数据都被加上时间戳
curl -X POST -d '[{"headers":{"state":"11111111","b":"b1"},"body":"hello 11111111"}]' http://localhost:8888
Host Interceptor
一、概述
- 这个拦截器插入当前处理Agent的主机名或ip
- 头的名字为host或配置的名称
- 值是主机名或ip地址,基于配置
二、可配置项说明
配置参数 | 说明 |
---|---|
type | host |
preserveExisting | false 如果主机名已经存在是否保留 |
useIP | true 如果配置为true则用IP,配置为false则用主机名 |
hostHeader | host 加入头时使用的名称 |
三、配置示例
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=host
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
结果添加了请求地址:
Static Interceptor
一、概述
- 此拦截器允许用户增加静态头信息使用静态的值到所有事件
- 目前的实现中不允许一次指定多个头
- 如果需要增加多个静态头可以指定多个Static interceptors
二、可配置项说明
配置项 | 说明 |
---|---|
type | static |
preserveExisting | true |
key | key 要增加的头名 |
value | value 要增加的头值 |
三、配置示例
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=static
a1.sources.r1.interceptors.i1.key=addr
a1.sources.r1.interceptors.i1.value=beijing
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
结果可以看到addr=beijing:
UUID Interceptor
一、概述
- 这个拦截器在所有事件头中增加一个全局一致性标志,其实就是UUID
二、可配置项说明
配置项 | 说明 |
---|---|
type | org.apache.flume.sink.solr.morphline.UUIDInterceptor$Builder |
headerName | id 头名称 |
preserveExisting | true 如果头已经存在,是否保留 |
prefix | “” 在UUID前拼接的字符串前缀 |
三、配置示例
结果示意:
Search And Replace Interceptor
一、概述
- 这个拦截器提供了简单的基于字符串的正则搜索和替换功能。
二、可配置项说明
配置项 | 说明 |
---|---|
type | search_replace |
searchPattern | 要搜索和替换的正则表达式 |
replaceString | 要替换为的字符串 |
charset | UTF-8 字符集编码,默认utf-8 |
三、配置示例
发送的数据示意(比如在body里写一些数字):
结果示意:
Regex Filtering Interceptor
一、概述
- 此拦截器通过解析事件体去匹配给定正则表达式来筛选事件
- 所提供的正则表达式即可以用来包含或刨除事件
二、可配置项说明
配置项 | 说明 |
---|---|
type | regex_filter |
regex | ”.*” 所要匹配的正则表达式 |
excludeEvents | false 如果是true则刨除匹配的事件,false则包含匹配的事件。 |
三、配置示例
结果将过滤到以jp开头的信息,即如果发送的是以jp开头的信息,则收不到
Regex Filtering Interceptor
一、概述
- 使用指定正则表达式匹配事件,并将匹配到的组作为头加入到事件中
- 它也支持插件化的序列化器用来格式化匹配到的组在加入他们作为头之前
二、可配置项说明
配置项 说明
type regex_extractor
regex 要匹配的正则表达式
serializers 匹配对象列表
三、配置示例
01 define agent name, source/sink/channel
a1.sources = r1
a1.sinks = k1
a1.channels = c1
02 source,http,jsonhandler
a1.sources.r1.type = http
a1.sources.r1.bind = master
a1.sources.r1.port = 6666
a1.sources.r1.handler = org.apache.flume.source.http.JSONHandler
03 regex extractor interceptor,match event body to extract character and digital
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = regex_extractor
a1.sources.r1.interceptors.i1.regex = (^[a-zA-Z]*)\\s([0-9]*$) # regex匹配并进行分组,匹配结果将有两个部分, 注意\s空白字符要进行转义
specify key for 2 matched part
a1.sources.r1.interceptors.i1.serializers = s1 s2
key name
a1.sources.r1.interceptors.i1.serializers.s1.name = word
a1.sources.r1.interceptors.i1.serializers.s2.name = digital
04 logger sink
a1.sinks.k1.type = logger
05 channel,memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
06 bind source,sink to channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
发送事件:
结果示意:
Sink Group Processor
- Sink Group允许用户将多个Sink组合成一个实体
- Flume Sink Processor 可以通过切换组内Sink用来实现负载均衡的效果,或在一个Sink故障时切换到另一个Sink
Default Sink Processor
一、概述
- 只接受一个 Sink
- 这是默认的策略。即如果不配置Processor,用的是这个策略
二、可配置选项说明
配置项 | 说明 |
---|---|
sinks | 用空格分隔的Sink集合 |
processor.type | default |
Failover Sink Processor
一、概述
- 维护一个sink们的优先表。确保只要一个是可用的就事件就可以被处理
- 失败处理原理是,为失效的sink指定一个冷却时间,在冷却时间到达后再重新使用
- sink们可以被配置一个优先级,数字越大优先级越高
- 如果sink发送事件失败,则下一个最高优先级的sink将会尝试接着发送事件
- 如果没有指定优先级,则优先级顺序取决于sink们的配置顺序,先配置的默认优先级高于后配置的
- 在配置的过程中,设置一个group processor ,并且为每个sink都指定一个优先级
- 优先级必须是唯一的
- 另外可以设置maxpenalty属性指定限定失败时间。
二、可配置项说明
配置项 | 说明 |
---|---|
sinks | 绑定的sink |
processor.type | failover |
processor.priority | 设置优先级,注意,每个sink的优先级必须是唯一的 |
processor.maxpenalty | 30000 The maximum backoff period for the failed Sink (in millis) |
三、示例
a1.sinkgroups = g1
a1.sinkgroups.g1.sinks = k1 k2
a1.sinkgroups.g1.processor.type = failover
a1.sinkgroups.g1.processor.priority.k1 = 5
a1.sinkgroups.g1.processor.priority.k2 = 10
a1.sinkgroups.g1.processor.maxpenalty = 10000
Load Balancing Sink Processor
一、概述
- 提供了在多个sink之间实现负载均衡的能力
- 它维护了一个活动sink的索引列表
- 它支持轮询或随机方式的负载均衡,默认值是轮询方式,可以通过配置指定
- 也可以通过实现AbstractSinkSelector接口实现自定义的选择机制。
二、可配置项说明
配置项 | 说明 |
---|---|
processor.sinks | 绑定的sink |
processor.type | load_balance |
processor.selector | round_robin(轮叫调度)random(随机) |
三、示例
01的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1
a1.sinkgroups=g1
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sinkgroups.g1.sinks=s1 s2
a1.sinkgroups.g1.processor.type=load_balance
a1.sinkgroups.g1.processor.selector=round_robin
#轮叫调度算法(轮询发送)
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.234.212
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.234.213
a1.sinks.s2.port=9999
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c1
02,03的配置示例:
#配置Agent a1 的组件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述内存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#为channel 绑定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
事务机制
- Flume的事务机制与可靠性保证的实现,最核心的组件是Channel(通道)。如果没有Channel组件,而紧靠Source与Sink组件是无从谈起的
- 文件通道指的是将事件存储到代理(Agent)本地文件系统中的通道。虽然要比内存通道慢一些,不过它却提供了持久化的存储路径,可以应对大多数情况,它应该用在数据流中不允许出现缺口的场合
- File channel虽然提供了持久化,但是其性能较差,吞吐量会受到一定的限制。相反,memory channel则牺牲可靠性换取吞吐量。当然,如果机器断电重启,则无法恢复。在实际应用中,大多数企业都是选择内存通道,因为在通过flume收集海量数据场景下,使用FileChannel所带来的性能下降是很大的甚至是无法忍受的。
一、put事务流程
- doPut:将批数据先写入临时缓冲区putList(Linkedblockingdequeue)
- doCommit:检查channel内存队列是否足够合并。
- doRollback:channel内存队列空间不足,回滚,等待内存通道的容量满足合并
- putList就是一个临时的缓冲区,数据会先put到putList,最后由commit方法会检查channel是否有足够的缓冲区,有则合并到channel的队列
二、Take事务
- doTake:先将数据取到临时缓冲区takeList(linkedBlockingDequeue)
- 将数据发送到下一个节点
- doCommit:如果数据全部发送成功,则清除临时缓冲区takeList
- doRollback:数据发送过程中如果出现异常,rollback将临时缓冲区takeList中的数据归还给channel内存队列。