常用Source及应用案例
1、功能
- Flume主要的应用是采集文件【文件、基于网络协议、Kafka】
- Source就是专门实现采集的组件
- 根据程序中的配置,监听我们的数据源
- 如果数据源的数据发生变化
- Source会将新的数据封装成Event发送到Channel中
2、Exce Source
http://archive.cloudera.com/cdh5/cdh/5/flume-ng-1.6.0-cdh5.14.0/FlumeUserGuide.html#exec-source
- 功能:采集文件,可以使用一条Linux的命令,来动态获取一个文件中的数据
- 一般都与Linux的tail命令搭配使用
- 只有tail命令能动态的获取文件的内容
cat/more/less/head/tail -f
- 应用场景
- 用于动态的监听单个文件的变化,将单个文件最新的变化数据进行采集
- 只要这个文件产生了新的数据,新的数据就立马会被采集
- 例如:Nginx的日志文件【用户行为】
- Nginx会将所有的数据都以追加的形式写入一个文件
- 缺点:这个文件会越来越大
需求1:将hive的日志动态的采集到Flume的日志中打印在控制台
- source:exec source
- channel:mem channel
- sink:logger
- 实现
- 将Flume分发到另外两台机器:备用
cd /export/servers/
scp -r flume-1.6.0-cdh5.14.0-bin node-02:$PWD
scp -r flume-1.6.0-cdh5.14.0-bin node-03:$PWD
- 启动Hadoop和Hive
- 在第三台机器复制程序的 文件
cd /export/servers/flume-1.6.0-cdh5.14.0-bin/userCase/
cp log-console.properties hive-mem-console.properties
- 编辑hive-mem-console.properties
# define sourceName/channelName/sinkName for the agent
a1.sources = s1
a1.channels = c1
a1.sinks = k1
# define the s1
a1.sources.s1.type = exec
a1.sources.s1.command = tail -f /export/servers/hive-1.1.0-cdh5.14.0/logs/hive.log
# define the c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# def the k1
a1.sinks.k1.type = logger
#source、channel、sink bond
a1.sources.s1.channels = c1
a1.sinks.k1.channel = c1
- 运行测试
bin/flume-ng agent -c conf/ -f userCase/hive-mem-console.properties -n a1 -Dflume.root.logger=INFO,console
- 在Hive中执行SQL命令,观察是否有新的Event产生
- 不适合的应用场景
- 文件是多个
- Tomcat、Hive日志数据:一天一个
- 今天的00:00一过,日志就会被重命名为对应日期的文件
3、Spool dir Source
- 功能:动态的监听一个目录,如果目录中产生新的文件,就会将新的文件进行采集
- 一般用于监控日志生成的目录
- 应用场景
- 数据生成是按照时间或者其他规则进行划分的,一天一个文件或者一个小时一个文件
- 目录中会动态的生成多个文件
- 例如:hive、Tomcat的日志数据
logs/hive.log.2020-06-06
hive.log.2020-06-07
hive.log.2020-06-08
hive.log.2020-06-09
hive.log.2020-06-10
……
- exec能不能实现?
- 不能,
exec只能监听一个文件
- 不能,
需求2:监听一个目录,只要目录中有新的文件产生,就立即采集这个文件的内容,打印在控制台
- source:spooldir
- channel:mem
- sink:logger
- 实现
- 第三台机器:复制一份程序
cp hive-mem-console.properties dir1-mem-console.properties
- 创建一个测试的目录
cd /export/datas/
mkdir -p flume/spooldir1
cd /export/datas/flume/spooldir1
- 编写程序
# define sourceName/channelName/sinkName for the agent
a1.sources = s1
a1.channels = c1
a1.sinks = k1
# define the s1
a1.sources.s1.type = spooldir
a1.sources.s1.spoolDir = /export/datas/flume/spooldir1
# define the c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# def the k1
a1.sinks.k1.type = logger
#source、channel、sink bond
a1.sources.s1.channels = c1
a1.sinks.k1.channel = c1
- 测试运行
bin/flume-ng agent -c conf/ -f userCase/dir1-mem-console.properties -n a1 -Dflume.root.logger=INFO,console
- 将数据文件不断往/export/datas/flume/spooldir1目录中放
cp /export/datas/r2c1.txt ./
- 查看被采集过的文件,自动加上.COMPLETED后缀名,表示这个文件被采集过了
- 避免下次Flume重新启动,又采集一遍
- 问题:所有文件只要在这个监听的目录中一产生,就立即会被采集,采集完成以后会被重命名,添加.compeleted标记
为什么要给文件重命名呢?
- 为了避免下次Flume程序重新启动,重复采集之前已经采集的过的文件
- 加上标识以后,下次重启,有标识的文件不会被采集
日志文件【一天一个文件】生成的两种方式
-
第一种方式:先生成临时文件,等到这天过去,这个临时文件会变成正式的日志文件
-
每天的00点一过,会生成一个临时日志文件,等到这天过去,这个临时文件会变成真正的日志文件,又会生成一个新的日志文件
-
举例
第一天:2020-01-01 00:00:00
tomcat/log/2020-01-01.log.tmp 今天所有的日志都会写入这个文件
第二天:2020-01-02 00:00:00
tomcat/log/2020-01-01.log
tomcat/log/2020-01-02.log.tmp 今天所有的日志都会写入这个文件
第三天:2020-01-03 00:00:00
tomcat/log/2020-01-01.log
tomcat/log/2020-01-02.log
tomcat/log/2020-01-03.log.tmp
- 问题:如果按照之前的Spooldir这个程序,就会出现问题
- 只要临时文件一生成,就立即会被Flume采集,然后重命名
- 但是程序依旧往原来的临时文件名称中写入日志,Flume就会报错并且不会采集这个临时文件
- 解决
- 思考:我们要采集的是.log.tmp的文件还是.log文件,等到所有日志写完了,不会再被写入了,我们再采集,只需要采集.log结尾的文件
通过正则表达式来匹配文件名称
- includePattern :符合这个正则的将被采集
- ignorePattern :符合这个正则的将被过滤,不采集
需求3:动态监控日志目录,按照方式一生成日志文件,只采集.log结尾的文件
- 先创建测试的日志目录
cd /export/datas/flume/
mkdir spooldir2
- 复制一份程序
cp dir1-mem-console.properties dir2-mem-console.properties
- 开发程序
# define sourceName/channelName/sinkName for the agent
a1.sources = s1
a1.channels = c1
a1.sinks = k1
# define the s1
a1.sources.s1.type = spooldir
a1.sources.s1.spoolDir = /export/datas/flume/spooldir2
#指定被采集成功以后的文件的后缀
a1.sources.s1.fileSuffix = .end
#通过正则过滤以.tmp结尾的文件
a1.sources.s1.ignorePattern = ([^ ]*\\.tmp$)
# define the c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# def the k1
a1.sinks.k1.type = logger
#source、channel、sink bond
a1.sources.s1.channels = c1
a1.sinks.k1.channel = c1
- 测试运行
bin/flume-ng agent -c conf/ -f userCase/dir2-mem-console.properties -n a1 -Dflume.root.logger=INFO,console
- 第二种方式:每天的00直接生成日志文件,然后以追加的形式写入日志文件,等到第二天的00点,再生成新的新日志文件
第一天:2020-01-01 00:00:00
tomcat/log/2020-01-01.log 今天所有的日志都会写入这个文件
第二天:2020-01-02 00:00:00
tomcat/log/2020-01-01.log
tomcat/log/2020-01-02.log 今天所有的日志都会写入这个文件
第三天:2020-01-03 00:00:00
tomcat/log/2020-01-01.log
tomcat/log/2020-01-02.log
tomcat/log/2020-01-03.log
- Spood dir能不能解决?
- 不能解决
- 为什么
- Spool dir中,只要文件一产生,就立即会被采集
- Exec能不能解决?
- 不能解决?
- 为什么
- exec只能监控单个文件
- Spool dir不适合的场景
- 可以监控目录中的变化,不能动态的监控文件的变化
- 文件一旦生成,就立即会被采集,这个文件就没有了,不能再变化
- Exec和Spool dir对比
Exec
- 优点:可以监控文件内容的
动态变化
- 缺点:
只能监控一个文件
- 优点:可以监控文件内容的
Spool dir
- 优先:可以监控一个目录中的
多个文件
- 缺点:
不能动态监控文件的变化
- 优先:可以监控一个目录中的
4、taildir source
http://archive.cloudera.com/cdh5/cdh/5/flume-ng-1.6.0-cdh5.14.0/FlumeUserGuide.html#taildir-source
- 这种Source类型是apache flume
1.7版本中才更新
的source类型- 如果你使用的版本没有这个功能,需要自己编译这个功能放入自己的版本中
- cdh5.14系列是在1.7之后发布的,也封装了这个功能
- 功能:
能实现多个文件的动态监控采集
- 应用场景
监控多个数据源,可以是目录、也可以是文件
每个数据源中的每个文件都可以动态变化
需求4:监控一个目录和一个文件,目录中也有文件,监控的所有文件发生变化都动态监听
- 创建测试的目录和文件
cd /export/datas/flume/
mkdir taildir
cd /export/datas/flume/taildir
echo " " >> bigdata.txt
mkdir dirtest
mkdir /export/servers/flume-1.6.0-cdh5.14.0-bin/position
- 复制一份程序
cp dir2-mem-console.properties tail-mem-console.properties
- 编写程序
# define sourceName/channelName/sinkName for the agent
a1.sources = s1
a1.channels = c1
a1.sinks = k1
# define the s1
a1.sources.s1.type = TAILDIR
#指定一个元数据记录文件
a1.sources.s1.positionFile = /export/servers/flume-1.6.0-cdh5.14.0-bin/position/taildir_position.json
#将所有需要监控的数据源变成一个组,这个组内有两个数据源
a1.sources.s1.filegroups = f1 f2
#指定了f1是谁:监控一个文件
a1.sources.s1.filegroups.f1 = /export/datas/flume/taildir/bigdata.txt
#指定f1采集到的数据的header中包含一个KV对
a1.sources.s1.headers.f1.headerKey1 = value1
#指定f2是谁:监控一个目录下的所有文件
a1.sources.s1.filegroups.f2 = /export/datas/flume/taildir/dirtest/.*
#指定f2采集到的数据的header中包含一个KV对
a1.sources.s1.headers.f2.headerKey1 = value2
a1.sources.s1.fileHeader = true
# define the c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# def the k1
a1.sinks.k1.type = logger
#source、channel、sink bond
a1.sources.s1.channels = c1
a1.sinks.k1.channel = c1
- 运行测试
bin/flume-ng agent -c conf/ -f userCase/tail-mem-console.properties -n a1 -Dflume.root.logger=INFO,console
- 问题:
taildir_position.json这个文件的作用是什么呢?
[
{"inode":792883,"pos":37,"file":"/export/datas/flume/taildir/bigdata.txt"},{"inode":792885,"pos":14,"file":"/export/datas/flume/taildir/dirtest/hanjiaxiaozhi.txt"},{"inode":792886,"pos":7,"file":"/export/datas/flume/taildir/dirtest/bigdata.txt"}
]
- 功能:用于保证记录每个文件已经被采集的数据的位置,避免数据重复采集
- 当程序重复启动时,不会采集之前已经采集过的数据
5、avro source
- 网络协议,监听端口,实现采集端口的数据
- 采集基于网络的数据流的
6、kafka source
- 采集Kafka中的数据