在一个完整的离线大数据处理系统中,除了hdfs+mapreduce+hive组成分析系统的核心之外,还需要数据采集、结果数据导出、任务调度等不可或缺的辅助系统,而这些辅助工具在hadoop生态体系中都有便捷的开源框架,如图所示:
因此,flume可以适用于大部分的日常数据采集场景。
宏观角度来看类似生活中的
扫码枪
吸尘器吸头
1、Flume分布式系统中最核心的角色是agent,flume采集系统就是由一个个agent所连接起来形成
2、每一个agent相当于一个数据传递员,内部有三个组件:
<1>Source:采集组件,用于跟数据源对接,以获取数据
<2>Channel:传输通道组件,用于从source将数据传递到sink
<3>Sink:下沉组件,用于往下一级agent传递数据或者往最终存储系统传递数据
Source 到 Channel 到 Sink之间传递数据的形式是Event事件;Event事件是一个数据流单元。
单个agent采集数据
多级agent之间串联
Flume的安装非常简单,只需要解压即可,当然,前提是已有hadoop环境。
上传安装包到数据源所在节点上
这里我们采用在第三台机器来进行安装
上传安装文件并解压
tar -zxvf flume-ng-1.6.0-cdh5.14.0.tar.gz -C /export/servers/ cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf cp flume-env.sh.template flume-env.sh vim flume-env.sh
在文件中配置一下JDK的安装路径export JAVA_HOME=/export/servers/jdk1.8.0_141
案例:使用网络telent命令向一台机器发送一些网络数据,然后通过flume采集网络端口数据
根据数据采集的需求配置采集方案,描述在配置文件中(文件名可任意自定义)
配置我们的网络收集的配置文件
在flume的conf目录下新建一个配置文件(采集方案)
vim /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf/netcat-logger.conf
# 定义这个agent中各组件的名字 a1.sources = r1 a1.sinks = k1 a1.channels = c1 # 描述和配置source组件:r1 a1.sources.r1.type = netcat a1.sources.r1.bind = 192.168.52.120 a1.sources.r1.port = 44444 # 描述和配置sink组件:k1 a1.sinks.k1.type = logger # 描述和配置channel组件,此处使用是内存缓存的方式 a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # 描述和配置source channel sink之间的连接关系 a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
Channel参数解释:
capacity:默认该通道中最大的可以存储的event数量 trasactionCapacity:每次最大可以从source中拿到或者送到sink中的event数量
指定采集方案配置文件,在相应的节点上启动flume agent
先用一个最简单的例子来测试一下程序环境是否正常
启动agent去采集数据
bin/flume-ng agent -c conf -f conf/netcat-logger.conf -n a1 -Dflume.root.logger=INFO,console
其中:
-c conf 指定flume自身的配置文件所在目录
-f conf/netcat-logger.con 指定我们所描述的采集方案
-n a1 指定我们这个agent的名字
在node02机器上面安装telnet客户端,用于模拟数据的发送
yum -y install telnet telnet node03 44444 # 使用telnet模拟数据发送
结构示意图如下:
采集需求:
某服务器的某特定目录下,会不断产生新的文件,每当有新文件出现,就需要把文件采集到HDFS中去
根据需求,首先定义以下3大要素
配置文件编写:
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf mkdir -p /export/servers/dirfile vim spooldir.conf
# Name the components on this agent a1.sources=r1 a1.channels=c1 a1.sinks=k1 # Describe/configure the source ##注意:不能往监控目中重复丢同名文件 a1.sources.r1.type=spooldir a1.sources.r1.spoolDir=/export/dir a1.sources.r1.fileHeader = true # Describe the sink a1.sinks.k1.type=hdfs a1.sinks.k1.hdfs.path=hdfs://node01:8020/spooldir/ # Describe the channel 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
bin/flume-ng agent -c ./conf -f ./conf/spooldir.conf -n a1 -Dflume.root.logger=INFO,console
将不同的文件上传到下面目录里面去,注意文件不能重名
cd /export/dir
采集需求:比如业务系统使用log4j生成的日志,日志内容不断增加,需要把追加到日志文件中的数据实时采集到hdfs
根据需求,首先定义以下3大要素
node03开发配置文件cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim tail-file.conf
配置文件内容
a1.sources=r1 a1.channels=c1 a1.sinks=k1 # Describe/configure tail -F source1 a1.sources.r1.type=exec a1.sources.r1.command =tail -F /export/taillogs/access_log # Describe sink1 a1.sinks.k1.type=hdfs a1.sinks.k1.hdfs.path=hdfs://node01:8020/spooldir/ # 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
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -c conf -f conf/tail-file.conf -n a1 -Dflume.root.logger=INFO,console
mkdir -p /export/shells/ cd /export/shells/ vim tail-file.sh
#!/bin/bash while true do date >> /export/servers/taillogs/access_log; sleep 0.5; done
创建文件夹mkdir -p /export/servers/taillogs
启动脚本mkdir -p /export/servers/taillogs
第一个agent负责收集文件当中的数据,通过网络发送到第二个agent当中去,第二个agent负责接收第一个agent发送的数据,并将数据保存到hdfs上面去
将node03机器上面解压后的flume文件夹拷贝到node02机器上面去
cd /export/servers scp -r apache-flume-1.6.0-cdh5.14.0-bin/ node02:$PWD
在node02机器配置我们的flume
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim tail-avro-avro-logger.conf
################## # Name the components on this agent a1.sources = r1 a1.sinks = k1 a1.channels = c1 # Describe/configure the source a1.sources.r1.type = exec a1.sources.r1.command = tail -F /export/taillogs/access_log # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 ## `sink端的avro是一个数据发送者` a1.sinks.k1.type = avro a1.sinks.k1.hostname = 192.168.52.120 a1.sinks.k1.port = 4141 #Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
直接将node03下面的脚本和数据拷贝到node02即可,node03机器上执行以下命令
cd /export scp -r shells/ taillogs/ node02:$PWD
在node03机器上开发flume的配置文件
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim avro-hdfs.conf
# Name the components on this agent a1.sources = r1 a1.sinks = k1 a1.channels = c1 ##source中的avro组件是一个接收者服务 a1.sources.r1.type = avro a1.sources.r1.bind = 192.168.52.120 a1.sources.r1.port = 4141 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Describe the sink a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://node01:8020/avro # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
node03机器启动flume进程
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -c conf -f conf/avro-hdfs.conf -n a1 -Dflume.root.logger=INFO,console
node02机器启动flume进程
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/ bin/flume-ng agent -c conf -f conf/tail-avro-avro-logger.conf -n a1 -Dflume.root.logger=INFO,console
node02机器启shell脚本生成文件mkdir /export/taillogs/
cd /export/servers/shells
sh tail-file.sh
Flume支持众多的source和sink类型,详细手册可参考官方文档http://archive.cloudera.com/cdh5/cdh/5/flume-ng-1.6.0-cdh5.14.0/FlumeUserGuide.html
在完成单点的Flume NG搭建后,下面我们搭建一个高可用的Flume NG集群,架构图如下所示:
图中,我们可以看出,Flume的存储可以支持多种,这里只列举了HDFS和Kafka(如:存储最新的一周日志,并给Storm系统提供实时日志流)。
Flume的Agent和Collector分布如下表所示:
图中所示,Agent1数据分别流入到Collector1和Collector2,Flume NG本身提供了Failover机制,可以自动切换和恢复。在上图中,有3个产生日志服务器分布在不同的机房,要把所有的日志都收集到一个集群中存储。下 面我们开发配置Flume NG集群
将node03机器上面的flume安装包以及文件生产的两个目录拷贝到node01机器上面去
node03机器执行以下命令
cd /export/servers scp -r apache-flume-1.6.0-cdh5.14.0-bin/ node01:$PWD cd /export scp -r shells/ taillogs/ node01:$PWD
node01机器配置agent的配置文件
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim agent.conf
#agent1 name agent1.channels = c1 agent1.sources = r1 agent1.sinks = k1 k2 # ##set gruop agent1.sinkgroups = g1 ##set sink group agent1.sinkgroups.g1.sinks = k1 k2 # agent1.sources.r1.type = exec agent1.sources.r1.command = tail -F /export/taillogs/access_log # ##set channel agent1.channels.c1.type = memory agent1.channels.c1.capacity = 1000 agent1.channels.c1.transactionCapacity = 100 ## set sink1 agent1.sinks.k1.type = avro agent1.sinks.k1.hostname = node02 agent1.sinks.k1.port = 52020 # ## set sink2 agent1.sinks.k2.type = avro agent1.sinks.k2.hostname = node03 agent1.sinks.k2.port = 52020 # ##set failover agent1.sinkgroups.g1.processor.type = failover agent1.sinkgroups.g1.processor.priority.k1 = 2 agent1.sinkgroups.g1.processor.priority.k2 = 1 agent1.sinkgroups.g1.processor.maxpenalty = 10000 # agent1.sources.r1.channels = c1 agent1.sinks.k1.channel = c1 agent1.sinks.k2.channel = c1
其中,maxpenalty故障转移的默认时间
node02机器修改配置文件
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim collector.conf
#set Agent name a1.sources = r1 a1.channels = c1 a1.sinks = k1 ## other node,nna to nns a1.sources.r1.type = avro a1.sources.r1.bind = node02 a1.sources.r1.port = 52020 ##set channel a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # ##set sink to hdfs a1.sinks.k1.type=hdfs a1.sinks.k1.hdfs.path= hdfs://node01:8020/flume/failover/ a1.sources.r1.channels=c1 a1.sinks.k1.channel=c1
node03机器修改配置文件
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim collector.conf
#set Agent name a1.sources = r1 a1.channels = c1 a1.sinks = k1 ## other node,nna to nns a1.sources.r1.type = avro a1.sources.r1.bind = node03 a1.sources.r1.port = 52020 ##set channel a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # ##set sink to hdfs a1.sinks.k1.type=hdfs a1.sinks.k1.hdfs.path= hdfs://node01:8020/flume/failover/ a1.sources.r1.channels=c1 a1.sinks.k1.channel=c1
node03机器上面启动flume
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n a1 -c conf -f conf/collector.conf -Dflume.root.logger=DEBUG,consolenode02机器上面启动flume
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n a1 -c conf -f conf/collector.conf -Dflume.root.logger=DEBUG,console
node01机器上面启动flume
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n agent1 -c conf -f conf/agent.conf -Dflume.root.logger=DEBUG,console
node01机器启动文件产生脚本
cd /export/shells sh tail-file.sh
下面我们来测试下Flume NG集群的高可用(故障转移)。场景如下:我们在Agent1节点上传文件,由于我们配置Collector1的权重比Collector2大,所以 Collector1优先采集并上传到存储系统。然后我们kill掉Collector1,此时有Collector2负责日志的采集上传工作,之后,我 们手动恢复Collector1节点的Flume服务,再次在Agent1上次文件,发现Collector1恢复优先级别的采集工作。具体截图如下所 示:
lector1优先上传
HDFS集群中上传的log内容预览
Collector1宕机,Collector2获取优先上传权限
重启Collector1服务,Collector1重新获得优先上传的权限
负载均衡是用于解决一台机器(一个进程)无法解决所有请求而产生的一种算法。Load balancing Sink Processor 能够实现 load balance 功能,如下图Agent1 是一个路由节点,负责将 Channel 暂存的 Event 均衡到对应的多个 Sink组件上,而每个 Sink 组件分别连接到一个独立的 Agent 上
在此处我们通过三台机器来进行模拟flume的负载均衡
三台机器规划如下:
node01:采集数据,发送到node02和node03机器上去 node02:接收node01的部分数据 node03:接收node01的部分数据
node01服务器配置:
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim load_banlancer_client.conf
#agent name a1.channels = c1 a1.sources = r1 a1.sinks = k1 k2 #set gruop a1.sinkgroups = g1 #set sink group a1.sinkgroups.g1.sinks = k1 k2 #set sources a1.sources.r1.type = exec a1.sources.r1.command = tail -F /export/taillogs/access_log #set channel a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # set sink1 a1.sinks.k1.type = avro a1.sinks.k1.hostname = node02 a1.sinks.k1.port = 52021 # set sink2 a1.sinks.k2.type = avro a1.sinks.k2.hostname = node03 a1.sinks.k2.port = 52021 #set failover a1.sinkgroups.g1.processor.type = load_balance a1.sinkgroups.g1.processor.backoff = true a1.sinkgroups.g1.processor.selector = round_robin a1.sinkgroups.g1.processor.selector.maxTimeOut=10000 a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 a1.sinks.k2.channel = c1
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin/conf vim load_banlancer_server.conf
# Name the components on this agent a1.sources = r1 a1.sinks = k1 a1.channels = c1 # Describe/configure the source a1.sources.r1.type = avro a1.sources.r1.bind = node02 a1.sources.r1.port = 52021 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Describe the sink a1.sinks.k1.type = logger # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
启动node03的flume服务
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n a1 -c conf -f conf/load_banlancer_server.conf -Dflume.root.logger=DEBUG,console
启动node02的flume服务
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n a1 -c conf -f conf/load_banlancer_server.conf -Dflume.root.logger=DEBUG,console
启动node01的flume服务
cd /export/servers/apache-flume-1.6.0-cdh5.14.0-bin bin/flume-ng agent -n a1 -c conf -f conf/load_banlancer_client.conf -Dflume.root.logger=DEBUG,console
cd /export/shells sh tail-file.sh
本次的分享就到这里了,大家有什么疑惑或者好的建议可以在评论区留言,另外从中受益的小伙伴们记得关注小菌哟!