目录
定义
组成架构
原理
安装
安装地址
安装部署
启动命令
数据链路
Source端接入类型
source端常用方式
sink端输出类型
Sink常用输出方式
channel类型
常见拓扑结构
定义
Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume 基于流式架构,灵活简单。
Flume最主要的作用就是,实时读取服务器本地磁盘或网络端口的数据,将其写入到存储介质中。
组成架构
Flume 组成架构
Agent
Agent 是一个 JVM 进程,它以事件的形式将数据从源头送至目的,是 Flume 数据传输的基本单元。
Agent 主要有 3 个部分组成,Source、Channel、Sink。
Source
Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。
Channel
Channel 是位于 Source 和 Sink 之间的缓冲区。因此,Channel 允许 Source 和 Sink 运作在不同的速率上。Channel 是线程安全的,可以同时处理几个 Source 的写入操作和几个 Sink的读取操作。
Flume 自带两种 Channel:Memory Channel 和 File Channel。
Memory Channel 是内存中的队列。Memory Channel 在不需要关心数据丢失的情景下适用。如果需要关心数据丢失,那么 Memory Channel 就不应该使用,因为程序死亡、机器宕机或者重启都会导致数据丢失。
File Channel 将所有事件写到磁盘。因此在程序关闭或机器宕机的情况下不会丢失数据。
Sink
Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个 Flume Agent。
Sink 是完全事务性的。在从 Channel 批量删除数据之前,每个 Sink 用 Channel 启动一个事务。批量事件一旦成功写出到存储系统或下一个 Flume Agent,Sink 就利用 Channel 提交事务。事务一旦被提交,该 Channel 从自己的内部缓冲区删除事件。
Sink 组件目的地包括 hdfs、logger、avro、thrift、ipc、file、null、HBase、solr、自定义。
Event
传输单元,Flume 数据传输的基本单元,以事件的形式将数据从源头送至目的地。
原理
安装
安装地址
1) Flume 官网地址
http://flume.apache.org/ 2)文档查看地址
http://flume.apache.org/FlumeUserGuide.html
3)下载地址
http://archive.apache.org/dist/flume/
注意:
下述内容基于apache-flume-1.9.0-bin.tar.gz 版本实现
安装部署
1)将 apache-flume-1.9.0-bin.tar.gz 上传到 linux 的/opt/software 目录下
2)解压 apache-flume-1.9.0-bin.tar.gz 到/opt/module/目录下:$ tar -zxf apache-flume-1.9.0-bin.tar.gz -C /opt/module/
3)修改 apache-flume-1.9.0-bin.tar.gz 的名称为 flume: $ mv apache-flume-1.9.0-bin flume
4)将 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.0_144 #配置jdk目录
5)在 flume 目录下创建 job 文件夹并进入 job 文件夹。
$ mkdir job
$ cd job/
6) 在 job 文件夹下创建 Flume Agent 配置文件 flume-telnet-logger.conf。
$ touch flume-telnet-logger.conf
在 flume-telnet-logger.conf 文件中添加与任务相关的配置内容,此处以监控本地磁盘某个文件为例,具体看下面内容。
# Name the components on this agent a1:表示agent的名称
a1.sources = r1 r1:表示a1的输入源
a1.sinks = k1 k1:表示a1的输出目的地
a1.channels = c1 c1:表示a1的缓冲区
# Describe/configure the source
a1.sources.r1.type = netcat 表示a1的输入源类型为netcat端口类型
a1.sources.r1.bind = localhost 表示a1的监听的主机
a1.sources.r1.port = 44444 表示a1的监听的端口号
# Describe the sink
a1.sinks.k1.type = logger 表示a1的输出目的地是控制台logger类型
# Use a channel which buffers events in memory
a1.channels.c1.type = memory 表示a1的channel类型是memory内存型
a1.channels.c1.capacity = 1000 表示a1的channel总容量1000个event
a1.channels.c1.transactionCapacity = 100 表示a1的channel传输时收集到了100条event以后再去提交事务
# Bind the source and sink to the channel
a1.sources.r1.channels = c1 表示将r1和c1连接起来
a1.sinks.k1.channel = c1 表示将k1和c1连接起来
启动命令
$ bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-telnet-logger.conf -Dflume.root.logger=INFO,console
参数说明:
--conf conf/ :表示配置文件存储在 conf/目录
--name a1 :表示给 agent 起名为 a1
--conf-file job/flume-telnet.conf :flume 本次启动读取的配置文件是在 job 文件夹下的 flume-telnet.conf 文件。
-Dflume.root.logger==INFO,console : -D 表 示 flume运行时动态修改flume.root.logger 参数属性值,并将控制台日志打印级别设置为 INFO 级别。日志级别包括:log、info、warn、error。
备注:
启动任务前需要配置好flume-telnet-logger.conf文件,针对不同的使用方式,参数配置部分会给出不同配置方式。
数据链路
Source端接入类型
avro
1 说明
监听Avro端口,从Avro client streams接收events。当与另一个(前一跳)Flume agent内置的Avro Sink配对时,它可以创建分层收集拓扑。可以监听IP和端口,并不一定是本机的IP,可以监听其他机器的IP和port
2 实例
#配置一个agent,agent的名称可以自定义(如a1)
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#配置source
a1.sources.s1.channels = c1
a1.sources.s1.type = avro
a1.sources.s1.bind = 192.168.1.100
a1.sources.s1.port = 9999
#配置channels
a1.channels.c1.type = memory
#配置sinks
a1.sinks.k1.channel = c1
a1.sinks.k1.type = logger
#为sources和sinks绑定channels
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
thriftSource
1 说明
但不支持ip过滤
2 实例
#配置一个agent,agent的名称可以自定义(如a1)
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#配置source
a1.sources.s1.channels = c1
a1.sources.s1.type = thrift
a1.sources.s1.bind = 192.168.1.100
a1.sources.s1.port = 9999
#配置channels
a1.channels.c1.type = memory
#配置sinks
a1.sinks.k1.channel = c1
a1.sinks.k1.type = logger
#为sources和sinks绑定channels
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
exec
1 说明
ExecSource的配置就是设定一个Unix(linux)命令,然后通过这个命令不断输出数据。如果进程退出,Exec Source也一起退出,不会产生进一步的数据。
通常用于监控单个文件,常用的是tail -F [file]指令,即只要应用程序向日志(文件)里面写数据,source组件就可以获取到日志(文件)中最新的内容 ,EXEC执行一个给定的命令获得输出的源,如果要使用tail命令,必选使得file足够大才能看到输出内容
2 实例
#Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#配置source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/flume/logs/test.log
a1.sources.r1.channels = c1
#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
jms
1 说明
从JMS系统(消息、主题)中读取数据,比如一个队列或者一个topic中读取数据,能够与各种JSM日志提供者对接,与ActiveMQ链接确保可用,其他未知
2 实例
spooling directory
1 说明
Spool Source监听一个指定的目录,source组件就可以获取该目录中添加新的文件信息,将其写入到channel。等待sink处理完之后,标记该文件已完成处理,文件名添加.completed后缀。
需要注意:
- 虽然是自动监控整个目录,但是只能监控文件,如果以追加的方式向已被处理的文件中添加内容,source并不能识别;
- spool目录下的文件不可以再打开编辑;
- 第二个是spool目录下不可包含相应的子目录;
2 实例
a1.sources = s1
a1.sinks = k1
a1.channels = c1
#Describe/configure the source
a1.sources.s1.type =spooldir
a1.sources.s1.spoolDir =/home/hadoop/logs
a1.sources.s1.fileHeader= true
a1.sources.s1.channels =c1
#Describe the sink
a1.sinks.k1.type = logger
a1.sinks.k1.channel = c1
#Use a channel which buffers events inmemory
a1.channels.c1.type = memory
netcat
1 说明
监听指定的端口,把传入的每一行文本都作为event传入sink中,可以通过nc -k -l [host] [port]来作为外部数据来源,flume可以通过此种来源进行监听;包含 TCP Source 和 UDP Source两种
2 实例
tcp source
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = netcat
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 6666
a1.sources.r1.channels = c1
udp source
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = netcatudp
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 6666
a1.sources.r1.channels = c1
Taildir Source
1 说明
监控指定的多个文件,一旦文件内有新写入的数据,就会将其写入到指定的sink内,本来源可靠性高,不会丢失数据,建议使用;但目前不适用于Windows系统;其不会对于跟踪的文件有任何处理,不会重命名也不会删除,不会做任何修改,这点比Spooling Source有优势;目前不支持读取二进制文件,支持一行一行的读取文本文件;
2 实例
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = TAILDIR
a1.sources.r1.channels = c1
a1.sources.r1.positionFile = /var/log/flume/taildir_position.json
a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1 = /var/log/test1/example.log
a1.sources.r1.headers.f1.headerKey1 = value1
a1.sources.r1.filegroups.f2 = /var/log/test2/.*log.*
a1.sources.r1.headers.f2.headerKey1 = value2
a1.sources.r1.headers.f2.headerKey2 = value2-2
a1.sources.r1.fileHeader = true
a1.sources.ri.maxBatchCount = 1000
kafka source
1 说明
从Kafka指定的topic中读取数据,如果有多个Kafka源运行,可以使用相同的Consumer Group配置它们,这样每个都将为主题读取一组唯一的分区。
2 实例
tier1.sources.source1.type = org.apache.flume.source.kafka.KafkaSource
tier1.sources.source1.channels = channel1
tier1.sources.source1.batchSize = 5000
tier1.sources.source1.batchDurationMillis = 2000
tier1.sources.source1.kafka.bootstrap.servers = localhost:9666
tier1.sources.source1.kafka.topics = test1, test2
tier1.sources.source1.kafka.consumer.group.id = custom.g.id
http
legacy
source端常用方式
- 监控服务器某个端口数据
- 实时监控本地磁盘文件
- 实时读取目录下所有文件
- 从上游的sink中获取数据
- 监控多个数据源
sink端输出类型
HDFS SINK
1 说明
此接收器将事件写入Hadoop分布式文件系统(HDFS)。 它目前支持创建文本和序列文件。 它支持两种文件类型的压缩。 可以基于经过的时间或数据大小或事件数量来周期性地滚动文件(关闭当前文件并创建新文件)。 它还通过属性(例如事件发生的时间戳或机器)来对数据进行桶/分区。 HDFS目录路径可能包含将由HDFS接收器替换的格式化转义序列,以生成用于存储事件的目录/文件名。 使用此接收器需要安装hadoop,以便Flume可以使用Hadoop jar与HDFS集群进行通信
2 实例
# hdfs sink
a2.sinks.k1.type = hdfs
a2.sinks.k1.channel = c1
a2.sinks.k1.hdfs.path = /nginx_logs/events/%y-%m-%d/
a2.sinks.k1.hdfs.filePrefix = events-
# hfds上文件目录创建的频率
#a2.sinks.k1.hdfs.round = true
#a2.sinks.k1.hdfs.roundValue = 10
#a2.sinks.k1.hdfs.roundUnit = minute
# hfds上目录使用了时间转换符 %y-%m-%d
a2.sinks.k1.hdfs.useLocalTimeStamp = true
# 使用文本文件,不使用sequenceFile
a2.sinks.k1.hdfs.fileType = DataStream
# 多长时间写数据到新文件
a2.sinks.k1.hdfs.rollInterval = 0
# 文件达到多少数据量时 写新文件
# 文件大小 接近于一个Block的大小 128M ~ 120M左右
a2.sinks.k1.hdfs.rollSize = 10240
# 文件已经写了多次次之后,写新文件
a2.sinks.k1.hdfs.rollCount = 0
hive sink
1 说明
将包含定界文本或JSON数据的事件直接传输到Hive表或分区
2 实例
a1.channels = c1
a1.channels.c1.type = memory
a1.sinks = k1
a1.sinks.k1.type = hive
a1.sinks.k1.channel = c1
a1.sinks.k1.hive.metastore = thrift://127.0.0.1:9666
a1.sinks.k1.hive.database = logsdb
a1.sinks.k1.hive.table = weblogs
a1.sinks.k1.hive.partition = asia,%{country},%y-%m-%d-%H-%M
a1.sinks.k1.useLocalTimeStamp = false
a1.sinks.k1.round = true
a1.sinks.k1.roundValue = 10
a1.sinks.k1.roundUnit = minute
a1.sinks.k1.serializer = DELIMITED
a1.sinks.k1.serializer.delimiter = "\t"
a1.sinks.k1.serializer.serdeSeparator = '\t'
a1.sinks.k1.serializer.fieldnames =id,,msg
HBase Sink
将数据写入hbase,实例如下
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hbase2
a1.sinks.k1.table = foo_table
a1.sinks.k1.columnFamily = bar_cf
a1.sinks.k1.serializer = org.apache.flume.sink.hbase2.RegexHBase2EventSerializer
a1.sinks.k1.channel = c1
Avro Sink
发送到此接收器的Flume事件将转换为Avro事件并发送到配置的主机名/端口, 实例
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = avro
a1.sinks.k1.channel = c1
a1.sinks.k1.hostname = 10.10.10.10
a1.sinks.k1.port = 4545
File Roll Sink
将数据写到本地磁盘,配置如下
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = file_roll
a1.sinks.k1.channel = c1
a1.sinks.k1.sink.directory = /var/log/flume
Sink常用输出方式
- 输出到hdfs,kafka,hbase,hive
- 输出到本地磁盘
- 输出给下一个flume的source
channel类型
File Channel
File Channel是一个持久化的隧道(channel),数据安全并且只要磁盘空间足够,它就可以将数据存储到磁盘上。
a1.channels = c1
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /mnt/flume/checkpoint
a1.channels.c1.dataDirs = /mnt/flume/data
对本地文件还可以进行加密存储
Memory Channel
事件被存储在内存中,内存大小可以配置,在程序意外推出时会丢失数据,
a1.channels = c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000
a1.channels.c1.byteCapacityBufferPercentage = 20
a1.channels.c1.byteCapacity = 800000
JDBC Channel
将事件存储在一个持久化的数据库中,目前支持DERBY
a1.channels = c1
a1.channels.c1.type = jdbc
Kafka Channel
将事件存储到kafka中,可以使用如下场景:
- 同时包含source和sink,提供高可用的通道;
- 包含source和拦截器没有sink,将事件写入topic,用于其他应用;
- 包含sink没有source,提同一个低延迟的读取方式,将数据存入hdfs或hbase;
a1.channels.channel1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.channel1.kafka.bootstrap.servers = kafka-1:9092,kafka-2:9092,kafka-3:9092
a1.channels.channel1.kafka.topic = channel1
a1.channels.channel1.kafka.consumer.group.id = flume-consumer