CC00029.pbpositions——|Hadoop&PB级数仓.V13|——|PB数仓.v13|会员活跃度分析|Hive on MR&活跃&新增&留存会员|数据加载|

本文介绍了使用Hadoop处理PB级别的数据仓库,通过Flume采集数据到HDFS,并利用Hive on MapReduce进行会员活跃度、新增及留存会员的分析。详细步骤包括数据加载、计算实例以及遇到的错误处理。
摘要由CSDN通过智能技术生成
一、高仿日启动数据测试:
### --- 高防日启动数据测试

~~~     数据采集 => ODS => DWD => DWS => ADS> MySQL
~~~     活跃会员、新增会员、会员留存
~~~     DAU: Daily Active User(日活跃用户)
~~~     MAU: monthly active user(月活跃用户)
~~~     假设App的DAU在1000W左右,日启动数据大概 1000W 条;
~~~     测试3天的数据:7月21日、7月22日、7月23日。1000W条数据约3.5G+,每条记录约370字节。
### --- 实验概述

~~~     选择 7月21日 的启动日志进行测试
~~~     使用 flume 采集数据(采集3天的数据)
~~~     修改flume的参数:1G滚动一次;加大channel缓存;加大刷新 hdfs 的缓存
二、Flume采集数据:hive通过Flume采集数据到hdfs下
### --- 创建flume配置conf文件:建议配置参数
~~~     # 建议配置:
~~~     # 自己环境可根据实际情况调节

# 配置文件滚动方式(文件大小1G)
a1.sinks.k1.hdfs.rollSize = 1073741824
a1.channels.c1.capacity = 500000
a1.channels.c1.transactionCapacity = 20000

# 向hdfs上刷新的event个数
a1.sinks.k1.hdfs.batchSize = 10000
### --- 创建Flume配置文件

[root@hadoop02 ~]# vim /data/yanqidw/conf/flume-log2hdfs4.conf
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# taildir source
a1.sources.r1.type = TAILDIR
a1.sources.r1.positionFile = /data/yanqidw/conf/startlog_position.json
a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1 = /data/yanqidw/logs/start/.*log
a1.sources.r1.headers.f1.logtype = start
a1.sources.r1.filegroups.f2 = /data/yanqidw/logs/event/.*log
a1.sources.r1.headers.f2.logtype = event

# 自定义拦截器
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = cn.yanqi.dw.flume.interceptor.LogTypeInterceptor$Builder

# memorychannel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 100000
a1.channels.c1.transactionCapacity = 2000

# hdfs sink
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /user/data/logs/%{logtype}/dt=%{logtime}/
a1.sinks.k1.hdfs.filePrefix = startlog
a1.sinks.k1.hdfs.fileType = DataStream

# 配置文件滚动方式(文件大小10M)(环境资源有限,生产环境根据实际情况来定,不然会造成很多小文件)
a1.sinks.k1.hdfs.rollSize = 10240000
a1.sinks.k1.hdfs.rollCount = 0
a1.sinks.k1.hdfs.rollInterval = 0
a1.sinks.k1.hdfs.idleTimeout = 0
a1.sinks.k1.hdfs.minBlockReplicas = 1

# 向hdfs上刷新的event的个数
a1.sinks.k1.hdfs.batchSize = 10000

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
三、Flume采集数据:hive通过Flume采集数据到hdfs下
### --- 清理工作:
~~~     清理本地环境
~~~     删除本地元数据文件、日志、hdfs等文件

rm -rf /data/yanqidw/conf/startlog_position.json
rm -rf /data/yanqidw/logs/start/*
rm -rf /data/yanqidw/logs/event/*
~~~     # 清理hdfs数据

hdfs dfs -rm -r -f /user/data/logs/start/dt=2020-07-21
hdfs dfs -rm -r -f /user/data/logs/start/dt=2020-07-22
hdfs dfs -rm -r -f /user/data/logs/start/dt=2020-07-23
### --- 启动flume
~~~     # 启动historyserver
/opt/yanqi/servers/hadoop-2.9.2/sbin/mr-jobhistory-daemon.sh start historyserver

~~~     # 启动flume
flume-ng agent --conf /opt/yanqi/servers/flume-1.9.0/conf \
--conf-file /data/yanqidw/conf/flume-log2hdfs4.conf \
-name a1 -Dflume.root.logger=INFO,console
### --- 写入日志数据
~~~     # 写日志:
~~~     该代码是更改日志时间为特定时间

cd /data/yanqidw/jars/
java -cp data-generator-1.1-SNAPSHOT-jar-with-dependencies.jar \
com.yanqi.ecommerce.AppStart 1 10000000 2020-07-21 \
>/data/yanqidw/logs/start/start0721.log

java -cp data-generator-1.1-SNAPSHOT-jar-with-dependencies.jar \
com.yanqi.ecommerce.AppStart 6000000 16000000 2020-07-22 \
>/data/yanqidw/logs/start/start0722.log

java -cp data-generator-1.1-SNAPSHOT-jar-with-dependencies.jar \
com.yanqi.ecommerce.AppStart 8000000 18000000 2020-07-23 \
>/data/yanqidw/logs/start/start0723.log
### --- 检查hdfs文件是否到达
~~~     检查 hdfs 文件是否到达
~~~     1个文件大小3.5G,时间4分钟左右

[root@hadoop02 ~]# hdfs dfs -ls /user/data/logs/start/dt=2020-07-21
Found 4 items
-rw-r--r--   5 root supergroup   10268344 2021-10-02 21:58 /user/data/logs/start/dt=2020-07-21/startlog..1633183121972
-rw-r--r--   5 root supergroup   10268071 2021-10-02 21:58 /user/data/logs/start/dt=2020-07-21/startlog..1633183121973
-rw-r--r--   5 root supergroup   10268135 2021-10-02 21:58 /user/data/logs/start/dt=2020-07-21/startlog..1633183121974
-rw-r--r--   5 root supergroup    5885342 2021-10-02 22:22 /user/data/logs/start/dt=2020-07-21/startlog..1633183121975
四、Hive on MR
### --- 语法:向ODS层下加载数据:
~~~     执行脚本语法
~~~     定义脚本地址变量

SCRIPT_HOME=/data/yanqidw/script/member_active
~~~     # ODS层与HDFS下数据文件建立关联
~~~     # 加载 ODS 层数据(文件与表建立关联)

sh $SCRIPT_HOME/ods_load_startlog.sh 2020-07-21
### --- 语法:在DWD层下解析json数据
~~~     # 加载 ODS 层数据(解析json数据)
~~~     number of mappers: 14; number of reducers: 0
~~~     是一个 map-only 的 Task;只对输入的数据做格式上的转换,没有聚合操作(即没有reduce task)
~~~     mapred.max.split.size=256M;3.5G / 256M = 14 Mapper Task

sh $SCRIPT_HOME/dwd_load_startlog.sh 2020-07-21
### --- 语法:计算活跃会员
~~~     # 活跃会员
~~~     number of mappers: 3; number of reducers: 2
~~~     调整了task的内存分配(根据实际情况分配)
~~~     任务执行时间:3.5 + 3 + 3 = 10分钟
~~~     ODS(Text) => 14个map => DWD(parquet) => 小文件合并 256M切分 =>3 map

sh $SCRIPT_HOME/dws_load_member_start.sh 2020-07-21
sh $SCRIPT_HOME/ads_load_member_active.sh 2020-07-21
### --- 语法:计算新增会员
~~~     # 新增会员

sh $SCRIPT_HOME/dws_load_member_add_day.sh 2020-07-21
sh $SCRIPT_HOME/ads_load_member_add.sh 2020-07-21
### --- 语法:计算留存会员
~~~     # 会员留存

sh $SCRIPT_HOME/dws_load_member_retention_day.sh 2020-07-21
sh $SCRIPT_HOME/ads_load_member_retention.sh 2020-07-21
### --- 语法:查询相关表,数据是否映射成功。

select count(*) from ods.ods_start_log where dt='2020-07-21';
select count(*) from dwd.dwd_start_log where dt='2020-07-21';
select count(*) from dws.dws_member_start_day where dt='2020-07-21';
select count(*) from dws.dws_member_start_week where dt='2020-07-21';
select count(*) from dws.dws_member_start_month where dt='2020-07-21';
select count(*) from dws.dws_member_add_day where dt='2020-07-21';
select count(*) from dws.dws_member_retention_day where dt='2020-07-21';
select count(*) from ads.ads_member_active_count where dt='2020-07-21';
select count(*) from ads.ads_new_member_cnt where dt='2020-07-21';
select count(*) from ads.ads_member_retention_count where dt='2020-07-21';
select count(*) from ads.ads_member_retention_rate where dt='2020-07-21';
一、操作实例:向ODS层下加载数据
### --- 定义脚本地址变量

[root@hadoop02 ~]# SCRIPT_HOME=/data/yanqidw/script/member_active
### --- ODS层与HDFS下数据文件建立关联
~~~     # 加载 ODS 层数据(文件与表建立关联)

[root@hadoop02 ~]# sh $SCRIPT_HOME/ods_load_startlog.sh 2020-07-21
~~~     # 查看数据是否加载进来

hive (default)> show partitions ods.ods_start_log;
OK
partition
dt=2020-07-21
hive (default)> select count(*) from ods.ods_start_log where dt='2020-07-21' limit 10;
9999
二、操作实例:把数据从ODS层加载到DWD层中
### --- 把数据从ODS层加载到DWD层中
~~~     # 加载 ODS 层数据到DWD中(解析json数据)
~~~     number of mappers: 14; number of reducers: 0
~~~     是一个 map-only 的 Task;只对输入的数据做格式上的转换,没有聚合操作(即没有reduce task)
~~~     mapred.max.split.size=256M;3.5G / 256M = 14 Mapper Task

[root@hadoop02 ~]# sh $SCRIPT_HOME/dwd_load_startlog.sh 2020-07-21
hive (dwd)> set mapred.max.split.size;
mapred.max.split.size=256000000         # 取决于这个参数
### --- 查看数据是否加载dwd层
~~~     # 查看解析的数据

hive (default)> show partitions dwd.dwd_start_log;
partition
dt=2020-07-21

hive (default)> select count(*) from dwd.dwd_start_log where dt='2020-07-21';
9999                #  解析到的数据个数
三、操作实例:计算活跃会员
### --- 把活跃会员加载到dws层
~~~     # 活跃会员
~~~     number of mappers: 3; number of reducers: 2
~~~     调整了task的内存分配(根据实际情况分配)
~~~     任务执行时间:3.5 + 3 + 3 = 10分钟
~~~     ODS(Text) => 14个map => DWD(parquet) => 小文件合并 256M切分 =>3 map

[root@hadoop02 ~]# sh $SCRIPT_HOME/dws_load_member_start.sh 2020-07-21
### --- 查看活跃会员是否加载到DWS层

hive (default)> show partitions dws.dws_member_start_day;
partition
dt=2020-07-21
hive (default)> select count(*) from dws.dws_member_start_day where dt='2020-07-21';
9999

hive (default)> show partitions dws.dws_member_start_week;
partition
dt=2020-07-21
hive (default)> select count(*) from dws.dws_member_start_week where dt='2020-07-21';
9999

hive (default)> show partitions dws.dws_member_start_month;
partition
dt=2020-07-21
hive (default)> select count(*) from dws.dws_member_start_month where dt='2020-07-21';
9999
### --- 计算活跃会员

[root@hadoop02 ~]# sh $SCRIPT_HOME/ads_load_member_active.sh 2020-07-21
~~~     # 查看计算结果
~~~     对于第一天的数据来说,日活跃,周活跃,月活跃数据是一样的

hive (default)> show partitions ads.ads_member_active_count;
partition
dt=2020-07-21

hive (default)> select * from ads.ads_member_active_count where dt='2020-07-21';
ads_member_active_count.day_count   ads_member_active_count.week_count  ads_member_active_count.month_count ads_member_active_count.dt
9999    9999    9999    2020-07-21
四、操作实例:计算新增会员
### --- 把新增会员加载到dws层
~~~     # 加载新增会员到dws层

[root@hadoop02 ~]# sh $SCRIPT_HOME/dws_load_member_add_day.sh 2020-07-21
~~~     # 查看新增会员是否加载到dws层

hive (default)> select count(*) from dws.dws_member_add_day where dt='2020-07-21';
9999
### --- 计算新增会员

[root@hadoop02 ~]# sh $SCRIPT_HOME/ads_load_member_add.sh 2020-07-21
~~~     # 对于第一天的数据来说,日新增会员是一样的

hive (default)> show partitions ads.ads_new_member_cnt;
partition
dt=2020-07-21

hive (default)> select * from ads.ads_new_member_cnt where dt='2020-07-21';
ads_new_member_cnt.cnt  ads_new_member_cnt.dt
9999    2020-07-21
五、操作实例:计算留存会员
### --- 把留存会员加载到dws层

[root@hadoop02 ~]# sh $SCRIPT_HOME/dws_load_member_retention_day.sh 2020-07-21
~~~     # 查看留存会员是否加载到dws层

hive (default)> show partitions dws.dws_member_retention_day;
OK
partition
dt=2020-07-21
hive (default)> select count(*) from dws.dws_member_retention_day where dt='2020-07-21';
0           # 因为它是第一天,是没有留存率的,所以说是没有数据的
### --- 计算留存会员
~~~     是没有数据的,因为是第一天,所以说是没有数据的。
~~~     在执行其它的日期的时候会计算出来。

[root@hadoop02 ~]# sh $SCRIPT_HOME/ads_load_member_retention.sh 2020-07-21
hive (default)> show partitions ads.ads_member_retention_count;
partition
dt=2020-07-21

hive (default)> select * from ads.ads_member_retention_count where dt='2020-07-21';
OK
附录一:报错处理一
### --- 报错现象:
~~~     卡在这个位置不会动,数据没有加载
~~~     在执行这个的时候,把history打开,用于监控错误信息

[root@hadoop02 ~]# sh $SCRIPT_HOME/dwd_load_startlog.sh 2020-07-21
Cannot run job locally: Input Size (= 368902544) is larger than hive.exec.mode.local.auto.inputbytes.max (= 134217728)
2021-10-02 20:14:22,095 Stage-1 map = 0%,  reduce = 0%
附录二:报错处理二
### --- 报错现象
Error during job, obtaining debugging information...
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched: 
Stage-Stage-1:  HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec

~~~     # 通过historyserver查看报错现象
Error:Java heap space       # 内存比较小
### --- 报错分析:

~~~     内存分配问题
### --- 解决方案:

~~~     解决方案一:加大内存:合理的分配内存
~~~     解决方案二:调整map和reduce数量
### --- 解决方案一:
~~~     # 调整map和reduce数量方案一:通过修改yarn计算资源来限制

~~~     给map、reduce task分配合理的内存;
~~~     map、reduce task处理合理的数据现在情况下map task分配了多少内存?
~~~     使用的是缺省参数每个task分配200M内存【mapred.child.java.opts】
~~~     每个节点:8 core / 32G;mapred.child.java.opts = 3G
~~~     # 设置yarn集群的map和reduce分配合理内存的参数

[root@hadoop01 ~]# vim /opt/yanqi/servers/hadoop-2.9.2/etc/hadoop/yarn-site.xml
<!-- 设置map、reduce合理内存参数 -->
<property>
        <name>mapred.child.java.opts</name>
        <value>-Xmx3072m</value>
</property>
~~~     # 发送到其它节点
[root@hadoop01 ~]# rsync-script /opt/yanqi/servers/hadoop-2.9.2/etc/hadoop/yarn-site.xml

~~~     # 重启yarn服务
[root@hadoop01 ~]# stop-yarn.sh 
[root@hadoop01 ~]# start-yarn.sh
~~~     # 通过jps查看查看进程:YarnClid可以看到内存配置情况
[root@hadoop01 ~]# jps
17245 YarnClid

[root@hadoop01 ~]# ps -ef | grep 17245
~~~     输出配置参数
~~~ -Xmx3072m ~~~
### --- 解决方案二:
~~~     # 调整map和reduce数量方案二:通过脚本文件来限制

#   在hive下调整map个数:
    mapred.max.split.size=256000000
#   调整reduce个数:
    hive.exec.reducers.bytes.per.reducer
    hive.exec.reducers.max
~~~     # 配置参数:调整hive下map和reduce个数及大小

[root@hadoop02 ~]# vim  /data/yanqidw/script/member_active/dws_load_member_start.sh
hive \
-hiveconf mapred.max.split.size=128000000 \
-hiveconf hive.exec.reducers.bytes.per.reducer=128000000 \
-e "$sql"
### --- 解决方案三:
~~~     # 调整map和reduce数量方案三:通过修改hive-site.xml文件来限制

~~~     此方案是全局的参数,不建议使用。
~~~     若是使用此方案,会对其它人的作业参数影响。
~~~     建议使用脚本文件来调整,只影响当前作业。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanqi_vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值