Flume

面试题

4.1 你是如何实现 Flume 数据传输的监控的

使用第三方框架 Ganglia 实时监控 Flume。

4.2 Flume Source**,Sink,**Channel 的作用?你们 Source 是什么类

型?

1、作用

(1)Source 组件是专门用来收集数据的,可以处理各种类型、各种格式的日志数据,

包括 avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、

http、legacy

(2)Channel 组件对采集到的数据进行缓存,可以存放在 Memory 或 File 中。

(3)Sink 组件是用于把数据发送到目的地的组件,目的地包括 HDFS、Logger、avro、

thrift、ipc、file、Hbase、solr、自定义。

2、我公司采用的 Source 类型为

(1)监控后台日志:exec

(2)监控后台产生日志的端口:netcat

Exec spooldir

4.3 Flume Channel Selectors

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KRiaRum5-1621439935092)(…/TypoarWrokPath/images/1619288682479.png)]

Channel Selectors,可以让不同的项目日志通过不同的Channel到不同的Sink中去。

官方文档上Channel Selectors 有两种类型:Replicating Channel Selector (default)和

Multiplexing Channel Selector

这两种Selector的区别是:Replicating 会 将source过来的events发往所有channel,而

Multiplexing可以选择该发往哪些Channel。

4.4 Flume 参数调优

\1. Source

增加 Source 个(使用 Tair Dir Source 时可增加 FileGroups 个数)可以增大 Source 的读

取数据的能力。例如:当某一个目录产生的文件过多时需要将这个文件目录拆分成多个文件

目录,同时配置好多个 Source 以保证 Source 有足够的能力获取到新产生的数据。

batchSize 参数决定 Source 一次批量运输到 Channel 的 event 条数,适当调大这个参数

可以提高 Source 搬运 Event 到 Channel 时的性能。

\2. 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 参数。

\3. Sink

增加 Sink 的个数可以增加 Sink 消费 event 的能力。Sink 也不是越多越好够用就行,过

多的 Sink 会占用系统资源,造成系统资源不必要的浪费。

batchSize 参数决定 Sink 一次批量从 Channel 读取的 event 条数,适当调大这个参数可

以提高 Sink 从 Channel 搬出 event 的性能。

4.5 Flume 的事务机制

Flume 的事务机制(类似数据库的事务机制):Flume 使用两个独立的事务分别负责从

Soucrce 到 Channel,以及从 Channel 到 Sink 的事件传递。比如 spooling directory source

为文件的每一行创建一个事件,一旦事务中所有的事件全部传递到 Channel 且提交成功,那

么 Soucrce 就将该文件标记为完成。同理,事务以类似的方式处理从 Channel 到 Sink 的传

递过程,如果因为某种原因使得事件无法记录,那么事务将会回滚。且所有的事件都会保持

到 Channel 中,等待重新传递

4.6 Flume 采集数据会丢失吗**?**

根据 Flume 的架构原理,Flume 是不可能丢失数据的,其内部有完善的事务机制,

Source 到 Channel 是事务性的,Channel 到 Sink 是事务性的,因此这两个环节不会出现数

据的丢失,唯一可能丢失数据的情况是 Channel 采用 memoryChannel,agent 宕机导致数据

丢失,或者 Channel 存储数据已满,导致 Source 不再写入,未写入的数据丢失。

Flume 不会丢失数据,但是有可能造成数据的重复,例如数据已经成功由 Sink 发出,

但是没有接收到响应,Sink 会再次发送数据,此时可能会导致数据的重复。

1.安装 netcat 工具**

sudo yum install -y nc

2.互相通信

-- hadoop102 服务器
nc -lk 44444  --开启服务端 444444是服务器的端口号
--hadooop103 客户端
nc hadoop102 44444 --启动客户端

1.可有多个客户端向服务器发送信息,只有服务器可以收到,其他客户端互不干扰

3.flume 启动命令

 1.第一种
 bin/flume-ng agent --conf conf/ --name  a1 --conf-file job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console
 
 2.第二种(推荐使用)
 bin/flume-ng agent -c conf/ -n a1 -f 
job/flume-netcat-logger.conf -Dflume.root.logger=INFO,console

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

4.动态监控日志

--语法:tail -f /路径
--如果监控任务失败了,那就直接失败了,不会重新在去监控
--读日志的时候会先默认读后面十行记录
tail -f /opt/module/hive/hive.log

--语法:tail -F /路径
--如果监控任务失败了,它会重试,去尝试重新开始监控
tail -F /opt/module/hive/hive.log

5.flume的定义

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

6.为什么要使用flume

1.Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS

6.flume的组件

1.2.1 Agent

Agent 是一个 JVM 进程,它以事件的形式将数据从源头送至目的。是flume存储数据流的地方

Agent 主要有 3 个部分组成,Source、Channel、Sink

1.2.2 Source

Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种

格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、sequence

generator、syslog、http、legacy

1.2.3日志输出的最大长度为16,如果长度大于16后面的就不输出

maxBytesToLog16Maximum number of bytes of the Event body to log

avro: 把多台服务器(flume generator)上面的日志汇总到一台或者几台服务器上面(flume collector),然后对接到kafka或者HDFS上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lp9WI21C-1621439935095)(…/TypoarWrokPath/images/1619106756731.png)]

Thrift:

侦听Thrift端口并从外部Thrift客户端流接收事件。 当与另一(前一跳)Flume agent上的内置ThriftSink配对时,它可以创建分层集合拓扑。 Thrift源可以配置为通过启用kerberos身份验证在安全模式下启动。 agent-principal和agent-keytab是Thrift源用来向Kerberos KDC进行身份验证的属性。

1.2.3 Sink

Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储

或索引系统、或者被发送到另一个 Flume Agent。

Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、HBase、solr、 taildir .自定

1.2.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 将所有事件写到磁盘.因此在程序关闭或机器宕机的情况下不会丢失数据。

首先是flume中三个组件的单词的意思,flume:水道;笕槽;引水槽,source:水源,channel:水渠,sink:水槽。见文知意,就是水从源头流出来,经过水渠或者管道,最终流到终点,也就是水槽了。之前总是flume的叫着,也不知道是啥意思,今天查了一下,再看其他几个组件的意思,这个工具的功能不言而喻了,就是针对像水一样的数据流处理的。
--flume channel selectors允许给一个source可以配置多个channel的能力。这种模式有两种方式,一种是用来复制(Replication),这也是默认配置,另一种是用来分流(Multiplexing)。
Flume中channel选择器(selector.type配置)必须实现ChannelSelector接口,实现了该接口的类主要作用是告诉Source中接收到的Event应该发送到哪些Channel,在Flume中主要由两个实现方式:
--1,复用,实现类:MultiplexingChannelSelector (Multiplexing n. 多路技术 多路复用)
--2,复制,实现类:ReplicatingChannelSelector   (Replicate  n. 复制品)
--如果没有手动配置,source的默认channel选择器类型是replicating(复制),当然这个选择器只针对source配置了多个channel的时候。
一个souce可以向多个channel同时写数据,所以也就产生了以何种方式向多个channel写的问题(比如自带的复制选择器,会把数据完整地发送到每一个channel,而多路分发选择器就可以通过配置来按照一定的规则进行分发,听起来很像负载均衡),channel选择器也就应运而生。

1.2.5 Event

传输单元,Flume 数据传输的基本单元,以 Event 的形式将数据从源头送至目的地。

Event 由 HeaderBody 两部分组成,Header 用来存放该 event 的一些属性,为 K-V 结构,

Body 用来存放该条数据,形式为字节数组。

sources 的avro类型监听Avro端口来接受外部avro客户端的事件流,和netcat不同的是,avro-source接收到的是经过avro序列化之后的数据,然后反序列化数据继续传输,所以,如果avro-source的话,源数据必须是经过avro序列化之后的数据。而netcat接收的是字符串格式的数据。
sources 的natcet类型

1.0,文件类型匹配

1.1配置文件 a1 a2 a3

2.如果在a1 使用sources netcat 接收数据,sink 使用avro类型,如果需要把数据传输给a2,那么a2的sources 就需要使用 avro类型接收数据, 建议也使用sink ,如果a2的数据还需要传给a3 ,都建议使用avro

7.安装详见山硅谷flume ppt 第四页

监控端口数据官方案例

1)案例需求:

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

2)需求分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eg6pa45G-1621439935097)(…/TypoarWrokPath/images/1618849609781.png)]

3.创建flume-netcat-logger.conf文件

# agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

#  source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444

#  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  source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

8.实时监控单个追加文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZJvK3L5-1621439935100)(…/TypoarWrokPath/images/1618849109512.png)]

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

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

2.创建 flume-file-hdfs.conf 文件

# Name the components on this agent
a2.sources = r2
a2.sinks = k2
a2.channels = c2

#  source
使用exec source type属性为exec
a2.sources.r2.type = exec
a2.sources.r2.command = tail -F /opt/module/hive/logs/hive.log

#  sink
a2.sinks.k2.type = hdfs
a2.sinks.k2.hdfs.path = hdfs://hadoop102:8020/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

9.实时监控目录下多个新文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tA7WCYDk-1621439935102)(…/TypoarWrokPath/images/1618849206288.png)]

1.创建配置文件 flume-dir-hdfs.conf

# Name the components on this agent
a2.sources = r2
a2.sinks = k2
a2.channels = c2

# Describe/configure the source 
a2.sources.r2.type = spooldir
a2.sources.r2.spoolDir = /opt/module/flume/upload
a2.sources.r2.fileHeader = true


# Describe the sink
a2.sinks.k2.type = hdfs
#上传到hdfs上的路径按年月日以分一级文件夹按日分二级文件夹
a2.sinks.k2.hdfs.path = hdfs://hadoop102:8020/flume/%Y%m%d/%H
#忽略所有以.tmp 结尾的文件,不上传
a2.sources.r2.ignorePattern = ([^ ]*\.tmp)
#上传文件的前缀
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

10.实时监控目录下的多个追加文件

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVqRy0Sp-1621439935103)(…/TypoarWrokPath/images/1618849411526.png)]

1.创建flume-files-logger.conf

# Name the components on this agent
--定义
a1.sources = r1
a1.sinks = k1
a1.channels = c1


# source
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1 =/opt/module/flume/files/files1.txt  --监控哪个文件
a1.sources.r1.filegroups.f2 =/opt/module/flume/files/files2.txt
a1.sources.r1.positionFile = /opt/module/flume/position/position.json --最终输出在本地路径

#  sink
a1.sinks.k1.type = logger

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


# Bind the source and sink to the channel
--将source sink 与channel绑定
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

Taildir 说明:

Taildir Source 维护了一个 json 格式的 position File,其会定期的往 position File

中更新每个文件读取到的最新的位置,因此能够实现断点续传。

Position File 的格式如下:

{“inode”:2496272,“pos”:12,“file”:"/opt/module/flume/files/file1.t

xt"}

{“inode”:2496275,“pos”:12,“file”:"/opt/module/flume/files/file2.t

xt"}

注:Linux 中储存文件元数据的区域就叫做 inode,每个 inode 都有一个号码,操作系统

用 inode 号码来识别不同的文件,Unix/Linux 系统内部不使用文件名,而使用 inode 号码来

11.实时读取目录文件到HDFS案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y9vevOAL-1621439935104)(…/TypoarWrokPath/images/1618850653510.png)]

1.创建配置文件 flume-dir-hdfs.conf

# Name the components on this agent
a2.sources = r2
a2.sinks = k2
a2.channels = c2

# Describe/configure the source
a2.sources.r2.type = 
a2.sources.r2.type = spooldir
a2.sources.r2.spoolDir = /opt/module/flume/upload
a2.sources.r2.fileHeader = true


# Describe the sink
a2.sinks.k2.type = hdfs
a2.sinks.k2.hdfs.path = hdfs://hadoop102:8020/flume/%Y%m%d/%H
#忽略所有以.tmp 结尾的文件,不上传
a2.sources.r2.ignorePattern = ([^ ]*\.tmp)


#上传文件的前缀
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

12Flume事务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ehh7U9QE-1621439935104)(…/TypoarWrokPath/images/1618936762325.png)]

1.Put事务流程

​ -doPut:将数据先写入临时缓冲区purlist

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

​ -doPollback:channel内存队列空间不足,回滚数据

2.Take事务

-doTake :将数据拉取到临时缓冲区take List,并将数据发送到HDFS

-doCommit:如果数据全部发送成功,则清除缓冲区TakeList的数据

-doRollback:数据发送过程中如果出现异常,rollack将临时缓冲区TakeList的数据还给channel

13.Flume Agent的内部原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KqcU0G7h-1621439935105)(…/TypoarWrokPath/images/1618937587240.png)]

1.重要组件

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

14.Flume 拓扑结构

1.简单串联

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UGEa3wCL-1621439935106)(…/TypoarWrokPath/images/1618938451676.png)]

这种模式是将多个 flume 顺序连接起来了,从最初的 source 开始到最终 sink 传送的

目的存储系统。此模式不建议桥接过多的 flume 数量,flume 数量过多不仅会影响传输速率,

而且一旦传输过程中某个节点 flume 宕机,会影响整个传输系统。

2.复制和多路复用

1.解释:单source 多个channel,Slnk

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IhjmQLII-1621439935108)(…/TypoarWrokPath/images/1618938523806.png)]

2.Flume 支持将事件流向一个或者多个目的地。这种模式可以将相同数据复制到多个

channel 中,或者将不同数据分发到不同的 channel 中,sink 可以选择传送到不同的目的

地。

3.负载均衡和故障转移

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCBXDvpY-1621439935109)(…/TypoarWrokPath/images/1618938734581.png)]

1.Flume支持使用将多个sink逻辑上分到一个sink组,sink组配合不同的SinkProcessor

可以实现负载均衡和错误恢复的功能。

4.聚合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hi6F1fzM-1621439935109)(…/TypoarWrokPath/images/1618938970389.png)]

1.这种模式是我们最常见的,也非常实用,日常 web 应用通常分布在上百个服务器,大者

甚至上千个、上万个服务器。产生的日志,处理起来也非常麻烦。用 flume 的这种组合方式

能很好的解决这一问题,每台服务器部署一个 flume 采集日志,传送到一个集中收集日志的

flume,再由此 flume 上传到 hdfs、hive、hbase 等,进行日志分析。

15.Fumle企业案例

1)案例需求

使用 Flume-1 监控文件变动,Flume-1 将变动内容传递给 Flume-2,Flume-2 负责存储

到 HDFS。同时 Flume-1 将变动内容传递给 Flume-3,

Flume-3 负责输出到 Local FileSystem。

2.需求分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKk440EQ-1621439935110)(…/TypoarWrokPath/images/1619073372383.png)]

flume1

#监控日志将日志发送发到flume2 和flume3
#names
a1.sources = r1
a1.channels = c1 c2  #因为是发送到两个flume 所以需要两个 
a1.sinks = k1 k2  #因为是发送到两个flume 所以需要两个 

#sources
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1 =/opt/module/data/hive.log  #监控的日志路径
a1.sources.r1.positionFile = /opt/module/flume/position/psoitionflume1.json  # JSON格式的文件,以记录每个尾随文件的偏移量,支持断点续传

#将数据流复制给所有的channel
a1.sources.r1.selector.type = replicating

# 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


#sinks
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hadoop102
a1.sinks.k1.port = 4141

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


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

flume2

#将监控到的日志文件保存到HDFS上
#name
a2.sources = r1
a2.channels = c1 
a2.sinks = k1 

#sources
a2.sources.r1.type = avro  #使用avro 类型
a2.sources.r1.bind = hadoop102  #主机ip
a2.sources.r1.port = 4141   #端口号

#channel
a2.channels.c1.type = memory   #使用avro 类型
a2.channels.c1.capacity = 1000  #主机ip
a2.channels.c1.transactionCapacity = 100   #端口号

#sinks
a2.sinks.k1.type = hdfs
a2.sinks.k1.hdfs.path = hdfs://hadoop102:8020/flume/group1/%Y%m%d/%H   #HDFS的路径
#上传文件的前缀
a2.sinks.k1.hdfs.filePrefix = logs- #是否按照时间滚动文件夹
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 = 1000
#设置文件类型,可支持压缩
a2.sinks.k1.hdfs.fileType = DataStream
#多久生成一个新的文件(单位秒)
a2.sinks.k1.hdfs.rollInterval = 30
#设置每个文件的滚动大小
a2.sinks.k1.hdfs.rollSize = 134217700
#文件的滚动与 Event 数量无关
a2.sinks.k1.hdfs.rollCount = 0


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

flume3

#保存到本地
#name
a3.sources = r1
a3.channels = c1 
a3.sinks = k1 

#sources
a3.sources.r1.type = avro  #使用avro
a3.sources.r1.bind = hadoop102  #主机ip
a3.sources.r1.port = 4142   #端口号  

#channel
a3.channels.c1.type = memory   #使用avro
a3.channels.c1.capacity = 1000   #主机ip
a3.channels.c1.transactionCapacity = 100   #端口号  

#sinks
a3.sinks.k1.type = file_roll
a3.sinks.k1.sink.directory = /opt/module/data/group1   #保存到本地路径


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

16.故障转移

1.使用 Flume1 监控一个端口,其 sink 组中的 sink 分别对接 Flume2 和 Flume3,采用

FailoverSinkProcessor,实现故障转移的功能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tVHAnSsQ-1621439935111)(…/TypoarWrokPath/images/1619093912648.png)]

flume1

#使用一个channel和sink组
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1
a1.sinkgroups = g1   #定义


#source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444

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

#sinks
a1.sinks.k1.type = avro  
a1.sinks.k1.hostname = hadoop102
a1.sinks.k1.port = 4141     

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


#sink group   #sink组

a1.sinkgroups.g1.sinks = k1 k2  #组内有哪些sink
a1.sinkgroups.g1.processor.type = failover  
#优先级数字越大优先级越高
a1.sinkgroups.g1.processor.priority.k1 = 0    
a1.sinkgroups.g1.processor.priority.k2 = 10
a1.sinkgroups.g1.processor.maxpenalty = 10000


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

flume2

#sink组的其中一个端口号为4141
#name
a2.sources = r1
a2.channels = c1 
a2.sinks = k1 

#sources
a2.sources.r1.type = avro
a2.sources.r1.bind = hadoop102
a2.sources.r1.port = 4141

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

#sinks
a2.sinks.k1.type =logger

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

flume3

#sink组的第二个端口号为4142
#name
a3.sources = r1
a3.channels = c1 
a3.sinks = k1 

#sources
a3.sources.r1.type = avro
a3.sources.r1.bind = hadoop102
a3.sources.r1.port = 4142

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

#sinks
a3.sinks.k1.type =logger


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

测试

开启多个窗口进入到 cd /opt/module/flume/

**开启命令:**bin/flume-ng agent -c conf/ -f job/group1 -n a1

​ bin/flume-ng agent -c conf/ -f job/group1 -n a1

​ bin/flume-ng agent -c conf/ -f job/group1 -n a1

连接客户端:

​ nc localhost 44444

17.负载均衡

1.使用 Flume1 监控一个端口,其 sink 组中的 sink 分别对接 Flume2 和 Flume3,采用**

,load_balance实现负载均衡的功能

flume1

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


#source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444

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

#sinks
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hadoop102
a1.sinks.k1.port = 4141

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


#sink group 
a1.sinkgroups.g1.sinks = k1 k2
#load_balance类型
a1.sinkgroups.g1.processor.type = load_balance
#开启推递
a1.sinkgroups.g1.processor.backoff = true
#随机
a1.sinkgroups.g1.processor.selector = random


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

flume2

#name
a2.sources = r1
a2.channels = c1 
a2.sinks = k1 

#sources
a2.sources.r1.type = avro
a2.sources.r1.bind = hadoop102
a2.sources.r1.port = 4141

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

#sinks
a2.sinks.k1.type =logger

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

flume3

#name
a3.sources = r1
a3.channels = c1 
a3.sinks = k1 

#sources
a3.sources.r1.type = avro
a3.sources.r1.bind = hadoop102
a3.sources.r1.port = 4142

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

#sinks
a3.sinks.k1.type =logger


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

测试

开启多个窗口进入到 cd /opt/module/flume/

**开启命令:**bin/flume-ng agent -c conf/ -f job/group2 -n a1

​ bin/flume-ng agent -c conf/ -f job/group2 -n a1

​ bin/flume-ng agent -c conf/ -f job/group2 -n a1

连接客户端:

​ nc localhost 44444

18.聚合–分布式

1.hadoop102 上的 Flume-1 监控文件/opt/module/data/group.log,

hadoop103 上的 Flume-2 监控某一个端口的数据流,

Flume-1 与 Flume-2 将数据发送给 hadoop104 上的 Flume-3,Flume-3 将最终数据打印到控

制台。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ubvpvssc-1621439935112)(…/TypoarWrokPath/images/1619109565678.png)]

方法一 单sources

1.单source解释:由图知 ,就是flume 1 flume 2,发送数据只发送到4141端口,最后flume 3 监听一个端口号4141

flume102–文件追加 放在hadoop102主机上

# Name the components on this agent
a2.sources = r1
a2.sinks = k1
a2.channels = c1

#source
a2.sources.r1.type = TAILDIR
a2.sources.r1.filegroups = f1
a2.sources.r1.filegroups.f1 =/opt/module/data/flume.log
a2.sources.r1.positionFile = /opt/module/flume/position/position2.json


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

#sinks
a2.sinks.k1.type = avro
a2.sinks.k1.hostname = hadoop104
a2.sinks.k1.port = 4141

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

flume103–数据流,放在hadoop103主机上

使用 nv localhost 44444 发送数据

# Name the components on this agent
a3.sources = r1
a3.sinks = k1
a3.channels = c1

#source
a3.sources.r1.type = netcat
a3.sources.r1.bind = localhost
a3.sources.r1.port = 44444 

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

#sinks
a3.sinks.k1.type = avro
a3.sinks.k1.hostname = hadoop104
a3.sinks.k1.port = 4141

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

flume104–聚合数据,放在hadoop104主机上

# Name the components on this agent
a4.sources = r1 
a4.sinks = k1
a4.channels = c1

#source
a4.sources.r1.type = avro
a4.sources.r1.bind = hadoop104
a4.sources.r1.port = 4141



#channel
a4.channels.c1.type = memory
a4.channels.c1.capacity = 1000
a4.channels.c1.transactionCapacity = 100

#sinks
a4.sinks.k1.type = logger

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

方式二 多sources

1.多source解释:由图知 ,就是flume 1 发送数据到4141,flume 2 发送数据到4142 ,最后flume 3 监听两个端口号4141 和 4142

flume102

# Name the components on this agent
a2.sources = r1
a2.sinks = k1
a2.channels = c1

#source
a2.sources.r1.type = TAILDIR
a2.sources.r1.filegroups = f1
a2.sources.r1.filegroups.f1 =/opt/module/data/flume.log
a2.sources.r1.positionFile = /opt/module/flume/position/position2.json


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

#sinks
a2.sinks.k1.type = avro
a2.sinks.k1.hostname = hadoop104
a2.sinks.k1.port = 4141

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

flume103

# Name the components on this agent
a3.sources = r1
a3.sinks = k1
a3.channels = c1

#source
a3.sources.r1.type = netcat
a3.sources.r1.bind = localhost
a3.sources.r1.port = 44444 

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

#sinks
a3.sinks.k1.type = avro
a3.sinks.k1.hostname = hadoop104
a3.sinks.k1.port = 4142

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

flume104

# Name the components on this agent
a4.sources = r1 r2
a4.sinks = k1
a4.channels = c1

#source
a4.sources.r1.type = avro
a4.sources.r1.bind = hadoop104
a4.sources.r1.port = 4141

a4.sources.r2.type = avro
a4.sources.r2.bind = hadoop104
a4.sources.r2.port = 4142

#channel
a4.channels.c1.type = memory
a4.channels.c1.capacity = 1000
a4.channels.c1.transactionCapacity = 100

#sinks
a4.sinks.k1.type = logger

#bind
a4.sources.r1.channels = c1
a4.sources.r2.channels = c1
a4.sinks.k1.channel = c1

19.自定义Interceptor拦截器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlJuQzKv-1621439935113)(…/TypoarWrokPath/images/1619273212959.png)]

使用 Flume 采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不

同的分析系统。

1.项目需求**

在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要

发送到不同的分析系统。此时会用到 Flume 拓扑结构中的 Multiplexing 结构,Multiplexing

的原理是,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel

中,所以我们需要自定义一个 Interceptor,为不同类型的 event 的 Header 中的 key 赋予

不同的值。

在该案例中,我们以端口数据模拟日志,以数字(单个)和字母(单个)模拟不同类型

的日志,我们需要自定义 interceptor 区分数字和字母,将其分别发往不同的分析系统

(Channel)

2.自定义interceptor

在该案例中,我们以端口数据模拟日志,以字符串中包含hello字符串不包含hello模拟不同类

的日志,我们需要自定义 interceptor 区分字符串,将其分别发往不同的分析系统 (Channel)

3.自定义Interceptorjava代码

<!--xml文件-->
		<dependency>
           <groupId>org.apache.flume</groupId>
           <artifactId>flume-ng-core</artifactId>
           <version>1.7.0</version>
       </dependency>
package com.lhh.Interceptor;

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

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

/**
* @program: lhh
* @description:
* @author: 华仔
* @create: 2021-04-24 14:44
* com\lhh\Interceptor\TypeInterceptor
*/
//自定义拦截器
public class TypeInterceptor implements Interceptor {
  //声明一个存放事件的集合
   private List<Event> addHeaderEvents;
   public void initialize() {
       //初始化集合
       addHeaderEvents=new ArrayList<Event>();
   }

   //单个事件拦截
   public Event intercept(Event event) {
       //1.获取事件中的头信息
       Map<java.lang.String, java.lang.String> headers = event.getHeaders();
       //2.获取事件中的body信息
       String body = new String(event.getBody());
       //3.根据body中是否有hello,来决定头信息
       if (body.contains("hello")) {
           //添加头信息
           headers.put("type","lhh");
       }else{
           //添加头信息
           headers.put("type","lmh");
       }
       return event;
   }
   //多个事件拦截
   public List<Event> intercept(List<Event> list) {
       //清空全局的集合
       addHeaderEvents.clear();
       for (Event event : list) {
           //添加头信息
           Event intercept = intercept(event);
           //将头信息添加到集合
           addHeaderEvents.add(intercept);
       }
       return addHeaderEvents;
   }

   //资源释放
   public void close() {

   }

   //自定义静态类,实现Builder
   public static class Builder implements Interceptor.Builder{

       public Interceptor build() {
           //返回一个Interceptor对象,直接调用上面的类
           return new TypeInterceptor();
       }

       public void configure(Context context) {

       }
   }
}

4.flume中创建配置文件–分布式–hadoop102 hadoop103 hadoop104

1.hadoop102-flume2

# Name the components on this agent
a2.sources = r1
a2.sinks = k1 k2
a2.channels = c1 c2

#sources 使用netcat模式,使用客户端发送信息
a2.sources.r1.type = netcat  
a2.sources.r1.bind = localhost
a2.sources.r1.port = 44444

#interceptors 使用拦截器
a2.sources.r1.interceptors = i1
#自定义的类全路径
a2.sources.r1.interceptors.i1.type = com.lhh.Interceptor.TypeInterceptor$Builder


#channle selector   
a2.sources.r1.selector.type = multiplexing
a2.sources.r1.selector.header = type
a2.sources.r1.selector.mapping.lhh = c1
a2.sources.r1.selector.mapping.lmh = c2 

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

a2.channels.c2.type = memory
a2.channels.c2.capacity = 1000
a2.channels.c2.transactionCapacity = 100

#sink
a2.sinks.k1.type = avro
a2.sinks.k1.hostname = hadoop103
a2.sinks.k1.port = 4142

a2.sinks.k2.type = avro
a2.sinks.k2.hostname = hadoop104
a2.sinks.k2.port = 4142


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

2.hadoop103-flume2.conf

#name
a3.sources = r1
a3.channels = c1 
a3.sinks = k1 

#sources
a3.sources.r1.type = avro
a3.sources.r1.bind = hadoop103
a3.sources.r1.port = 4142

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

#sinks
a3.sinks.k1.type =logger


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

20.自定义Sources

1.1)介绍

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 接口。

实现相应方法:

getBackOffSleepIncrement()//暂不用

getMaxBackOffSleepInterval()//暂不用

configure(Context context)//初始化 context(读取配置文件内容)

process()//获取数据封装成 event 并写入 channel,这个方法将被循环调用

使用场景:读取 MySQL 数据或者其他文件系统。

2)需求

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

件中配置。

1.自定义soource的需求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dqD98Sif-1621439935114)(…/TypoarWrokPath/images/1619273308150.png)]

2.自定义需求分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aaBcTFj4-1621439935115)(…/TypoarWrokPath/images/1619273359621.png)]

3.自定义source java代码

1.xml文件

<dependency>
           <groupId>org.apache.flume</groupId>
           <artifactId>flume-ng-core</artifactId>
           <version>1.7.0</version>
       </dependency>

2.代码

package com.lhh.source;

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;

/**
* @program: lhh
* @description:
* @author: 华仔
* @create: 2021-04-24 22:06
* com.lhh.source.Mysource
*/
public class Mysource extends AbstractSource implements Configurable, PollableSource {

   //定义全局前缀和后缀
   private String prefix;
   private String subfix;

   public void configure(Context context) {
       //读取信息给前后缀赋值
       prefix = context.getString("prefix");
       //默认在每一条数据后面加一个后缀
       subfix = context.getString("subfix", "LHH");
   }

   /**
    * 1.接收数据(自己伪造数据使用for循环造数据)
    * 2.封装为事件
    * 3.将事件传给channel
    *
    * @return
    * @throws EventDeliveryException
    */
   public Status process() throws EventDeliveryException {
       //定义状态
       Status status = null;
       try {
           //1.接收数据
           for (int i = 0; i < 5; i++) {
               //2.构建数据
               SimpleEvent simpleEvent = new SimpleEvent();
               //4.给时间设置值
               simpleEvent.setBody((prefix + "--" + i + "--" + subfix).getBytes());
               //将事件传给channel
               getChannelProcessor().processEvent(simpleEvent);
               //事件完成就重新赋值
               status = Status.READY;
           }
       } catch (Exception e) {
           e.printStackTrace();
           status = Status.BACKOFF;
       }
       try {
           Thread.sleep(2000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return status;
   }
	//不用
   public long getBackOffSleepIncrement() {
       return 0;
   }
	//不用
   public long getMaxBackOffSleepInterval() {
       return 0;
   }


}

4.flume文件

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1


# Describe/configure the source
#自定义source类的全路径
a1.sources.r1.type = com.lhh.source.Mysource
#自定义的前缀 prefix要和java代码中的变量名一样
a1.sources.r1.prefix = feiji
#自定义的后缀 subfix要和java代码中的变量名一样
#a1.sources.r1.subfix = xiaxian


# 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

5.测试代码,输出到日志

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

21.自定义Sink

1.1)介绍

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 接口。

实现相应方法:

configure(Context context)//初始化 context(读取配置文件内容)

process()//从 Channel 读取获取数据(event),这个方法将被循环调用。

使用场景:读取 Channel 数据写入 MySQL 或者其他文件系统。

2)需求

使用 flume 接收数据,并在 Sink 端给每条数据添加前缀和后缀,输出到控制台。前后

缀可在 flume 任务配置文件中配置。

流程分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xxeD5G7-1621439935116)(…/TypoarWrokPath/images/1619278575258.png)]

3.自定义sink java代码

1.xml文件

<dependency>
           <groupId>org.apache.flume</groupId>
           <artifactId>flume-ng-core</artifactId>
           <version>1.7.0</version>
       </dependency>
package com.lhh.sink;

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

/**
* @program: lhh
* @description:
* @author: 华仔
* @create: 2021-04-24 23:47
*/
public class Mysink extends AbstractSink implements Configurable {

   //获取logger对象
   private Logger logger = LoggerFactory.getLogger(Mysink.class);


   //定义前后缀
   private String prefix;
   private String subfix;

   public void configure(Context context) {
       //读取配置文件给亲后缀赋值
       prefix = context.getString("prefix");
       subfix = context.getString("subfix", "LHH");
   }

   /**
    * 1.获取channel
    * 2.从channel事务以及数据
    * 3.发送数据
    *
    * @return
    * @throws EventDeliveryException
    */
   public Status process() throws EventDeliveryException {
       //1.定义返回值
       Status status = null;
       //2. 获取channel
       Channel channel = getChannel();
       //3.从channel中获取事务
       Transaction transaction = channel.getTransaction();
       //4.开启事务
       transaction.begin();
       try {
           //5.从channel获取数据
           Event event = channel.take();
           if (event != null) {
               //6.处理事件
               String body = new String(event.getBody());
               //info日志级别
              //logger.info(prefix + body + subfix);
               //error日志级别
              logger.error(prefix + body + subfix);
               //8.成功提交,修改状态信息
               status = Status.READY;
           } else {
               //10.修改状态
               status = Status.BACKOFF;
           }
           //7.提交事务
           transaction.commit();

       } catch (ChannelException e) {
           e.printStackTrace();
           //9.提交事务异常
           transaction.rollback();
           //10.修改状态
           status = Status.BACKOFF;
       } finally {
           //11.关闭事务
           transaction.close();
       }
       //11.返回状态信息
       return status;
   }
}

3.自定义sink flume文件

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1



# Describe/configure the source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444



# Describe the sink
#自定义mysink的全类名
a1.sinks.k1.type = com.lhh.sink.Mysink
#自定义的前缀 prefix要和java代码中的变量名一样
a1.sinks.k1.prefix = feiji--
#自定义的后缀 subfix要和java代码中的变量名一样
a1.sinks.k1.subfix = --xiaxian

# 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

4.测试代码

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

22.安装Ganglia

1.安装 httpd 服务与 php

sudo yum -y install httpd php

2) 安装其他依赖

  1. sudo yum -y install rrdtool perl-rrdtool rrdtool-devel

  2. sudo yum -y install apr-devel

3)安装 ganglia

  1. sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  2. sudo yum -y install ganglia-gmetad
  3. sudo yum -y install ganglia-web
  4. sudo yum -y install ganglia-gmond

-Dflume.monitoring.hosts=192.168.126.102:8649

-Dflume.root.logger=INFO,console

transaction.commit();
   } catch (ChannelException e) {
       e.printStackTrace();
       //9.提交事务异常
       transaction.rollback();
       //10.修改状态
       status = Status.BACKOFF;
   } finally {
       //11.关闭事务
       transaction.close();
   }
   //11.返回状态信息
   return status;

}
}


3.自定义sink flume文件

~~~xml
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1



# Describe/configure the source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444



# Describe the sink
#自定义mysink的全类名
a1.sinks.k1.type = com.lhh.sink.Mysink
#自定义的前缀 prefix要和java代码中的变量名一样
a1.sinks.k1.prefix = feiji--
#自定义的后缀 subfix要和java代码中的变量名一样
a1.sinks.k1.subfix = --xiaxian

# 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

4.测试代码

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

22.安装Ganglia

1.安装 httpd 服务与 php

sudo yum -y install httpd php

2) 安装其他依赖

  1. sudo yum -y install rrdtool perl-rrdtool rrdtool-devel

  2. sudo yum -y install apr-devel

3)安装 ganglia

  1. sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  2. sudo yum -y install ganglia-gmetad
  3. sudo yum -y install ganglia-web
  4. sudo yum -y install ganglia-gmond

-Dflume.monitoring.hosts=192.168.126.102:8649

-Dflume.root.logger=INFO,console

bin/flume-ng agent -c conf/ -f job/flume-netcat-logger.conf -n a1 -Dflume.root.logger=INFO,console,console-Dflume.monitoring.type=ganglia-Dflume.monitoring.hosts=192.168.126.102:8649

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热心市民爱抽烟屁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值