目录
一、概览
1、简介
-
Apache Flume 是一个分布式、高可靠、高可用的用来收集、聚合、转移不同来源的大量日志数据到中央数据仓库的工具
-
Apache Flume是Apache软件基金会(ASF)的顶级项目
-
目前有两个发行版本,0.9.x和1.x
0.9.x 介绍请访问:http://archive.cloudera.com/cdh/3/flume/UserGuide/.
提示 : 总结一下就是Flume是一个很NB的用来收集日志的工具,因为历史原因现在有两个版本0.9.x和1.x,从版本号也能看出来1.x版本新一些(通常软件系统有大的重构之后才会有大版本号的升级),所以新用户推荐使用1.x版本。
2、下载安装
Flume1.6下载及安装请查看:Flume下载安装教程.
二、体系结构
1、数据流模型
Event是Flume定义的一个数据流传输的最小单元。Agent就是一个Flume的实例,本质是一个JVM进程,该JVM进程控制Event数据流从外部日志生产者那里传输到目的地(或者是下一个Agent)。
提示: 学习Flume必须明白这几个概念,Event英文直译是事件,但是在Flume中表示数据传输的一个最小单位。参照下图可以看得出Agent就是Flume的一个部署实例, 一个完整的Agent中包含了三个组件Source、Channel和Sink,Source是指数据的来源和方式,Channel是一个数据的缓冲池,Sink定义了数据输出的方式和目的地。
Source消耗由外部(如Web服务器)传递给它的Event。外部以Flume Source识别的格式向Flume发送Event。例如,Avro Flume Source可接收从Avro客户端(或其他FlumeSink)接收Avro Event。用Thrift Flume Source也可以实现类似的流程,接收的Event数据可以是任何语言编写的只要符合Thrift协议即可。
当Source接收Event时,它将其存储到一个或多个channel。该channel是一个被动存储器,可以保持Event直到它被Sink消耗。『文件channel』就是一个例子 - 它由本地文件系统支持。sink从channel中移除Event并将其放入外部存储库(如HDFS,通过 Flume的 HDFS Sink 实现)或将其转发到流中下一个Flume Agent(下一跳)的Flume Source。
Agent中的source和sink与channel存取Event是异步的。
Flume的Source负责消费外部传递给它的数据(比如web服务器的日志)。外部的数据生产方以Flume Source识别的格式向Flume发送Event。
2、复杂流
Flume可以设置多级Agent连接的方式传输Event数据。也支持扇入和扇出的部署方式,类似于负载均衡方式或多点同时备份的方式。
提示 : 这里必须解释一下,第一句的意思是可以部署多个Agent组成一个数据流的传输链。第二句要知道扇入(多对一)和扇出(一对多)的概念,就是说Agent可以将数据流发到多个下级Agent,也可以从多个Agent发到一个Agent中。
其实他们就是想告诉你,你可以根据自己的业务需求来任意组合传输日志的Agent实例,引用一张后面章节的图,这就是一个扇入方式的Flume部署方式,前三个Agent的数据都汇总到一个Agent4上,最后由Agent4统一存储到HDFS。
3、可靠性
Event会在每个Agent的Channel上进行缓存,随后Event将会传递到流中的下一个Agent或目的地(比如HDFS)。只有成功地发送到下一个Agent或目的地后Event才会从Channel中删除。这一步保证了Event数据流在Flume Agent中传输时端到端的可靠性。
提示 : 同学们这里是知识点啊(敲黑板)!Flume的这个channel最重要的功能是用来保证数据的可靠传输的。其实另外一个重要的功能也不可忽视,就是实现了数据流入和流出的异步执行。
Flume使用事务来保证Event的 可靠传输。Source和Sink对channel提供的每个Event数据分别封装一个事务用于存储和恢复,这样就保证了数据流的集合在点对点之间的可靠传输。在多层架构的情况下,来自前一层的sink和来自下一层的Source 都会有事务在运行以确保数据安全地传输到下一层的Channel中。
4、可恢复性
Event数据会缓存在Channel中用来在失败的时候恢复出来。Flume支持保存在本地文件系统中的『文件channel』,也支持保存在内存中的『内存Channel』,『内存Channel』显然速度会更快,缺点是万一Agent挂掉『内存Channel』中缓存的数据也就丢失了。
三、配置Flume Agent
1、单节点Flume控制台输出
部署一个单节点的Flume,这个配置是让你自己生成Event数据然后Flume会把它们输出到控制台上。
下面的配置文件中,source使用的是 NetCat TCP Source,Source简单说就是监听本机上某个端口上接收到的TCP协议的消息,收到的每行内容都会解析封装成一个Event,然后发送到channel; sink使用的是 Logger Sink,这个sink可以把Event输出到控制台; channel使用的是Memory Channel,是一个用内存作为Event缓冲的channel。 Flume内置了多种多样的source、sink和channel,后面 配置 章节会逐一介绍。
创建一个 netcat-flume-logger.conf
文件,内容如下
# 配置Agent a1各个组件的名称
a1.sources=r1
a1.channels=c1
a1.sinks=k1
# 配置Agent a1的source r1的属性
a1.sources.r1.type=netcat #使用的是NetCat TCP Source,这个的是别名,Flume内置的一些组件都是有别名的,没有别名填全限定类名
a1.sources.r1.bind=localhost #NetCat TCP Source监听的hostname,这个是本机
a1.sources.r1.port=7777 #监听的端口
# 配置Agent a1的channel c1的属性,channel是用来缓冲Event数据的
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=1000
# 配置Agent a1的sink k1的属性
a1.sinks.k1.type=logger
# 把source和sink绑定到channel上
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1
配置文件里面的注释已经写的很明白了,这个配置文件定义了一个Agent叫做a1,a1有一个source监听本机7777端口上接收到的数据、一个缓冲数据的channel还有一个把Event数据输出到控制台的sink。这个配置文件给各个组件命名,并且设置了它们的类型和其他属性。通常一个配置文件里面可能有多个Agent,当启动Flume时候通常会传一个Agent名字来做为程序运行的标记。
用下面的命令加载这个配置文件启动Flume:
flume-ng agent --name a1 --conf ./conf/ --conf-file netcat-flume-logger.conf -Dflume.root.logger=INFO,console
请注意,在完整的部署中通常会包含 –conf=<conf-dir>
这个参数,<conf-dir>
目录里面包含了flume-env.sh和一个log4j.properties文件,在这个例子里面,我们强制Flume把日志输出到了控制台,运行的时候没有任何自定义的环境脚本。
测试一下我们的这个例子吧,打开一个新的终端窗口,用telnet命令连接本机的7777端口
telnet localhost 7777
然后输入Hello world!后按回车,这时收到服务器的响应[OK](这是 NetCat TCP Source 默认给返回的),说明一行数据已经成功发送,如下图右边所示
Flume的终端里面会以log的形式输出这个收到的Event内容,如上图左边所示
2、读取文件为Event控制台输出
部署一个单节点的Flume,这个配置是读取文件中的内容生成Event数据然后Flume会把它们输出到控制台上。
tmp.txt 内容如下
hello java
hello Flume
hello Scala
hello spark
创建一个 file-flume-logger
文件,内容如下
a2.sources=r1
a2.channels=c1
a2.sinks=k1
a2.sources.r1.type=exec
a2.sources.r1.command=tail -f /.../tmp.txt
a2.channels.c1.type=memory
a2.channels.c1.capacity=1000
a2.channels.c1.transactionCapacity=1000
a2.sinks.k1.type=logger
a2.sources.r1.channels=c1
a2.sinks.k1.channel=c1
用下面的命令加载这个配置文件启动Flume:
flume-ng agent --name a2 --conf ./conf/ --conf-file ./file-flume-logger.conf -Dflume.root.logger=INFO,console
flume-ng agent -n a2 -c ./conf/ -f ./file-flume-logger.conf -Dflume.root.logger=INFO,console
启动后控制台输出内容如下
3、读取文件夹生成Event控制台输出
部署一个单节点的Flume,这个配置是动态读取文件夹中的文件生成Event数据然后Flume会把它们输出到控制台上。
创建三个文件夹,依次是数据来源文件夹、检查点文件夹、缓冲池文件夹
mkdir -p /opt/flume/conf/jobkb09/dataSourceFile/events
mkdir -p /opt/flume/conf/jobkb09/checkPointFile/events
mkdir -p /opt/flume/conf/jobkb09/dataChannelFile/events
创建一个 events-flume-logger.conf
文件
events.sources=eventsSource
events.channels=eventsChannel
events.sinks=eventsSink
events.sources.eventsSource.type=spooldir
events.sources.eventsSource.spoolDir=/opt/flume/conf/jobkb09/dataSourceFile/events
events.sources.eventsSource.deserializer=LINE
events.sources.eventsSource.deserializer.maxLineLength=10000
events.sources.eventsSource.includePattern=events_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv
events.channels.eventsChannel.type=file
events.channels.eventsChannel.checkpointDir=/opt/flume/conf/jobkb09/checkPointFile/events
events.channels.eventsChannel.dataDirs=/opt/flume/conf/jobkb09/dataChannelFile/events
events.sinks.eventsSink.type=logger
events.sources.eventsSource.channels=eventsChannel
events.sinks.eventsSink.channel=eventsChannel
参数简要说明:
-
spoolDir:Flume Source监控的文件夹目录,该目录下的文件会被Flume收集,即数据来源文件夹
-
deserializer:指定一个把文件中的数据行解析成Event的解析器。默认是把每一行当做一个Event进行解析,所有解析器必须实现EventDeserializer.Builder接口
-
deserializer.maxLineLength:每行的最大长度
-
includePattern:定义文件来源名字格式,上面使用了正则匹配日期格式
用下面的命令加载这个配置文件启动Flume:
flume-ng agent --name a2 --conf ./conf/ --conf-file ./file-flume-logger.conf -Dflume.root.logger=INFO,console
flume-ng agent -n a2 -c ./conf/ -f ./file-flume-logger.conf -Dflume.root.logger=INFO,console
将需要获取的文件传入数据来源文件夹中,即 dataSourceFile/events
中
注意:上面定义了数据来源的文件名格式,传入文件时必须按照定义的格式命名传入的文件,每传入一个文件Flume就会获取一个文件信息,最后执行完成的文件会在原文件名后加上后缀
.COMPLETED
这里执行后的文件名会变为:events_2020-11-30.csv.COMPLETED
cp ./events.csv ./dataSourceFile/events/events_2020-11-30.csv
4、读取文件夹生成Event上传到HDFS
部署一个单节点的Flume,这个配置是动态读取文件夹中的文件生成Event数据然后Flume会把它们上传到HDFS上
创建一个 userFriend-flume-hdfs.conf
文件,内容如下
user_friend.sources=userFriendSource
user_friend.channels=userFriendChannel
user_friend.sinks=userFriendSink
user_friend.sources.userFriendSource.type=spooldir
user_friend.sources.userFriendSource.spoolDir=/opt/flume/conf/jobkb09/dataSourceFile/userFriend
user_friend.sources.userFriendSource.deserializer=LINE
user_friend.sources.userFriendSource.deserializer.maxLineLength=320000
user_friend.sources.userFriendSource.includePattern=userFriend_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv
user_friend.channels.userFriendChannel.type=file
user_friend.channels.userFriendChannel.checkpointDir=/opt/flume/conf/jobkb09/checkPointFile/userFriend
user_friend.channels.userFriendChannel.dataDirs=/opt/flume/conf/jobkb09/dataChannelFile/userFriend
user_friend.sinks.userFriendSink.type=hdfs
user_friend.sinks.userFriendSink.hdfs.fileType=DataStream
user_friend.sinks.userFriendSink.hdfs.filePrefix=userFriend
user_friend.sinks.userFriendSink.hdfs.fileSuffix=.csv
user_friend.sinks.userFriendSink.hdfs.path=hdfs://192.168.8.99:9000/kb09File/user/userFriend/%Y-%m-%d
user_friend.sinks.userFriendSink.hdfs.useLocalTimeStamp=true
user_friend.sinks.userFriendSink.hdfs.batchSize=640
user_friend.sinks.userFriendSink.hdfs.rollInterval=20
user_friend.sinks.userFriendSink.hdfs.rollCount=0
user_friend.sinks.userFriendSink.hdfs.rollSize=120000000
user_friend.sources.userFriendSource.channels=userFriendChannel
user_friend.sinks.userFriendSink.channel=userFriendChannel
用下面的命令加载这个配置文件启动Flume:
flume-ng agent -n user_friend -c ./conf/ -f ./userFriend-flume-hdfs.conf -Dflume.root.logger=INFO,console
导入需要上传的文件
cp user_friends.csv ../dataSourceFile/userFriend/userFriend_2020-12-03.csv
执行后查看HDFS文件系统结果如下:
5、users.csv上传到hdfs添加拦截器
利用flume获取文件users.csv的内容,并添加拦截器,去掉文件的首行内容,最后上传到HDFS文件系统
创建一个 user-flume-hdfs.conf
文件
users.sources=userSource
users.channels=userChannel
users.sinks=userSink
users.sources.userSource.type=spooldir
users.sources.userSource.spoolDir=/opt/flume/conf/jobkb09/dataSourceFile/user
users.sources.userSource.includePattern=user_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv
users.sources.userSource.deserializer=LINE
users.sources.userSource.maxLineLength=10000
users.sources.userSource.interceptors=head_filter
users.sources.userSource.interceptors.head_filter.type=regex_filter
users.sources.userSource.interceptors.head_filter.regex=^user_id*
users.sources.userSource.interceptors.head_filter.excludeEvents=true
users.channels.userChannel.type=file
users.channels.userChannel.checkpointDir=/opt/flume/conf/jobkb09/checkPointFile/user
users.channels.userChannel.dataDirs=/opt/flume/conf/jobkb09/dataChannelFile/user
users.sinks.userSink.type=hdfs
users.sinks.userSink.hdfs.fileType=DataStream
users.sinks.userSink.hdfs.filePrefix=users
users.sinks.userSink.hdfs.fileSuffix=.csv
users.sinks.userSink.hdfs.path=hdfs://hadoop:9000/kb09File/user/users/%Y-%m-%d
users.sinks.userSink.hdfs.useLocalTimeStamp=true
users.sinks.userSink.hdfs.batchSize=640
users.sinks.userSink.hdfs.rollCount=0
users.sinks.userSink.hdfs.rollSize=120000000
users.sinks.userSink.hdfs.rollInterval=20
users.sources.userSource.channels=userChannel
users.sinks.userSink.channel=userChannel
用下面的命令加载这个配置文件启动Flume:
flume-ng agent -n users -c ./conf/ -f ./user-flume-hdfs.conf -Dflume.root.logger=INFO,console
导入需要上传的文件
cp users.csv ../dataSourceFile/users/users_2020-12-03.csv
执行后查看HDFS文件系统结果如下: