Record:我在某厂的奇幻漂流

Record:我在某厂的奇幻漂流

本文记录我在某大厂担任数据研发(DE)的实习经历。并记录完成的主要需求,以及产出成果。相关内容已脱敏处理,感谢我的mt和同事们这几个月来的帮助!本文持续更新中。。。

Task_id 1:早鸟版-优化表的运行时长

需求:原先表funnel的运行时长接近14个小时,主要原因是大funnel表太大了,聚合维度太高了,导致下游的看板产出时间太晚,不利于数据分析。要求看板的产出时间早于上午9:00.
思路1:对上游的funnel表进行调优。
参数调优:主要思路为对于大表需要尽可能增加并行度,所以通过优化3减小并行上限增加并行度,同时通过4、5增加reduce的最大并行度;通过6合并过程中的小文件的问题;尽可能减小大表join小表的时间,所以扩大广播join的阈值,让小表广播到其他节点上提高join效率;通过8、9给予executor的尽可能多的内存。

1:set hive.specify.execution.engine.enforce.name=spark;
2:set spark.io.compression.codec=zstd;
3:set spark.sql.adaptive.shuffle.targetPostShuffleInputSize=160000000;(默认256M)
4:set spark.sql.shuffle.partitions=6000;
5:set spark.sql.adaptive.maxNumPostShufflePartitions=6000;
6:set spark.sql.parquet.mergeV2=true;
7:set spark.sql.autoBroadcastJoinThreshold = 104857600;
8:set spark.executor.memory=16g;
9:set spark.executor.memoryOverhead = 12288;

聚合维度调优:在初版中产出的维度(Grouping sets)太多了,但是在看板中产出的维度远远不需要这么多,故对一些不需要的维度进行优化削减。
However!! 经过调优后仍然需要6个小时左右,时间太长了。发现拖慢进程的主要问题在于聚合下面这个维度的时候时间太长。
思路2:原来卡点在聚合维度下钻了两三层导致缓存很大,给后台调度带来很大压力。所以干脆只要核心的维度,只支持下钻一层维度的早鸟版,计算发送到达点击pv/uv和首活点击。
交付:早鸟版上线表一项,数据集一项,看板一项。

Task_id 2:push链路更新【重要】

需求:业务新增两个属性的映射。需要对一些下游作变更字段,同时分流一些下游。

要求:
1、创建excel2hive源表更新新的在线文档源,旧表废弃;
2、和其他部门的表沟通切换上游;
3、将新的属性带到下游的一些表中。
注意:
1、新表,同步Excel,上线
2、切下游的数据源(数据验证)
3、下游的表加字段(HUDI 表加字段)
4、业务明细冗余维度信息,做好数据验证(条数)
5、新上的表做好DQC配置,配置强规则(遇到条件不满足直接阻塞)

记录数不为0
波动监控
主键唯一

交付:源头维表,切换业务流。

Task_id 3:主要渠道下pad新回数量统计

需求:根据四个主要渠道计算六个指标,新回pad设备数量、同时统计出新回pad次留数量。
交付:日常上线表一项,数据集一项。

遇到的问题:在实现的过程中发现第一版得到的数据和看板的结果不一致。新相关字段的数值正确,回流相关的字段远小于对比。

解决:发现在底表中,新回设备的channel_type不同,新使用的是channel_type字段;回使用的是reflux_channel_type。

Task_id 4:funnel_attribution调优

问题:看spark日志发现堆外内存不足。
改进前的job运行,运行时间:2h33m
调优参数

set hive.specify.execution.engine.enforce.name=spark;
set spark.executor.memory=12g;
set spark.executor.memoryOverhead=6g;
set spark.driver.memory=12g;
set spark.driver.memoryOverhead=6g;
set spark.sql.adaptive.maxNumPostShufflePartitions=6000;
set sspark.sql.adaptive.shuffle.targetPostShuffleInputSize=160000000;
set spark.autoBroadcastjoinThreshold=134217728;
set spark.kwai.sql.dynamic.maxPartitionBytes = 838860800;
set spark.sql.parquet.mergeV2=true;
set spark.io.compression.codec=zstd;

思路

1.调大堆内堆外缓存不超过20g,没什么好说的。

2.调小分区大小提高并行度,增加广播阈值,对于大文件使用解压缩速率更快的zstd。在hdfs中合并临时文件。

3.有收获的一点。今天大佬带我看了spark日志,调了spark.*.sql.dynamic.maxPartitionBytes参数。作用是每个task的内存上限。在spark日志中,我们找到了用时最长的那个job,然后优化他。发现那是一段扫描表的逻辑,且job输入文件大小为3.8TB,task数为4167,如下图,也即每个task要处理0.9g文件,很大。所以缩小了这个参数到0.8g,强迫他增多task数量提高并行度。
改进后:35min46s(减小切片数上限)

Task_id 5:星盘时效行tp(每日维护)

背景

星盘:基于用户标签, 面向用户增长提供用户体系分层分析,解决有用户精细化运营诉求的业务部门在画像洞察分析、目标人群圈选、投放效果追踪等场景下的效率问题。

爆款内容池:将优质内容入池作为push的优质物料,提供爆款push、运行修改文案和监控DAU收益等功能。

需求:奥运期间有大量的优质内容,且内容随赛程推进有时效性。业务会筛选爆款内容统计成在线excel,将爆款入池。DE侧需要每日例行入池链将优质pid入池。

问题: 上游运行资源过载,上游产出慢导致下游运行任务跨天。解决方案是由原先T-1切换为T-2的依赖。

Task_id 6:暑期活动资源位质量评估

需求:需要评估暑期活动中各资源位质量。根据不同会场(主会场、未来明星、王者、和平精英、原神、裂变购物金、裂变泡泡红包等)的不同资源位的引流进行质量评估。

评估的指标要求

  • 页面曝光设备数

  • 18-页面曝光设备数

  • 18-页面曝光占比 = 18-页面曝光设备数/页面曝光设备数

  • 平均页面停留时长 = 页面停留时长/页面曝光设备数

  • 参与次数

  • 人均参与次数 = 参与次数/参与设备数

  • 分享成功发起次数:成功发起分享的did是通过某渠道进来的(和参与中的分享定义对齐)

  • 人均分享量 = 分享成功发起次数/分享成功发起设备数

  • 拉端量=分享拉端次数 :发起分享且拉端的did是通过某渠道进来的

  • 人均拉端量 = 拉端量/分享拉端设备数

  • 分享拉新设备数

  • 分享拉回设备数

  • 分享首活设备数

  • 千分享拉新设备数 = 分享拉新设备数/分享次数*1000

  • 千分享拉回设备数 = 分享拉回设备数/分享次数*1000

  • 千分享首活设备数 = 分享首活设备数/分享次数*1000

  • 页面拉新设备数

  • 页面拉回设备数

  • 页面首活设备数

  • 千UV页面拉新 = 页面拉新设备数/页面曝光设备数 *1000

  • 千UV页面拉回 = 页面拉回设备数/页面曝光设备数 *1000

  • 千UV页面拉活 = 页面首活设备数/页面曝光设备数 *1000

交付:在线表一张(1k+代码,整合口径得到23个指标),数据集一项。

遇到的问题

1.口径对齐的时候,原来讨论的时候是用did来关联底表。数据量呈现膨胀,原因是did被多个entrysrc给多记了。但是,出现了会场和资源位之间不能关联上的问题。所以口径调整为用activity和did关联底表。

2.[Meaning one!]在代码中为了带上求和统计使用了grouping sets,呈现出数据量异常膨胀的问题!原因在于我的组织结构有两层,外循环中nvl(a,'全部')grouping sets,内循环是多表left join,每张join的表中对可能出现null的字段作了nvl(a,'')处理。But!!出现了膨胀。(请思考5秒中问题在哪里?)忽略了left join 带来的null。

感想:接手的时候就各种不理解,维度不理解、背景不理解等等,加班四天,天天干到凌晨一两点,最崩溃的项目!数一直验不对,要么逻辑错误要么口径问题,改了一版又一版。我一度觉得自己完成不了,但也走过来了。总之,要相信自己的能力,心态一定要好~

Task_id 7:添加拉端量中的首活比例

背景:

  1. 拉新:这指的是吸引新用户注册和使用平台或服务的过程。拉新通常涉及市场营销和推广活动,例如在线广告、社交媒体推广、口碑传递、优惠活动等,目的是增加用户基础。
  2. 拉回:拉回是指重新吸引已经流失或长时间不活跃的用户回到平台或服务的过程。拉回通常采用各种策略,比如发送提醒邮件或消息、提供特殊优惠或折扣、更新内容或功能等,其目的是重新激活这些用户,使其再次使用平台或服务。
  3. 首活:该词通常是“首次活跃”的缩写,指的是新用户第一次在平台上进行互动或使用服务。首活时间是指从用户注册到第一次使用核心功能之间的时间长度。平台和应用通常会关注首活,以确保新用户在注册后迅速体验到产品的核心价值,从而提升用户留存率。

需求:在核心看板的打开理由TAB下,增加“拉端量中的首活比例”指标,用来监控归因量的异常,并回刷2024.01.01至今的数据。

交付:在BI看板上数据处添加一个派生字段,用于计算“拉端量中的首活比例”。

Task_id 8:

需求1

统计 某些特定时间引入作者 在特定日期范围内发布的 不同播放量区间的作品数量。你需要从表t中获取数据,并根据播放量 play_cnt_td 将作品划分为以下五个区间:

  1. 播放量大于等于 100 万的作品数量
  2. 播放量在 50 万到 100 万之间的作品数量
  3. 播放量在 10 万到 50 万之间的作品数量
  4. 播放量在 1 万到 10 万之间的作品数量
  5. 播放量小于 1 万的作品数量

请编写一个 SQL 查询来实现上述统计。查询的日期范围条件如下:

  • 使用t-1更新的最新作品数据
  • 引入日期intro_date 在 2024 年 4 月 1 日到 2024 年 4 月 30 日之间
  • 视频发布upload_date日期 在 2024 年 5 月 1 日到 2024 年 5 月 27 日之间

需求2

统计在指定时间段内(2023-12-26 到 2024-01-23)引入的作者,并计算这些作者在30天内是否有发文(留存情况)。具体要求如下:

  1. 从表 tb中提取数据。
  2. 统计在指定时间段内(2023-12-26 到 2024-01-23)引入的所有作者。
  3. 计算这些作者在 引入时间 intro_date 后的1天到31天内是否有发文。
  4. 如果有发文,则留存标记为1,否则为0。

交付:每日例行任务一项。

Task_id 9:新回打开理由特征组合

背景:探究影响新回用户召回的打开理由的特征。新回push团队与大模型团队共建新回push user emb召回。生产任务整合了十几个特征表,而特征表涉及底层权限,大模型团队无法获取到权限。

交付:创建例行任务一项,把大模型需要的特征表同打开理由维度表和设备新回归因表进行关联。在特征表中筛选出新回用户,返回所有特征维度。
调优:Feature大小为39.82TB(不包含副本);user _device 大小为1.92PB;attribute表1.74TB。表的量级特别大,尤其是保留对feature表中所有的维度导致计算特别慢,作出了以下调优:

1.原先使用的distinct来去重命中的新回用户ID,后来用group by来替代更高效。
2.谓词下推,尽量将需要过滤的语句放在子查询中,比如将时间分区放在where中然后返回子查询
3.spark调优
set hive.auto.convert.join = true;(join优化)
set hive.map.aggr = true;(group by优化)
set spark.executor.memory = 16g;(executor堆内存大小)
set spark.executor.memoryOverhead = 12g;(executor堆外内存的大小)
set spark.driver.memory = 16g;(driver对内存大小)
set spark.driver.memoryOverhead = 12;(driver堆外内存大小)
spark.sql.adaptive.shuffle.targetPostShuffleInputSize = 268435456(256M)
spark.sql.adaptive.maxNumPostShufflePartitions = 6000
spark.sql.files.maxPartitionBytes = 268435456(256M)

调优后由原先的4h优化到1h42m左右。

Task_id 10:18-人群指标

需求:统计站内业务的18-双关渗透率、18-作者率、deltaDAU。这三个指标和口径对应“社交”、“生产”、“消费”。

  • 18-双关渗透率:计算双关用户/活跃用户;当然需要关联年龄和用户的维度表过滤出18-。
  • 18-作者率:18-用户且发文数/18-活跃数。
  • DeltaDAU:这个其实是AB实验,就是对照组/实验流量-实验组/实验流量。这里需要用到udf函数。

交付:暑期活动例行任务一项。

Task_id 11:长时效物料

需求:内容兴趣push有不同时效性的物料,大部分内容需要限制90天有效,小部分非常优质的内容可以长时间下发,因此需要豁免90天有效的过滤规则,将时效性延长至365天。
交付:将底表的分区access_online_content_pool添加一个新的字段用来存放distribution_date=‘100’

Task_id 12:收益挂新实验

需求:对于日收益表和总收益表更新AB实验,同时,核验相关看板数据,修改看板的配置。
需求变更的逻辑:AB Test 变更 - > 底表的逻辑需要变更 - > 紧跟着依托底表的数据集需要变更 - > 看板变更。
可能存在和值得探讨的问题:
因为这一部分频繁需要变更AB Test,而且有回刷需求。很容易产生回刷时实验日期未校准导致运行报错的问题,如某AB Test 上线的日期是date,但是需要回刷到date-1,就要注意这溢出的一天不能用这个AB Test去跑。最后的方式是建一个维度表,在维度表中记录上线的AB Test。同时,配置质检DQC检测每日的数据是否异常。
遇到的问题:
替换完实验组后ab实验的流量和结果对不上。原因:是上游实验存在抽流现象,即上游可能依据uid过滤了一些本该计算在当前实验的dau流量。这个无法避免,只能尽可能的缩小误差。
交付:更新上线表和三个看板。

Task_id 13: 光线过滤链路产出

背景:光线是青鸟平台的一个功能,作用是将基于push_id转化加工push的内容文案。
需求:上游给出同城pid物料,但是pid中有不少劣质资源,必须根据规则进行过滤在放到内容池中。
需要通过详细字段获取 -> 清洗 -> 黑名单过滤 -> 规则过滤。

过滤规则:根据第一大类别(’ 人文’,'时尚’等),第二大类别(‘宗教’,'穿搭’等),标题过滤,劣质过滤(‘暴露诱惑’、‘危险驾驶’)等。

Task_id 14: 新回设备前三刷城乡标签覆盖率

背景: 基于用户常住地附近POI的城市/农村人群包。
根据这些POI,附近X米范围(农村、高端城市人群采用1km,地铁附近人群采用1.5km)的常驻人群,且结合该用户常住乡镇的城乡类型(农村要求城乡类型=乡村,城市要求城乡类型=城区)来保障高准,进行人群圈选。
需求: 新回(当然可以拆成1日、14日的新、回),前三刷的经纬度,新回设备没有常住地,则使用该用户前三刷的经纬度或WiFi的经纬度作为用户的位置点,然后依据1中人群包逻辑进行打标。离线评估该标签覆盖率,如果认为有用,再由业务侧接入数据和计算逻辑等,做后续的线上化。

Task_id 15: 氛围页清洗

背景:进入端内页面会呈现加载的空白页,这时如果插入激励赚钱页诱导用户点击进入,能提高赚钱页的激励转化。

需求:通过加载页的过程为开始加载-> 加载成功-> 点击*关闭-> 成功自动退场,需要通过埋点统计 “开始加载时间”、“加载成功时间”、“加载错误时间”、“完成时间”、“完成原因(用户点击/超时/成功退场)”。

开发:需要通过埋点底表的明细字段中取出上述维度。这里为什么不产出例行表,是因为业务的变更比较频繁。

交付:视图一项。

Task_id 告警类

1.表t 2024-07-29 00:00:00

[2024-07-30T10:34:48.122]org.apache.hudi.exception.HoodieException: Unknown versionCode:6
[2024-07-30T10:34:48.122]	at org.apache.hudi.common.table.HoodieTableVersion.lambda$versionFromCode$1(HoodieTableVersion.java:56)
[2024-07-30T10:34:48.122]	at java.base/java.util.Optional.orElseThrow(Optional.java:403)

解决:运维扩容的时候没有用新版本导致报错。运维端解决问题。

2.表t P1报警
报警规则:主键不唯一报错
核查数据:核查记录数为135条没有问题,放行!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值