Flume-使用与详解

目录

一、概述

1、介绍

2、基本架构

(1)Agent

[(2) Source](#(2) Source)

(3)Sink

(4)Channel

(5)Event

二、安装与入门

1、Flume安装

(1)下载

(2)上传并解压

(3)修改配置文件

2、入门案例

(1)监控端口数据

[1)安装使用netcat 工具](#1)安装使用netcat 工具)

2)创建配置文件

3)开启flume监听端口

4)发送数据

5)查看Flume监听

(2)实时监控单个追加文件

1)输出控制台

2)添加依赖jar包

3)创建配置文件

4)运行Flume

5)启动hive

[6)在HDFS 上查看文件](#6)在HDFS 上查看文件)

(3)实时监控目录下多个新文件

1)创建配置文件

2)运行Flume

3)测试

(4)实时监控目录下的多个追加文件

1)创建配置文件

2)运行Flume

3)测试

三、进阶

[1、Flume 事务](#1、Flume 事务)

[2、Flume Agent 内部原理](#2、Flume Agent 内部原理)

[3、Flume 拓扑结构](#3、Flume 拓扑结构)

(1)简单串联

(2)复制和多路复用

1)说明

2)案例

(3)负载均衡和故障转移

1)说明

2)案例:故障转移

3)案例:负载均衡

(4)聚合

1)说明

2)案例

​编辑

4、自定义Interceptor

5、自定义Source

6、自定义Sink


一、概述

1、介绍

Flume 是Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传 输的系统。Flume基于流式架构,灵活简单。

Flume官网地址http://flume.apache.org/文档查看地址 http://flume.apache.org/FlumeUserGuide.html

2、基本架构

组件说明:

(1)Agent

Agent 是一个JVM进程,它以事件的形式将数据从源头送至目的。 Agent 主要有3个部分组成,Source、Channel、Sink

(2) Source

Source 是负责接收数据到Flume Agent的组件。Source组件可以处理各种类型、各种格式的日志数据,包括avro 、thrift、exec 、jms、spooling directory、netcat、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 以及 Kafka Channel

Memory Channel 是内存中的队列。Memory Channel在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么Memory Channel就不应该使用,因为程序死亡、机器宕 机或者重启都会导致数据丢失。 File Channel 将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。

(5)Event

传输单元,Flume 数据传输的基本单元,以 Event 的形式将数据从源头送至目的地。 Event 由Header 和Body两部分组成,Header用来存放该event的一些属性,为K-V结构, Body 用来存放该条数据,形式为字节数组。

二、安装与入门

1、Flume安装

(1)下载

下载地址http://archive.apache.org/dist/flume/

(2)上传并解压

tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /opt/module/

mv apache-flume-1.7.0-bin/ flume

(3)修改配置文件

将flume/conf 下的 flume-env.sh.template 文件修改为flume-env.sh,并配置 flume env.sh 文件

mv flume-env.sh.template flume-env.sh

vi flume-env.sh

export JAVA_HOME=/opt/module/jdk1.8

2、入门案例

(1)监控端口数据

使用Flume监听一个端口,收集该端口数据,并打印到控制台。

netcat Source官网参数https://flume.apache.org/FlumeUserGuide.html#netcat-tcp-source

1)安装使用netcat 工具

a、安装netcat 工具

sudo yum install -y nc

b、开启一个服务端监听4444端口

nc -lk 4444

c、开启一个客户端向4444端口发送数据

nc ip 端口

观察服务端, 收到客户端数据

2)创建配置文件

官网示例https://flume.apache.org/FlumeUserGuide.html#a-simple-example 创建Flume Agent 配置文件flume-netcat-logger.conf;在flume 目录下创建job文件夹并进入job文件夹。

mkdir job

cd job/

在job文件夹下创建Flume Agent配置文件flume-netcat-logger.conf。

vim flume-netcat-logger.conf

在flume-netcat-logger.conf 文件中添加如下内容

复制代码
# Name the components on this agent
# a1 表示agent的名字 r1 表示a1的source的名称
a1.sources = r1
# k1 表示a1的sinks的名称
a1.sinks = k1
# c1 表示a1的channels的名称
a1.channels = c1

# Describe/configure the source
# 表示a1的输入源类型为netcat端口类型
a1.sources.r1.type = netcat
# 表示a1的监听的主机
a1.sources.r1.bind = localhost
# 表示a1的监听的端口号
a1.sources.r1.port = 44444

# Describe the sink
# 表示a1的输出目的地是控制台logger类型
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
# 表示a1的channel类型是memory内存型
a1.channels.c1.type = memory
# 表示a1的channel总容量1000个event
a1.channels.c1.capacity = 1000
# 表示a1的channel传输时收集到了100条event以后再去提交事务
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
# 表示将r1和c1连接起来
a1.sources.r1.channels = c1
# 表示将k1和c1连接起来
a1.sinks.k1.channel = c1
3)开启flume监听端口

bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console

或者简写

bin/flume-ng agent -c conf/ -n a1 -f job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console

参数说明:

  • --conf/-c:表示配置文件存储在conf/目录
  • --name/-n:表示给agent起名为a1
  • --conf-file/-f:flume 本次启动读取的配置文件是在job文件夹下的flume-netcat-logger.conf文件。 -Dflume.root.logger=INFO,console:-D 表示flume运行时动态修改 flume.root.logger参数属性值,并将控制台日志打印级别设置为INFO级别。日志级别包括:log、info、warn、error
4)发送数据

使用netcat工具向本机的44444端口发送内容

5)查看Flume监听

在Flume监听页面观察接收数据情况

(2)实时监控单个追加文件

实时监控Hive日志,并上传到HDFS中

1)输出控制台

a、创建输出控制台配置文件

在输出到hdfs之前可以先将日志输出到控制台

vim flume-file-logger.conf

添加如下内容

复制代码
# Name the components on this agent
# a1 表示agent的名字 r1 表示a1的source的名称
a1.sources = r1
# k1 表示a1的sinks的名称
a1.sinks = k1
# c1 表示a1的channels的名称
a1.channels = c1

# Describe/configure the source
# 定义source类型为exec可执行命令的
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/module/hive/logs/hive.log
a1.sources.r1.shell = /bin/bash -c

# Describe the sink
# 表示a1的输出目的地是控制台logger类型
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
# 表示a1的channel类型是memory内存型
a1.channels.c1.type = memory
# 表示a1的channel总容量1000个event
a1.channels.c1.capacity = 1000
# 表示a1的channel传输时收集到了100条event以后再去提交事务
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
# 表示将r1和c1连接起来
a1.sources.r1.channels = c1
# 表示将k1和c1连接起来
a1.sinks.k1.channel = c1

b、启动命令

bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-file-logger.conf -Dflume.root.logger=INFO,console

c、启动hive

d、观察Flume

发现控制台一直在持续输出日志

2)添加依赖jar包

Flume 要想将数据输出到HDFS,须持有Hadoop相关jar包

将jar包拷贝到flume/lib 文件夹下

commons-configuration-1.6.jar

hadoop-auth-2.7.2.jar

hadoop-common-2.7.2.jar

hadoop-hdfs-2.7.2.jar

commons-io-2.4.jar

htrace-core-3.1.0-incubating.jar

3)创建配置文件

exec-source官网参数https://flume.apache.org/FlumeUserGuide.html#exec-source

hdfs-sink官网参数https://flume.apache.org/FlumeUserGuide.html#hdfs-sink

vim flume-netcat-logger.conf

在flume-netcat-logger.conf 文件中添加如下内容

复制代码
# Name the components on this agent
a2.sources = r2
a2.sinks = k2
a2.channels = c2
 
# Describe/configure the source
# 定义source类型为exec可执行命令的
a2.sources.r2.type = exec
a2.sources.r2.command = tail -F /opt/module/hive/logs/hive.log
a2.sources.r2.shell = /bin/bash -c
 
# Describe the sink
# 表示输出到hdfs
a2.sinks.k2.type = hdfs
# hdfs的地址
a2.sinks.k2.hdfs.path = hdfs://hd01:9000/flume/%Y%m%d/%H 
#上传文件的前缀 
a2.sinks.k2.hdfs.filePrefix = logs-
#是否按照时间滚动文件夹 
a2.sinks.k2.hdfs.round = true
#多少时间单位创建一个新的文件夹
a2.sinks.k2.hdfs.roundValue = 1
#重新定义时间单位
a2.sinks.k2.hdfs.roundUnit = hour
#是否使用本地时间戳
a2.sinks.k2.hdfs.useLocalTimeStamp = true
#积攒多少个Event才flush到HDFS一次
a2.sinks.k2.hdfs.batchSize = 1000
#设置文件类型,可支持压缩
a2.sinks.k2.hdfs.fileType = DataStream
#多久生成一个新的文件
a2.sinks.k2.hdfs.rollInterval = 30
#设置每个文件的滚动大小
a2.sinks.k2.hdfs.rollSize = 134217700
#文件的滚动与Event数量无关
a2.sinks.k2.hdfs.rollCount = 0
 
# Use a channel which buffers events in memory 
a2.channels.c2.type = memory
a2.channels.c2.capacity = 1000
a2.channels.c2.transactionCapacity = 100
 
# Bind the source and sink to the channel 
a2.sources.r2.channels = c2
a2.sinks.k2.channel = c2

注意: 对于所有与时间相关的转义序列,Event Header中必须存在以 "timestamp"的key(除非 hdfs.useLocalTimeStamp设置为true,此方法会使用TimestampInterceptor自动添加timestamp)

a3.sinks.k3.hdfs.useLocalTimeStamp = true

4)运行Flume

bin/flume-ng agent --conf conf/ --name a2 --conf-file job/flume-file-hdfs.conf

5)启动hive

bin/hive

6)在HDFS 上查看文件

当有日志数据增加时,会写入到hdfs临时文件,当触发条件后会将临时文件转为真实文件

(3)实时监控目录下多个新文件

使用Flume监听整个目录的文件,并上传至HDFS

spooling-directory-source官网参数https://flume.apache.org/FlumeUserGuide.html#spooling-directory-source

1)创建配置文件

vim flume-dir-hdfs.conf

添加如下内容

复制代码
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# source 配置
# 定义source类型为目录
a1.sources.r1.type = spooldir
# 定义监控目录
a1.sources.r1.spoolDir = /opt/module/flume/upload
# 定义文件上传完,后缀
a1.sources.r1.fileSuffix = .COMPLETED
# 是否有文件头
a1.sources.r1.fileHeader = true
# 忽略所有以.tmp结尾的文件,不上传
a1.sources.r1.ignorePattern = ([^ ]*\.tmp)

# sink配置
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = hdfs://hd01:9000/flume/upload/%Y%m%d/%H
# 上传文件的前缀
a1.sinks.k1.hdfs.filePrefix = upload-
#是否按照时间滚动文件夹 
a1.sinks.k1.hdfs.round = true 
#多少时间单位创建一个新的文件夹
a1.sinks.k1.hdfs.roundValue = 1
#重新定义时间单位
a1.sinks.k1.hdfs.roundUnit = hour
#是否使用本地时间戳
a1.sinks.k1.hdfs.useLocalTimeStamp = true
#积攒多少个Event才flush到HDFS一次
a1.sinks.k1.hdfs.batchSize = 100
#设置文件类型,可支持压缩 
a1.sinks.k1.hdfs.fileType = DataStream
#多久生成一个新的文件
a1.sinks.k1.hdfs.rollInterval = 60
#设置每个文件的滚动大小大概是128M
a1.sinks.k1.hdfs.rollSize = 134217700
#文件的滚动与Event数量无关
a1.sinks.k1.hdfs.rollCount = 0

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
2)运行Flume

bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-dir-hdfs.conf

说明:在使用Spooling Directory Source 时不要在监控目录中创建并持续修改已经上传完成的文件会以;.COMPLETED结尾被监控文件夹每500毫秒扫描一次文件变动

3)测试

创建文件夹并添加文件

在flume 目录下创建upload 文件夹

mkdir upload

touch hello.txt

echo java >> hello.txt

mv hello.txt upload/

touch hello2.tmp

echo java >> hello2.tmp

mv hello2.tmp upload/

发现hdfs不会产生新的文件,upload里面也不会产生.COMPLETED文件,因为.tmp的文件会过滤掉。

(4)实时监控目录下的多个追加文件

Exec source 适用于监控一个实时追加的文件,但不能保证数据不丢失;

Spooldir Source 能够保证数据不丢失,且能够实现断点续传,但延迟较高,不能实时监控;

Taildir Source 既能够实现断点续传,又可以保证数据不丢失,还能够进行实时监控。

案例:使用Flume监听整个目录的实时追加文件,并输出到控制台

taildir-source官网参数https://flume.apache.org/FlumeUserGuide.html#taildir-source

1)创建配置文件

vim flume-taildir-hdfs.conf

添加如下内容

复制代码
a1.sources = r1
a1.sinks = k1
a1.channels = c1
 
# Describe/configure the source
# 定义source类型
a1.sources.r1.type = TAILDIR
# 指定position_file位置
a1.sources.r1.positionFile = /opt/module/flume/tail_dir.json
# 定义监控目录文件
a1.sources.r1.filegroups = f1
a1.sources.r1.filegroups.f1 = /opt/module/flume/upload/hello.*
 
# Describe the sink 
a1.sinks.k1.type = logger
 
# Use a channel which buffers events in memory 
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
 
# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
2)运行Flume

bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-taildir-logger.conf -Dflume.root.logger=INFO,console

3)测试

向文件中写入数据

touch hello.txt

echo java >> hello.txt

关闭flume,再次向文件中写入数据后,再次启动flume,发现新写入的数据也会输出不会丢失

Taildir Source 维护了一个json 格式的position File,其会定期的往position File 中更新每个文件读取到的最新的位置,因此能够实现断点续传。

Position File的格式如下:

{"inode":36391382,"pos":16,"file":"/opt/module/flume/upload/hello.txt"}

注:Linux 中储存文件元数据的区域就叫做inode,每个inode都有一个号码,操作系统 用inode 号码来识别不同的文件,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。

三、进阶

1、Flume 事务

Put事务流程

doPut:将批数据先写入临时缓冲区putList

doCommit:检查channel内存队列是否足够合并。

doRollback:channel内存队列空间不足,回滚数据

Take事务

doTake:将数据取到临时缓冲区takeList,并将数据发送到HDFS

doCommit:如果数据全部发送成功,则清除临时缓冲区takeList

doRollback:数据发送过程中如果出现异常,rollback将临时缓冲区takeList中的数据归还给channel内存队列。

2、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可以实现故障转移的功能。

3、Flume 拓扑结构

(1)简单串联

这种模式是将多个flume顺序连接起来了,从最初的source开始到最终sink 传送的目的存储系统。此模式不建议桥接过多的flume数量,flume数量过多不仅会影响传输速率, 而且一旦传输过程中某个节点flume宕机,会影响整个传输系统。

(2)复制和多路复用

1)说明

Flume 支持将事件流向一个或者多个目的地。这种模式可以将相同数据复制到多个 channel 中,或者将不同数据分发到不同的 channel 中,sink 可以选择传送到不同的目的 地。

2)案例

需求:使用Flume-1 监控文件变动,Flume-1 将变动内容传递给Flume-2,Flume-2 负责存储 到HDFS。同时Flume-1将变动内容传递给Flume-3,Flume-3负责输出到Local FileSystem。

所使用的配置文档

exec-source文档replicating-channel-selector文档memory-channel文档avro-sink文档avro-source文档hdfs-sink文档file-roll-sink文档

a、创建flume-1的配置文件

cd job/test1/

vim flume-file-flume.conf

添加如下内容

复制代码
# agent
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1 c2

# 配置channel选择器 将数据流复制给所有channel
a1.sources.r1.selector.type = replicating

# 配置source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/module/hive/logs/hive.log
a1.sources.r1.shell = /bin/bash -c

# 配置sink sink端的avro是一个数据发送者
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd01
a1.sinks.k1.port = 4141

a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hd01
a1.sinks.k2.port = 4142

# 配置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

# bind
a1.sources.r1.channels = c1 c2
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c2

b、创建flume-2的配置文件

vim flume-flume-hdfs.conf

添加如下内容

复制代码
# agent
a2.sources = r1
a2.sinks = k1
a2.channels = c1

# 配置source
a2.sources.r1.type = avro
a2.sources.r1.bind = hd01
a2.sources.r1.port = 4141

# 配置sink
a2.sinks.k1.type = hdfs
a2.sinks.k1.hdfs.path = hdfs://hd01:9000/flume2/%Y%m%d/%H
#上传文件的前缀 
a2.sinks.k1.hdfs.filePrefix = flume2-
#是否按照时间滚动文件夹
a2.sinks.k1.hdfs.round = true
#多少时间单位创建一个新的文件夹
a2.sinks.k1.hdfs.roundValue = 1
#重新定义时间单位
a2.sinks.k1.hdfs.roundUnit = hour
#是否使用本地时间戳
a2.sinks.k1.hdfs.useLocalTimeStamp = true
#积攒多少个Event才flush到HDFS一次
a2.sinks.k1.hdfs.batchSize = 100
#设置文件类型,可支持压缩
a2.sinks.k1.hdfs.fileType = DataStream
#多久生成一个新的文件
a2.sinks.k1.hdfs.rollInterval = 600
#设置每个文件的滚动大小大概是128M
a2.sinks.k1.hdfs.rollSize = 134217700
#文件的滚动与Event数量无关
a2.sinks.k1.hdfs.rollCount = 0

# 配置channel
a2.channels.c1.type = memory
a2.channels.c1.capacity = 1000
a2.channels.c1.transactionCapacity = 100

# bind
a2.sources.r1.channels = c1
a2.sinks.k1.channel = c1

c、创建flume-3的配置文件

vim flume-flume-dir.conf

添加如下内容

复制代码
# agent
a3.sources = r1
a3.sinks = k1
a3.channels = c1

# 配置source
a3.sources.r1.type = avro
a3.sources.r1.bind = hd01
a3.sources.r1.port = 4142

# 配置sink
a3.sinks.k1.type = file_roll
a3.sinks.k1.sink.directory = /opt/module/flume/datas/flume3

# 配置channel
a3.channels.c1.type = memory
a3.channels.c1.capacity = 1000
a3.channels.c1.transactionCapacity = 100

# bind
a3.sources.r1.channels = c1
a3.sinks.k1.channel = c1

提示:输出的本地目录必须是已经存在的目录,如果该目录不存在,并不会创建新的目录。

d、启动flume

先启动flume-flume-dir和flume-flume-hdfs,后启动flume-file-flume

bin/flume-ng agent --conf conf/ --name a3 --conf-file job/test1/flume-flume-dir.conf

bin/flume-ng agent --conf conf/ --name a2 --conf-file job/test1/flume-flume-hdfs.conf

bin/flume-ng agent --conf conf/ --name a1 --conf-file job/test1/flume-file-flume.conf

e、启动hive

bin/hive

f、查看日志输出

查看文件夹

查看HDFS

(3)负载均衡和故障转移

1)说明

Flume支持使用将多个sink逻辑上分到一个sink组,sink组配合不同的SinkProcessor 可以实现负载均衡和错误恢复的功能。

2)案例:故障转移

使用Flume1 监控一个端口,其 sink 组中的 sink 分别对接 Flume2 和 Flume3,采用 FailoverSinkProcessor,实现故障转移的功能。

所使用的配置文档

netcat-tcp-source文档failover-sink-processor文档memory-channel文档avro-sink文档avro-source文档logger-sink文档

a、创建flume-1的配置文件

cd job/test2/

vim flume-netcat-flume.conf

添加如下内容

复制代码
# agent
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1
a1.sinkgroups = g1

# 配置source
a1.sources.r1.type = netcat
a1.sources.r1.bind = hd01
a1.sources.r1.port = 44444

# 配置processor
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

# 配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd01
a1.sinks.k1.port = 4141

a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hd01
a1.sinks.k2.port = 4142

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c1
a1.sinkgroups.g1.sinks = k1 k2

b、创建flume-2的配置文件

vim flume-flume-console1.conf

添加如下内容

复制代码
# agent
a2.sources = r1
a2.sinks = k1
a2.channels = c1

# 配置source
a2.sources.r1.type = avro
a2.sources.r1.bind = hd01
a2.sources.r1.port = 4141

# 配置sink
a2.sinks.k1.type = logger

# 配置channel
a2.channels.c1.type = memory
a2.channels.c1.capacity = 1000
a2.channels.c1.transactionCapacity = 100

# bind
a2.sources.r1.channels = c1
a2.sinks.k1.channel = c1

c、创建flume-3的配置文件

vim flume-flume-console2.conf

添加如下内容

复制代码
# agent
a3.sources = r1
a3.sinks = k1
a3.channels = c1

# 配置source
a3.sources.r1.type = avro
a3.sources.r1.bind = hd01
a3.sources.r1.port = 4142

# 配置sink
a3.sinks.k1.type = logger

# 配置channel
a3.channels.c1.type = memory
a3.channels.c1.capacity = 1000
a3.channels.c1.transactionCapacity = 100

# bind
a3.sources.r1.channels = c1
a3.sinks.k1.channel = c1

d、启动flume

先启动flume-flume-console1和flume-flume-console2,后启动flume-netcat-flume

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-flume-console1.conf --name a2 -Dflume.root.logger=INFO,console

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-flume-console2.conf --name a3 -Dflume.root.logger=INFO,console

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-netcat-flume.conf --name a1

e、使用netcat 工具向44444端口发送内容

nc hd01 44444

f、查看flume2和flume3

发现总是flume3接收到数据,因为flume3的权重比flume2高

g、将Flume2 kill,观察Flume3的控制台打印情况

jps -ml

kill -9 86849

再次发送数据

发下flume3依然能接收数据

3)案例:负载均衡

所使用的配置文档

load-balancing-sink-processor文档

a、修改flume-1的配置文件

配置processor

a1.sinkgroups.g1.processor.type = load_balance

a1.sinkgroups.g1.processor.backoff = true

a1.sinkgroups.g1.processor.selector = random

复制代码
# agent
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1
a1.sinkgroups = g1

# 配置source
a1.sources.r1.type = netcat
a1.sources.r1.bind = hd01
a1.sources.r1.port = 44444

# 配置processor
a1.sinkgroups.g1.processor.type = load_balance
a1.sinkgroups.g1.processor.backoff = true
a1.sinkgroups.g1.processor.selector = random

# 配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd01
a1.sinks.k1.port = 4141

a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hd01
a1.sinks.k2.port = 4142

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c1
a1.sinkgroups.g1.sinks = k1 k2

b、启动flume

先启动flume-flume-console1和flume-flume-console2,后启动flume-netcat-flume

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-flume-console1.conf --name a2 -Dflume.root.logger=INFO,console

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-flume-console2.conf --name a3 -Dflume.root.logger=INFO,console

bin/flume-ng agent --conf conf/ --conf-file job/test2/flume-netcat-flume.conf --name a1

c、使用netcat 工具向44444端口发送内容

nc hd01 44444

d、查看flume2和flume3

(4)聚合

1)说明

这种模式是最常见的,也非常实用,日常web应用通常分布在上百个服务器,甚至更多。产生的日志,处理起来也非常麻烦。用flume的这种组合方式 能很好的解决这一问题,每台服务器部署一个flume采集日志,传送到一个集中收集日志的 flume,再由此flume上传到hdfs、hive、hbase等,进行日志分析。

2)案例

hd01 上的Flume-1 监控文件/opt/module/flume/datas/group.log, hd02上的Flume-2 监控某一个端口的数据流, Flume-1 与 Flume-2 将数据发送给 hd03上的 Flume-3,Flume-3 将最终数据打印到控制台。

a、安装flume

hd01、hd02、hd03上都要安装flume

b、创建flume-1的配置文件

在hd01上创建配置文件

cd job/test3

vim flume-logger-flume.conf

添加如下内容

复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/module/flume/datas/group.log
a1.sources.r1.shell = /bin/bash -c

# 配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd03
a1.sinks.k1.port = 4141

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

b、创建flume-2的配置文件

在hd02上创建配置文件

cd job/test3

vim flume-netcat-flume.conf

添加如下内容

复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = netcat
a1.sources.r1.bind = hd02
a1.sources.r1.port = 44444

# 配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd03
a1.sinks.k1.port = 4141

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

c、创建flume-3的配置文件

在hd03上创建配置文件

cd job/test3

vim flume-flume-logger.conf

添加如下内容

复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = avro
a1.sources.r1.bind = hd03
a1.sources.r1.port = 4141

# 配置sink
a1.sinks.k1.type = logger 

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

d、启动flume

先启动flume3,后启动flume2和flume1

hd03上启动

bin/flume-ng agent --conf conf/ --conf-file job/test3/flume-flume-logger.conf --name a1 -Dflume.root.logger=INFO,console

hd02上启动

bin/flume-ng agent --conf conf/ --conf-file job/test3/flume-netcat-flume.conf --name a1

hd01上启动

bin/flume-ng agent --conf conf/ --conf-file job/test3/flume-logger-flume.conf --name a1

e、在hd01上向group.log追加内容,查看hd03的输出

c、在hd02向44444端口发送内容,查看hd03的输出

4、自定义Interceptor

在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。此时会用到Flume拓扑结构中的Multiplexing结构,Multiplexing 的原理是,根据event中Header的某个key的值,将不同的event发送到不同的Channel中,所以需要自定义一个Interceptor,为不同类型的event的Header中的key赋予不同的值。

案例:使用Flume采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不同的分析系统。

所使用的配置文档

flume-interceptors文档

(1)创建项目

(2)添加依赖

XML 复制代码
    <dependencies>
        <dependency>
            <groupId>org.apache.flume</groupId>
            <artifactId>flume-ng-core</artifactId>
            <version>1.7.0</version>
        </dependency>
    </dependencies

(3)定义CustomInterceptor 类

java 复制代码
package com.hk;

import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;

import java.util.ArrayList;
import java.util.List;

public class CustomInterceptor implements Interceptor {

    List<Event> eventList;

    // 初始化
    @Override
    public void initialize() {
        eventList = new ArrayList<>();
    }

    // 核心业务
    @Override
    public Event intercept(Event event) {
        String s = new String(event.getBody());
        if (s.contains("hello")) {
            event.getHeaders().put("type", "java");
        } else {
            event.getHeaders().put("type", "php");
        }
        return event;
    }

    @Override
    public List<Event> intercept(List<Event> list) {
        // 清空集合
        eventList.clear();
        for (Event event : list) {
            eventList.add(intercept(event));
        }
        return eventList;
    }

    @Override
    public void close() {

    }


    public static class Builder implements Interceptor.Builder {

        @Override
        public Interceptor build() {
            return new CustomInterceptor();
        }

        @Override
        public void configure(Context context) {
        }
    }
}

(4)打包上传

(5)编辑flume1配置文件

在hd01上创建配置文件

cd job/test4

vim flume-netcat-flume.conf

添加如下内容

java 复制代码
# agent
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1 c2

# 配置source
a1.sources.r1.type = netcat
a1.sources.r1.bind = hd01
a1.sources.r1.port = 44444

# 自定义拦截器
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.hk.CustomInterceptor$Builder

# 配置选择器
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = type
a1.sources.r1.selector.mapping.java = c1
a1.sources.r1.selector.mapping.php = c2

# 配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hd02
a1.sinks.k1.port = 4141

a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hd03
a1.sinks.k2.port = 4141

# 配置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

# bind
a1.sources.r1.channels = c1 c2
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c2

(6)编辑flume2配置文件

在hd02上创建配置文件

cd job/test4

vim flume-flume-logger.conf

添加如下内容

java 复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = avro
a1.sources.r1.bind = hd02
a1.sources.r1.port = 4141

# 配置sink
a1.sinks.k1.type = logger

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

(7)编辑flume3配置文件

在hd03上创建配置文件

cd job/test4

vim flume-flume-logger.conf

添加如下内容

java 复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = avro
a1.sources.r1.bind = hd03
a1.sources.r1.port = 4141

# 配置sink
a1.sinks.k1.type = logger

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

(8)启动 flume

先启动flume2、flume3,后启动flume1

hd03上启动

bin/flume-ng agent --conf conf/ --conf-file job/test4/flume-flume-logger.conf --name a1 -Dflume.root.logger=INFO,console

hd02上启动

bin/flume-ng agent --conf conf/ --conf-file job/test4/flume-flume-logger.conf --name a1 -Dflume.root.logger=INFO,console

hd01上启动

bin/flume-ng agent --conf conf/ --conf-file job/test4/flume-netcat-flume.conf --name a1

(9)测试

向hd01的44444端口发送内容,查看hd02的输出和查看hd03的输出

hd02输出

hd03输出

5、自定义Source

Source 是负责接收数据到Flume Agent的组件。Source组件可以处理各种类型、各种格式的日志数据,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。官方提供的 source 类型已经很多,但是有时候并不能满足实际开发当中的需求,此时需要根据实际需求自定义某些source。

官方文档https://flume.apache.org/releases/content/1.11.0/FlumeDeveloperGuide.html#source

根据官方说明自定义 MySource 需要继承AbstractSource 类并实现Configurable 和PollableSource 接口

实现相应方法:

  • configure(Context context)//初始化 context(读取配置文件内容)
  • process()//获取数据封装成event并写入channel,这个方法将被循环调用。 使用场景:读取MySQL数据或者其他文件系统。

案例:使用flume接收数据,并给每条数据添加前缀,输出到控制台。前缀可从flume配置文件中配置。

(1)编写自定义类

java 复制代码
package com.hk;

import org.apache.flume.Context;
import org.apache.flume.EventDeliveryException;
import org.apache.flume.PollableSource;
import org.apache.flume.conf.Configurable;
import org.apache.flume.event.SimpleEvent;
import org.apache.flume.source.AbstractSource;

public class MySource extends AbstractSource implements Configurable, PollableSource {

    private String prefix;
    private String suffix;

    // 获取配置信息
    @Override
    public void configure(Context context) {
        // 获取前缀
        prefix = context.getString("prefix");
        // 获取后缀
        suffix = context.getString("suffix", "-student");
    }

    @Override
    public Status process() throws EventDeliveryException {
        //创建事件
        SimpleEvent simpleEvent = new SimpleEvent();

        try {
            for (int i = 0; i < 5; i++) {
                simpleEvent.setBody((prefix + i + suffix).getBytes());
                //将事件写入channel
                getChannelProcessor().processEvent(simpleEvent);
                Thread.sleep(2000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            return Status.BACKOFF;
        }
        return Status.READY;
    }

    @Override
    public long getBackOffSleepIncrement() {
        return 0;
    }

    @Override
    public long getMaxBackOffSleepInterval() {
        return 0;
    }

}

(2)打包上传

并放到flume的lib目录

(3)编写配置文件

vim mysource.conf

添加如下内容

java 复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = com.hk.MySource
a1.sources.r1.prefix = hk-
a1.sources.r1.suffix = -hk

# 配置sink
a1.sinks.k1.type = logger

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

(4)运行flume

bin/flume-ng agent --conf conf/ --conf-file job/mysource.conf --name a1 -Dflume.root.logger=INFO,console

(5)测试

不配置后缀,使用默认后缀

6、自定义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。

官方文档https://flume.apache.org/releases/content/1.11.0/FlumeDeveloperGuide.html#sink自定义 MySink 需要继承AbstractSink类并实现Configurable接口。

实现相应方法:

  • configure(Context context)//初始化 context(读取配置文件内容)
  • process()//从 Channel 读取获取数据(event),这个方法将被循环调用。
  • 使用场景:读取Channel数据写入MySQL或者其他文件系统。

案例:使用flume接收数据,并在Sink端给每条数据添加前缀和后缀,输出到控制台。前后缀可在flume任务配置文件中配置。

(1)编写自定义类

java 复制代码
package com.hk;

import org.apache.flume.*;
import org.apache.flume.conf.Configurable;
import org.apache.flume.sink.AbstractSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MySink extends AbstractSink implements Configurable {
    //创建Logger对象
    private static final Logger logger = LoggerFactory.getLogger(MySink.class);

    private String prefix;
    private String suffix;

    @Override
    public void configure(Context context) {
        // 获取前缀
        prefix = context.getString("prefix");
        // 获取后缀
        suffix = context.getString("suffix", "-student");

    }

    @Override
    public Status process() throws EventDeliveryException {
        //获取当前Sink绑定的Channel
        Channel channel = getChannel();
        //获取事务
        Transaction transaction = channel.getTransaction();
        // 开启事务
        transaction.begin();

        //读取Channel中的事件
        try {
            Event take = channel.take();
            if (take != null) {
                String s = new String(take.getBody());
                //处理事件(打印)
                logger.info(prefix + s + suffix);

            }
            //事务提交
            transaction.commit();
            return Status.READY;
        } catch (ChannelException e) {
            e.printStackTrace();
            transaction.rollback();
            return Status.BACKOFF;
        } finally {
            transaction.close();
        }
    }

}

(2)打包上传

并放到flume的lib目录

(3)编写配置文件

vim mysink.conf

添加如下内容

java 复制代码
# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# 配置source
a1.sources.r1.type = netcat
a1.sources.r1.bind = hd01
a1.sources.r1.port = 44444

# 配置sink
a1.sinks.k1.type = com.hk.MySink
a1.sinks.k1.prefix = hello-
a1.sinks.k1.suffix = -hello

# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100


# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

(4)运行flume

bin/flume-ng agent --conf conf/ --conf-file job/mysink.conf --name a1 -Dflume.root.logger=INFO,console

(5)测试

向44444端口发送数据

查看flume

不配置后缀,使用默认后缀

相关推荐
2601_955363152 小时前
B端企业拓客:如何在精准度与成本之间找到真正平衡?氪迹科技法人股东号码核验系统,阶梯式价格
大数据·人工智能
小荟荟2 小时前
数据资产估值技术探秘:荟宸多源异构数据融合引擎介绍
大数据
chatexcel2 小时前
ChatExcel AIPPT新功能:自定义模板上传,动画完整导出,单页可编辑
大数据·人工智能
Hello.Reader3 小时前
Pandas API on Spark 配置选项系统、默认索引与性能调优
大数据·spark·pandas
腾讯云大数据3 小时前
存算分离,性能跃升:盖雅工场TCHouse-D 3.0升级实现查询效率再提升60%
大数据·腾讯云
武子康3 小时前
大数据-257 离线数仓 - 数据质量监控详解:从理论到Apache Griffin实践
大数据·hadoop·后端
源码之家3 小时前
计算机毕业设计:Python二手车交易价格预测分析平台 Django框架 随机森林 可视化 数据分析 汽车 车辆 大数据 hadoop(建议收藏)✅
大数据·爬虫·python·机器学习·django·汽车·课程设计
OPHKVPS3 小时前
网络安全新威胁:开源AI平台CyberStrikeAI显著降低攻击门槛
大数据·网络·人工智能·安全
AI先驱体验官3 小时前
数字人部署入门:轻量化方案与快速落地
大数据·运维·人工智能·深度学习·重构·aigc