数据采集模块
用户行为日志数据采集
这里详细介绍了如何采集用户行为日志
一、行为日志对应架构图说明
项目总架构图中该部分对应了用户行为采集,首先,通过前端埋点等方式(同时采用了Nginx负载均衡),获取用户的行为数据,并将行为数据存放到文件中,再通过Flume将数据传输到Kafka中,之后再通过一个Flume将数据传输到HDFS里。
二、用户行为日志数据从哪里来?
用户行为日志一般通过埋点的方式获得,数据存放在磁盘里的文件中。
三、行为日志采集规划
1.数据采集通道规划
说明:hadoop102和hadoop103作为日志服务器,用户行为数据存放在这两个服务器中的文件里,每个服务器启动一个Flume作为消息的生产者(这是相对于Kafka来说的),将数据传输到Kafka的topic_log这个topic中,之后在hadoop104这个服务器中启动一个Flume,将所有的行为日志数据传输到HDFS中(这里的Flume相当于消费者,从Kafka中拿数据)。
四、File—Flume—Kafka实现
这里先说明从文件到Flume再到Kafka这个流程
1.Flume安装规划
hadoop102:Flume(作为生产者)
hadoop103:Flume(作为生产者)
hadoop104:不做处理
2.Source选型
1.TailDir Source:可以实时监控一批文件,并记录每个文件的最新的消费问题,宕机重启后不会有重复消费问题(现在基本上都用这个)。
2.Exec Source:适用于监控一个实时追加的文件,不能实现断点续传。
3.Spooling Directory Source:可以监听一个目录,对目录下的新文件可以进行同步,同步完的文件被打上标记,之后不会再进行同步。不适合实时追加日志文件的同步。
综上,这里的Flume采用TailDir Source。
3.Channel选型
1.File Channel:将所有事件写到磁盘,可靠性较高,宕机后数据不会丢失,但是效率较低。
2.Memory Channel:将数据存储到内存中,可靠性较低,宕机后数据丢失,但是效率较高。
3.Kafka Channel:将数据存储在Kafka集群中,即存储到磁盘中
4.Kafka Channel分析
Kafka Channel有三种类型:
1.有source和sink
数据流程:从source到kafka channel再传入到kafka中的topic,读取数据时要从kafka的topic中到sink(跨节点通信)
2.有source没有sink(这里kafka channel相当于生产者)
数据流程:从source到kafka channel在传入到Kafka中的topic,省去了sink的操作,性能要好一点
3.没有source有sink(这里kafka channel相当于消费者)
数据流程:kafka channel直接从kafka中topic读取数据,省去了source(没办法写拦截器了)
综上,这里采用有source无sink的kafka source方式。
注意:kafka source中有一个参数parseAsFlumeEvent,该参数为true时,会把event的head+body一起放到kafka中;为false时,只会把event的body放到kafka中。(我们希望存放到kafka中的数据只是日志数据而不含有头信息,因此需要将该参数设置为false)
5.Flume到Kafka的配置规划
配置关键点:
这里LogInterceptor做简单的数据清洗操作(Flume是一个管道,如果做过于复杂的数据清洗操作,可能会发生数据堵塞的情况)
6.Flume到Kafka配置文件
配置文件代码:
#为各组件命名
a1.sources = r1
a1.channels = c1
#描述source
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = f1 (监控的文件夹组)
a1.sources.r1.filegroups.f1 = /opt/module/applog/log/app.* (监控的文件路径,正则匹配,以app开头的所有文件)
a1.sources.r1.positionFile = /opt/module/flume/taildir_position.json (flume下的固定路径)
a1.sources.r1.interceptors =i1 (ETL数据清洗,判断JSON是否完整)
a1.sources.r1.interceptors.i1.type = com.atguigu.flume.interceptor.ETLInterceptor$Builder
#描述channel
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.kafka.bootstrap.servers = hadoop102:9092,hadoop103:9092 (可以写1个地址,也可以写多个地址)
a1.channels.c1.kafka.topic = topic_log
a1.channels.c1.parseAsFlumeEvent = false (是否保持flume传过来的数据格式,这里设置只要body)
#绑定source和channel以及sink和channel的关系
a1.sources.r1.channels = c1