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 会再次发送数据,此时可能会导致数据的重复。
sudo yum install -y nc
-- hadoop102 服务器
nc -lk 44444 --开启服务端 444444是服务器的端口号
--hadooop103 客户端
nc hadoop102 44444 --启动客户端
1.可有多个客户端向服务器发送信息,只有服务器可以收到,其他客户端互不干扰
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。
--语法:tail -f /路径
--如果监控任务失败了,那就直接失败了,不会重新在去监控
--读日志的时候会先默认读后面十行记录
tail -f /opt/module/hive/hive.log
--语法:tail -F /路径
--如果监控任务失败了,它会重试,去尝试重新开始监控
tail -F /opt/module/hive/hive.log
1.Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传 输的系统。Flume 基于流式架构,灵活简单。
1.Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS
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后面的就不输出
maxBytesToLog 16 Maximum 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 由 Header 和 Body 两部分组成,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
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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
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 号码来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 可以实现故障转移的功能。
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 等,进行日志分析。
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
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
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
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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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代码
<dependency> <groupId>org.apache.flumegroupId> <artifactId>flume-ng-coreartifactId> <version>1.7.0version> 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
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.flumegroupId> <artifactId>flume-ng-coreartifactId> <version>1.7.0version> 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
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.flumegroupId> <artifactId>flume-ng-coreartifactId> <version>1.7.0version> 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
1.安装 httpd 服务与 php
sudo yum -y install httpd php
2) 安装其他依赖
sudo yum -y install rrdtool perl-rrdtool rrdtool-devel
sudo yum -y install apr-devel
3)安装 ganglia
- sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
- sudo yum -y install ganglia-gmetad
- sudo yum -y install ganglia-web
- 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
1.安装 httpd 服务与 php
sudo yum -y install httpd php
2) 安装其他依赖
sudo yum -y install rrdtool perl-rrdtool rrdtool-devel
sudo yum -y install apr-devel
3)安装 ganglia
- sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
- sudo yum -y install ganglia-gmetad
- sudo yum -y install ganglia-web
- 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