离线数仓04—— 用户行为数据同步

文章目录

  • 第1章 实时数仓同步数据
  • 第2章 离线数仓同步数据
    • 2.1 用户行为数据同步
      • 2.1.1 数据通道
      • 2.1.2 日志消费Flume配置概述
      • 2.1.3 日志消费Flume配置实操
      • 2.1.4 日志消费Flume测试
      • 2.1.5 日志消费Flume启停脚本

上一篇: 离线数仓03——业务数据采集平台
下一篇: 离线数仓05—— 业务数据同步

第1章 实时数仓同步数据

实时数仓由Flink源源不断从Kafka当中读数据计算,所以不需要手动同步数据到实时数仓。

第2章 离线数仓同步数据

2.1 用户行为数据同步

2.1.1 数据通道

用户行为数据由Flume从Kafka直接同步到HDFS,由于离线数仓采用Hive的分区表按天统计,所以目标路径要包含一层日期。具体数据流向如下图所示。

离线数仓04—— 用户行为数据同步_第1张图片

2.1.2 日志消费Flume配置概述

按照规划,该Flume需将Kafka中topic_log的数据发往HDFS。并且对每天产生的用户行为日志进行区分,将不同天的数据发往HDFS不同天的路径。
此处选择KafkaSource、FileChannel、HDFSSink。
关键配置如下:

离线数仓04—— 用户行为数据同步_第2张图片

2.1.3 日志消费Flume配置实操

1)创建Flume配置文件
在hadoop104节点的Flume的job目录下创建kafka_to_hdfs_log.conf

[atguigu@hadoop104 flume]$ vim job/kafka_to_hdfs_log.conf 

2)配置文件内容如下

#定义组件
a1.sources=r1
a1.channels=c1
a1.sinks=k1

#配置source1
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
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.atguigu.gmall.flume.interceptor.TimestampInterceptor$Builder

#配置channel
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior1
a1.channels.c1.dataDirs = /opt/module/flume/data/behavior1
a1.channels.c1.maxFileSize = 2146435071
a1.channels.c1.capacity = 1000000
a1.channels.c1.keep-alive = 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 = gzip

#组装 
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

注:配置优化
1)FileChannel优化
通过配置dataDirs指向多个路径,每个路径对应不同的硬盘,增大Flume吞吐量。
官方说明如下:

Comma separated list of directories for storing log files. Using multiple directories on separate disks can improve file channel peformance

checkpointDir和backupCheckpointDir也尽量配置在不同硬盘对应的目录中,保证checkpoint坏掉后,可以快速使用backupCheckpointDir恢复数据

2)HDFS Sink优化

(1)HDFS存入大量小文件,有什么影响?

**元数据层面:**每个小文件都有一份元数据,其中包括文件路径,文件名,所有者,所属组,权限,创建时间等,这些信息都保存在Namenode内存中。所以小文件过多,会占用Namenode服务器大量内存,影响Namenode性能和使用寿命

**计算层面:**默认情况下MR会对每个小文件启用一个Map任务计算,非常影响计算性能。同时也影响磁盘寻址时间。

​ (2)HDFS小文件处理

官方默认的这三个参数配置写入HDFS后会产生小文件,hdfs.rollInterval、hdfs.rollSize、hdfs.rollCount

基于以上hdfs.rollInterval=3600,hdfs.rollSize=134217728,hdfs.rollCount =0几个参数综合作用,效果如下:

(1)文件在达到128M时会滚动生成新文件

(2)文件创建超3600秒时会滚动生成新文件

3)编写Flume拦截器

(1)数据漂移问题

离线数仓04—— 用户行为数据同步_第3张图片

(2)在com.atguigu.gmall.flume.interceptor包下创建TimestampInterceptor类
package com.atguigu.gmall.flume.interceptor;

import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

public class TimestampInterceptor implements Interceptor {
    

@Override
public void initialize() {

}

@Override
public Event intercept(Event event) {

	//1、获取header和body的数据
    Map headers = event.getHeaders();
    String log = new String(event.getBody(), StandardCharsets.UTF_8);

	//2、将body的数据类型转成jsonObject类型(方便获取数据)
   JSONObject jsonObject = JSONObject.parseObject(log);

	//3、header中timestamp时间字段替换成日志生成的时间戳(解决数据漂移问题)
    String ts = jsonObject.getString("ts");
    headers.put("timestamp", ts);

    return event;
}

@Override
public List intercept(List list) {
    for (Event event : list) {
        intercept(event);
    }
    return list;
}

@Override
public void close() {

}

public static class Builder implements Interceptor.Builder {
    @Override
    public Interceptor build() {
        return new TimestampInterceptor();
    }

    @Override
    public void configure(Context context) {
   	 }
	}
}

(3)重新打包

image-20221229094647971

(4)需要先将打好的包放入到hadoop104的/opt/module/flume/lib文件夹下面。

2.1.4 日志消费Flume测试

1)启动Zookeeper、Kafka集群
2)启动日志采集Flume

[atguigu@hadoop102 ~]$ f1.sh start

3)启动hadoop104的日志消费Flume

[atguigu@hadoop104 flume]$ bin/flume-ng agent -n a1 -c conf/ -f job/kafka_to_hdfs_log.conf -Dflume.root.logger=info,console

4)生成模拟数据

[atguigu@hadoop102 ~]$ lg.sh 

5)观察HDFS是否出现数据

2.1.5 日志消费Flume启停脚本

若上述测试通过,为方便,此处创建一个Flume的启停脚本。

1)在hadoop102节点的/home/atguigu/bin目录下创建脚本f2.sh
[atguigu@hadoop102 bin]$ vim f2.sh
	在脚本中填写如下内容
#!/bin/bash

case $1 in
"start")
        echo " --------启动 hadoop104 日志数据flume-------"
        ssh hadoop104 "nohup /opt/module/flume/bin/flume-ng agent -n a1 -c /opt/module/flume/conf -f /opt/module/flume/job/kafka_to_hdfs_log.conf >/dev/null 2>&1 &"
;;
"stop")

        echo " --------停止 hadoop104 日志数据flume-------"
        ssh hadoop104 "ps -ef | grep kafka_to_hdfs_log | grep -v grep |awk '{print \$2}' | xargs -n1 kill"

;;
esac
2)增加脚本执行权限
[atguigu@hadoop102 bin]$ chmod 777 f2.sh
3)f2启动
[atguigu@hadoop102 module]$ f2.sh start
4)f2停止
[atguigu@hadoop102 module]$ f2.sh stop
fka_to_hdfs_log | grep -v grep |awk '{print \$2}' | xargs -n1 kill"

;;
esac
2)增加脚本执行权限
[atguigu@hadoop102 bin]$ chmod 777 f2.sh
3)f2启动
[atguigu@hadoop102 module]$ f2.sh start
4)f2停止
[atguigu@hadoop102 module]$ f2.sh stop

你可能感兴趣的:(离线数仓,kafka,hadoop,大数据)