flume-kafka数据采集
概述
今天来给大家展示一下,日常数据收集中,我们flume和kafka是如何协同工作的。
我们先来看一下整体集群情况。
hadoop102 | hadoop103 | hadoop104 |
---|---|---|
zk | zk | zk |
namenode | resourcemanager | secondarynamenode |
datanode | datanode | datanode |
kafka | kafka | kafka |
application | application | application |
nodemanager | nodemanager | nodemanager |
以上是整个进群的配置
接下来我们来收集日志的数据
我们在实际开发中,一般将其分为两个步骤,
(1)数据生产阶段(采集日志到kafka)
(2)数据消费阶段(消费kafka中的数据到hdfs)
从上图中,我们可以清晰看到我们将其拆分为两个flume阶段。
数据生产阶段(采集日志到kafka)
我们先走一下第一个阶段,大家先来看一简单的拓扑图
上图中我们可以简单看出来,我们由两种方案可以选择使用,但其第二种明显优势突出,那我们就使用第二种了。
直接上代码了
哦,对了,我们采集的是电商的数据,所以需要我们自己写一个拦截器,过滤掉不符号的数据public class LogInterceptor implements Interceptor { @Override public void initialize() { } /** * 判数据是否是json格式的 * @param event * @return */ @Override public Event intercept(Event event) { String body = new String(event.getBody(), StandardCharsets.UTF_8); try { JSON.parse(body); }catch (JSONException exception){ return null; } return event; } /** * 集合中删除某个元素不能使用集合原有的迭代循环,可以进行修改,或者使用迭代器的方式进行删除 * @param events * @return */ @Override public List<Event> intercept(List<Event> events) { Iterator<Event> iterator = events.iterator(); while (iterator.hasNext()){ Event currentEvent = iterator.next(); Event resultEvent = intercept(currentEvent); if (resultEvent == null){ iterator.remove(); } } return events; } @Override public void close() { } public static class MyBuilder implements Builder{ @Override public Interceptor build() { return new LogInterceptor(); } @Override public void configure(Context context) { } } }
把拦截器打包放到flume的lib目录下就可以了。
ok,接下来上配置文件#name a1.sources = r1 a1.channels = c1 #sources a1.sources.r1.type = TAILDIR a1.sources.r1.filegroups = g1 a1.sources.r1.filegroups.g1 = /opt/module/applog/log/app.* a1.sources.r1.positionFile = /opt/module/flume-1.9.0/taildir_position.json a1.sources.r1.batchSize = 500 #interceptor a1.sources.r1.interceptors = i1 a1.sources.r1.interceptors.i1.type = com.atguigu.flume.interceptor.LogInterceptor$MyBuilder #channel a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel a1.channels.c1.kafka.bootstrap.servers = hadoop102:9092,hadoop103:9092 a1.channels.c1.kafka.topic = topic_log a1.channels.c1.parseAsFlumeEvent = false #bind a1.sources.r1.channels = c1
我们使用两台服务器作为采集的服务器,即102和103
所以将配置文件分发给103一份[atguigu@hadoop102 bin]$ scp -r /opt/module/flume-1.9.0/dwh/logger-flume-kafka.conf atguigu@hadoop103:/opt/module/flume-1.9.0/dwh/
我们知道,如果启动flume采集数据的话,它会阻塞到命令行端口,所以我们编写一下采集数据的启停脚本
#! /bin/bash if [ $# -lt 1 ] then echo 'USAGE: f1.sh(start|stop)' exit fi case $1 in start) for i in hadoop102 hadoop103 do ssh $i nohup /opt/module/flume-1.9.0/bin/flume-ng agent -c /opt/module/flume-1.9.0/conf/ -f /opt/module/flume-1.9.0/dwh/logger-flume-kafka.conf -n a1 >//opt/module/flume-1.9.0/logs/flume.log 2>&1 & done ;; stop) for i in hadoop102 hadoop103 do ssh $i "ps -ef | grep logger-flume-kafka.conf | grep -v grep | awk '{print \$2}' | xargs -n1 kill -9" done ;; *) echo 'USAGE: f1.sh(start|stop)' exit exit ;; esac
数据消费阶段(消费kafka中的数据,并将其存储到hdfs)
ok,到这里数据的采集已经欧克了,结下了就要开始消费数据并存储到hdfs了,以便后边我们进行分析。
老样子,我们来看一下拓扑图简单的了解一下
虽然第二种方式优势突出,但是我们得雨露均沾不是,哈哈哈,使用第一种方式来。。。
我们使用104服务器来消费kafka中得数据#name a1.sources = r1 a1.channels = c1 a1.sinks = k1 #source a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource a1.sources.r1.batchSize = 5000 a1.sources.r1.batchDurationMillis = 2000 a1.sources.r1.kafka.bootstrap.servers = hadoop102:9092,hadoop103:9092,hadoop104:9092 a1.sources.r1.kafka.topics = topic_log #channel a1.channels.c1.type = file a1.channels.c1.checkpointDir = /opt/module/flume-1.9.0/checkpoint/behavior1 a1.channels.c1.dataDirs = /opt/module/flume-1.9.0/data/behavior1/ #文件的最大内存 a1.channels.c1.maxFileSize = 2146435071 #内存存队列的最大容量 a1.channels.c1.capacity = 1000000 a1.channels.c1.keepalive = 6 #sink a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = /origin_data/gmall/log/topic_log/%Y-%m-%d a1.sinks.k1.hdfs.filePrefix = log- a1.sinks.k1.hdfs.round = false a1.sinks.k1.hdfs.rollInterval = 10 a1.sinks.k1.hdfs.rollSize = 134217728 a1.sinks.k1.hdfs.rollCount = 0 #控制输出文件是原生文件 a1.sinks.k1.hdfs.fileType = CompressedStream a1.sinks.k1.hdfs.codeC = lzop #bind a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
以上的配置我们在其 官网都可以找的到的。
同样的我们也需要写一个脚本#! /bin/bash if [ $# -lt 1 ] then echo 'USAGE: f2.sh(start|stop)' exit fi case $1 in start) for i in hadoop104 do ssh $i nohup /opt/module/flume-1.9.0/bin/flume-ng agent -c /opt/module/flume-1.9.0/conf/ -f /opt/module/flume-1.9.0/dwh/kafka-file-hdfs.conf -n a1 >//opt/module/flume-1.9.0/logs/flume.log 2>&1 & done ;; stop) for i in hadoop104 do ssh $i "ps -ef | grep kafka-file-hdfs.conf | grep -v grep | awk '{print \$2}' | xargs -n1 kill -9" done ;; *) echo 'USAGE: f2.sh(start|stop)' exit exit ;; esac
以上操作完后,整个输出采集的通道就打通了,感谢大家近期的关注。
哈哈,祝大家中秋节快乐😄😄