什么是Flume
Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。
当前Flume主要有两个版本flume-og和flume-ng,一般情况下都是使用flume-ng,这里介绍的也是flume-ng版本。
Flume的架构与原理
flume整体架构图如下所示:
从图中我们可以看出,Flume由一个Agent中的三个组件Source、Channel以及Sink构成。Flume将日志采集过程进行解耦,Source组件负责从数据源采集数据,可以连接的数据源种类很多,avro,exec,taildir等等。Sink组件负责将采集的日志进行存储,可以存储到HDFS、Kafka、Hive等。Channel负责数据的传递。
Flume的核心组件
Flume Source:完成对日志数据的收集,分成transtion和event打入到channel之中。
Flume提供了各种source的实现,包括Avro Source、Exec Source、Spooling Directory Source、NetCat Source、Syslog Source、Syslog TCP Source、Syslog UDP Source、HTTP Source、HDFS Source,etc。
对现有程序改动最小的使用方式是使用是直接读取程序原来记录的体制文件,基本可以实现无缝接入,不需要对现有程序进行任何改动。直接读取文件Source,有两种方式:Exec Source和Spool Source。
Exec Source
以运行Linux命令的方式,持续的输出最新的数据,如tail -F 文件名指令,在这种方式下,取的文件名必须是指定的。
Spool Source
是监测配置的目录下系新增的文件,并将文件中的数据读取出来。
使用Spool Source需要注意:
1、拷贝到spool目录下的文件不可以再打开编辑。
2、spool目录下不可包含相应的子目录。
Spool Source如何使用?
在实际使用的过程中,可以结合log4j使用,使用log4j的时候,将log4j的文件分割机制设为1分钟一次,将文件拷贝到spool的监控目录。log4j有一个TimeRolling的插件,可以把log4j分割的文件到spool目录。基本实现了实时的监控。Flume在传完文件之后,将会修改文件的后缀,变为.COMPLETED(后缀也可以在配置文件中灵活指定)。
Exec Source和Spool Source比较
1、ExecSource可以实现对日志的实时收集,但是存在Flume不运行或者指令执行错误时,将无法收集到日志数据,无法保证日志数据的完整性。
2、SpoolSource虽然无法实现实时的收集数据,但是可以使用以分钟的方式分割文件,趋近于实时。
3、总结:如果应用无法实现以分钟切割日志文件的话,可以两种收集方式结合使用。
Flume Sink取出Channel中的数据,进行相应的存储文件系统,数据库,或者提交到远程服务器。
Flume也提供了各种sink的实现,包括HDFS sink、Logger sink、Avro sink、File Roll sink、Null sink、HBase sink,etc。
Flume Sink在设置存储数据时,可以向文件系统中,数据库中,Hadoop中存储数据,在日志数据较少时,可以将数据存储在文件系统中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。
Flume Channel主要提供一个队列的功能,对source提供中的数据进行简单的缓存。
Flume对于Channel,则提供了Memory Channel,JDBC Channel,File Channel,etc。
Memory Channel可以实现高速的吞吐,但是无法保证数据的完整性。
Memory Recover Channel在官方文档的建议上建议使用File Channel来替换。
File Channel保证数据的完整性与一致性。在具体配置不现的File Channel时,建议File Channel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率。
应用案例
Flume的安装很简单,下载安装包,解压,配置Java_Home等。
需求:应用程序将日志输出到本地给定路径的文件中,将该文件中的内容采集到Kafka中
#flume-kafka
#source's name
agent.sources=sc
#sink's name
agent.sinks=sk
#channel's name
agent.channels=chl
# info of source
agent.sources.sc.type=exec
agent.sources.sc.channels=chl
agent.sources.sc.command=tail -f /root/test.log
agent.sources.sc.fileHeader=false
#info of channel
agent.channels.chl.type=memory
agent.channels.chl.capacity=1000
agent.channels.chl.transactionCapacity=1000
#info of sink
agent.sinks.sk.type=org.apache.flume.sink.kafka.KafkaSink
agent.sinks.sk.channel=chl
agent.sinks.sk.kafka.bootstrap.servers=10.108.21.2:9092
agent.sinks.sk.kafka.topic=flume-kafka
agent.sinks.sk.serializer.class=kafka.serializer.StringEncoder
agent.sinks.sk.kafka.producer.acks=1
agent.sinks.sk.custom.encoding=utf-8
测试:
#创建主题
[root@master kafka]# bin/kafka-topics.sh --create --zookeeper master:2181,slave1:2181 --topic flume-kafka -partitions 1 -replication-factor 1
Created topic "flume-kafka".
#启动flume
[root@master flume]# bin/flume-ng agent --conf /root/software/flume/conf --conf-file conf/flume-kafka.properties --name agent -Dflume.root.logger=INFO,console
Info: Sourcing environment configuration script /root/software/flume/conf/flume-env.sh
#向日志文件中写数据
[root@master ~]# echo "hello world">>test.log
#Kafka进行消费
[root@master kafka]# bin/kafka-console-consumer.sh --bootstrap-server 10.108.21.2:9092 --topic flume-kafka
hello world
有疑问欢迎留言!