二、离线数仓—数据采集模块


用户行为日志数据采集

这里详细介绍了如何采集用户行为日志

一、行为日志对应架构图说明

在这里插入图片描述
项目总架构图中该部分对应了用户行为采集,首先,通过前端埋点等方式(同时采用了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

7.配置文件中拦截器ETLInterceptor的实现

1.添加pom.xml依赖

<dependencies>
    <dependency>
        <groupId>org.apache.flume</groupId>
        <artifactId>flume-ng-core</artifactId>
        <version>1.9.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

2.编写校验json字符串是否正确的类

public class JSONUtils {
    public static boolean isJSONValidate(String log){
        try {
            JSON.parse(log);
            return true;
        }catch (JSONException e){
            return false;
        }
    }
}

3.拦截器代码

public class ETLInterceptor implements Interceptor {

    @Override
    public void initialize() {

    }

    @Override
    public Event intercept(Event event) {

        byte[] body = event.getBody();
        String log = new String(body, StandardCharsets.UTF_8);

        if (JSONUtils.isJSONValidate(log)) {
            return event;
        } else {
            return null;
        }
    }

    @Override
    public List<Event> intercept(List<Event> list) {

        Iterator<Event> iterator = list.iterator();

        while (iterator.hasNext()){
            Event next = iterator.next();
            if(intercept(next)==null){
                iterator.remove();
            }
        }
        return list;
    }

    public static class Builder implements Interceptor.Builder{

        @Override
        public Interceptor build() {
            return new ETLInterceptor();
        }
        @Override
        public void configure(Context context) {

        }

    }

    @Override
    public void close() {

    }
}

7.启动运行

将拦截器代码打包,放到服务器flume/lib文件夹下(分发到hadoop102和hadoop103上),启动flume和对应文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值