大数据下的流量增长模型介绍

1,770 阅读16分钟

0.目标

本次分享的目标,主要是让没接触过用户/流量相关业务的大数据同学,也能对最通用的流量业务有所通识,因为用户/流量增长业务是最通用的,不管在哪个行业都殊途同归,因此学会了后,可以一通百通,建议学习。

1.整体概览

目标

首先,每个公司设立流量数据部门的初衷都是相似的,为了用户增长,或者说,利用一切资源让更多用户高频地使用核心功能,提高用户生命周期价值。

P.S. 生命周期价值——用户从激活到离开的时间里,公司从和用户的所有互动中所得到的全部经济收益的总和

怎么做

  • 围绕用户的生命周期(见图)去设计路径——建立触发机制,在用户生命周期中的关键节点,比如流失节点,续费节点,回访节点等,配套相应运营。

5dba0d0689904d70b68e83b6c3cdd91c_tplv-k3u1fbpfcp-zoom-in-crop-mark_3024_0_0_0.webp

  • 抓住某些标签用户,通过产品化的组建提供给用户特定的营销素材,促使用户去分享和推荐(Ex.瑞幸的各种联名营销,促使人们去分享购买后的商品)。

  • 不变的市场营销核心:围绕用户本质展开,把用户本质在不同情况下的特质解构出来。做到后期的商业智能,其实是前面积累的用户历史数据,被加工成数据资产后(用户画像),通过精准撒网带来高单产(个性化推荐,千人千面)。

架构

新流量模型.png

如图所示,流量模型可以粗略划分为三块,第一块是埋点日志输入,我们以前端SDK打点日志为主(更灵活),后端打点日志为辅,构成流量数仓的数据源;中间即是我们的工作,流量数仓,将面向在线系统的,半结构化的埋点数据,转化成面向分析、面向主题的一系列数据集/表;输出一般可以笼统地概括为一个用户行为分析系统,就是对用户使用产品过程中产生的行为数据,通过分析而输出各种有意义的指标,产出可以是报表,也可以是多维分析引擎。用户行为分析系统产出的指标一般诸如:

功能分析——检验功能的受欢迎程度;

业务分析——事件转化,页面访问路径上的损耗;

用户信息——构建用户画像;

在我呆过的作业帮,流量数仓作为用户行为分析系统的中间层,上游承接SDK组提供的全埋点数据,在架构组提供的大数据平台和技术支持下,将埋点数据处理成有用的信息,输出给下游各个使用方,在各个报表平台生成报表和可视化视图,以及支持即席查询和数据运营。

数据仓库(DW/BI)一直都主要以面向分析/运营功能去服务的,最早也被叫决策支持系统,因此,需要了解到流量数据被使用的分析/运营模型是什么,才能知道提供支持的流量数据模型应该怎么设计。

P.S.全埋点——不用写代码或者写少量代码,就可以完成大部分基础功能的埋点工作,具体业务的埋点还需要开发

3.分析/运营模型

问:为什么要挑选好的运营模型?

答:提高资源转化输出效率

漏斗模型

v2-200f92f74bbac1793663f94d0a44c2fd_1440w.jpeg

5a852c94f09bc74f8d3f62e3f7341e52.jpeg

最广为人知,也被称作海盗模型/AARRR模型,适合增长没有到顶,市场还很有潜力时的公司的打法。如图所见,可以将用户的生命周期划分为5个步骤:
获取——用户从不同渠道获取你的产品

激活——用户在你产品上完成核心任务并有良好的体验

留存——用户回来继续不断地使用你的产品

收益——用户在你的产品上发生了可使你收益的行为

推荐——用户通过你的产品,推荐引导他人来用你的产品

作为互联网行业最通用的漏斗分析模型/方法论,数分要做的,就是把最终目标(变现页,购买页)放到漏斗最下方,把需要经过的各个环节按照顺序依次放入漏斗中,然后从上往下,寻找每个环节的流失严重点。漏斗分析法常常被用来分析用户转化问题、用户流失问题等。

6R模型

aCTUVXO8wW2SyZdVvmB1.webp

6R模型,用三个词来概括,即“拉推”“回忆”“收留”,为开发者实现从“获客”到“激活”再到“变现”的用户全生命周期管理闭环、获得持续增长。6R模型更适合存量时代,相比于漏斗模型会更侧重老用户的规模和留存,把整个流程贯彻到一个体系里,即引流团队也会关注后续的使用体验等情况。

Recruitment(拉)指的是通过广告投放、渠道推广等方式拉新,Reproduction(推)则指的是在获得一个新用户之后,通过一定手段促使和激励这个新用户进行推荐和分享,再获取新的用户,从而分摊掉获客成本。

“回”指的是:通过消息推送、短信、EDM等方式对沉默用户进行再触达,促使已经沉默的用户再次登录和使用。“忆”指的是:通过持续为用户提供有用、有趣的服务和内容,给用户留下良好的印象,让沉默或流失用户能够在合适的场景主动记起并再次焕发活力。

“收”,即锁定适合投放的人群去进行精准投放,以获得高收益;“留”,是定期复盘,深入分析用户行为,进行流失预测,以做好提前应对,降低用户流失风险。

在作业帮时,我们主要使用漏斗模型去分析,因此流量数仓需要为数分产出这些主题的指标。因为这些指标的计算口径一般是跨部门通用的,因此计算工作会下沉到中台数仓,在美团时,也有类似中台数仓的团队负责该业务,各业务线再基于基础指标去进行个性化地加工。这些指标在大部分公司都通用,都会去看,比如投放广告组一般关心投放广告后的新增激活情况,品牌/业务方一般会关心每日的用户活跃情况,大部分数据使用方都会关注留存情况。

4.怎么建设

唯一标识id

刚才讲到了作业帮的流量数仓基于漏斗模型一般会输出什么指标,接着再讲这些指标的口径,具体而言是指标的“单位”。流量模型计算的指标单位一般是去重用户数(例子如uv,DAU),因为大部分情况下pv(人次,访问量)的分析意义是不如uv的。

为了统计各应用的SDK产生的用户行为日志对应的uv,也为了在建立用户画像后,能准确地给用户进行精准运营/个性化推送,需要给每个用户标记一个唯一标识(cuid),一般是通过给每个设备或账号打上一个具有唯一性的设备id和账号id来实现。该标识id最好在公司内部所有APP下保持一致即账号打通,这样统计各APP的用户重合度即成为可能。目前一般有两种统计口径,一个是统计去重账号数,一个是统计去重设备数,一般后者数量会大些(一个用户一段时间里拥有多个设备概率更大些),在作业帮,我们采用的是去重设备数做单位,因为作业帮的很多核心功能(比如拍搜),不需要注册也能充分使用。

这个问题搞清楚了,是不是可以开始对用户生命周期的每个环节建模了?别急,还得考虑具体的技术实现支不支持你这么做。

P.S. 此次的设备唯一标记只保证每个用户在每个端的id是唯一的,如果用户有多个端(比如使用安卓,iphone,pc等使用同一个APP),则会生成多个cuid,如何把他们映射到一个用户需要ID MAPPING

业务模型

这里涉及到具体业务且可能敏感,故不做说明。

统一分析能力

在作业帮的业务模型里,业务场景可以被简化为,用户在多个业务节点(激活,留存等)之间相互流转。一般常见的成单归因、漏斗分析都会要求我们把各个节点能串联起来,即所谓的,“全链路打通”。基于刚才的知识,我们能想到的是通过给用户赋予用户标识id(即cuid),再将业务节点按事件时间排序,即可通过cuid串联的业务节点做转化等分析。但在作业帮,某些业务场景获取不到cuid,因此不同业务节点的用户标识id往往不是统一的。

首先,端外即非APP的投放,由于依托第三方(比如快手,腾讯极光),无法获得cuid,使用的是设备自带的IMEI/OAID/IDFA,在android最新版升级协议后这些id可能更难获取,APP内则可以使用cuid,LEC业务(基于线索)使用uid(账号id)+手机号,订单系统使用uid。如此多的id,有的业务节点都具备,有的只具备其中一个或几个,很难有效地通过其中一个id进行串联,比如端外落地页和端内的串联就没有绝对的解决方案。通过维护ID MAPPING表来维护用户唯一标识之间的映射,可以将多个业务节点串联起来,但是这个办法的准确度也取决于ID MAPPING的准确度。

5.逻辑模型

业务+技术架构图.png

在作业帮,流量逻辑模型可以分为两层,最底层是流量数仓,上层是用户数仓。
我们用EVENT+USER+DIM来概述宽表模型:

  • EVENT即最细粒度的用户行为事件(埋点id/事件id,类似美团的资源位id),包含最全面的事件信息(5W,who,what,when,where,which),也包含埋点信息,设备信息和程序信息;

  • USER指用户,使用手机商或系统或第三方给用户生成的唯一标识;

  • DIM是通过画像挖掘或用户填写来收集的对用户某属性的描述,我们将维度信息填充到点击事件里来扩充可分析的维度,比如用户的身份、年级等;

流量数仓存的是埋点日志抽取过来的明细(EVENT),但是不同于保留原样日志的ODS层,流量数仓为了提升面向分析的易用性,把原始流量日志关联埋点维表,按照打点平台(APP、h5,pc)、埋点对应模块对数据做分区,并做了一系列查询和存储的优化,这个在下面会具体讨论。
用户数仓在流量数仓的基础上,从用户事件粒度去重退化到用户粒度(USER+DIM),将数据量从百亿级降低到千万级,降低了后续复杂计算的成本。数据来源是流量数仓,但是只筛选预置事件的流量数据。我们定义的预置事件包括:“APP打开”,“APP关闭”,“页面打开”,“页面关闭”等,预置事件的含义是,该用户当天在APP上有任何活跃,都必然会触发至少一个预置事件。
在用户数仓里,用户的每条记录都代表用户在那个时间点有活跃,因此退化事件粒度后,用户数仓的基础是活跃主题。在活跃的基础上,我们在基于分析需求产出了留存,激活,首登等主题,并为这些主题建立相应的数据模型。

6.流量经典问题

  1. 准确度问题

    1. 延迟上报——因为前端埋点的特点,可能存在用户1号在APP上的活跃日志,因为断网等原因没有在当天发送到日志服务器,而是缓存在本地,直到2号联网了才发送至日志服务器,但已经错过了1号的离线数据处理。策略:

      1. 每次重导都不限制计算日期往后的日期范围 -> 满足准确性,损失幂等性:同一个日期分区在不同的时间各刷一次,可能得到截然不同的结果
      2. 每次重导时都限制事件时间=数据入库时间 -> 损失准确性,满足幂等性:可能业务侧会反馈,一个用户X号活跃,但dt=X的前端日志里没有该用户信息

      目前作业帮采用的是策略2,以保证幂等性和一致性,避免重导时,出现数仓内部的不一致。比如,底层流量DWD表做加新字段重刷,结果刷完数据却变得和下游DWS到ADS层都有差异了(补上了延迟上报的数据),导致数仓内都不能保证一致性(整个数仓没有还可以用口径解释,数仓内部都不统一就会造成信任危机了。。。)。

    2. 生成唯一标识不保证唯一性。生成唯一标识的素材(android id, imei, oaid, idfa)因为新版本权限管理更导致难以获取,导致必须变更获取这些参数的逻辑,在样本量足够大的情况下,可能导致两个独立设备生成同一个uuid。这个问题如果不能控制规模,会动摇整个流量分析的底座。

    因为上述等原因,精确度很高的指标(比如钱相关)一般不会从前端日志出。流量类指标多用于给出个预估的总数(累计用户数,月活跃数),多用于优化产品体验。

  2. 海量问题

    作业帮:拍搜APP一天上百亿埋点日志,2-4TB存储

    快手:一天上万亿埋点日志

    1. 查询优化:

      数据分片——范围分片(Range Partition),相比于只适合点查询的哈希分片,更适合经常有范围查询的数据集

      排序规则——全局排序,LSM树

      通过将全部数据按照最高频查询字段列(组合)去排序,使得文件与文件之间是有序的,同时让查询计划能利用到文件的Min-Max索引,以加速data skipping

      Partition(key) {
      	range = (KEY_MAX - KEY_MIN) / No_Reducer
        return (key - KEY_MIN) / range
      } //仅适合key为数值型的情况
      

      新的问题:高频查询字段大概率存在数据倾斜,则在用高频字段对数据做重分发时,会有性能问题

      解决思路:见另一个博客链接:juejin.cn/post/704766…

      更高阶:当有多个字段用于排序且想保证每个字段排序时的权重一致时 -> z-order。

      z-order可以让使用该排序的多列数据集获得所有参与排序的列的元数据:Min-Max值,来达到查询时跳过文件的相关,不仅如此,还让相似的记录紧挨在一起,相似记录在被查询时有更高的概率被查出(space locality),且缓存命中的概率更高。

    2. 存储优化:

      数据重排——基于主流存储格式的压缩特点,混合存储会把若干行数据以行为单位存在一个文件,但更底层是按列去存数据块的。根据信息论中熵的概念,数据越是随机,需要用来表示的比特数就越多,如果能以一种相对低成本的方式让数据是相对有序的,比如,每个数据块里各列数据都是相似或相同的,则压缩时更少比特的字典就能代表全部数据,压缩效率就更高。因此,我们通过将数据按表内最具代表性的字段列去重新混洗和重排,使得相同或相似的数据被分配到同一个文件,以永久性节省存储空间。

      一张表每个字段的压缩系数公式:略

  3. 成本大,治理难

    流量数据的存储可能占大数据总存储的60%以上,计算成本占比应该也不容小觑,但是因为流量日志明细多为半结构化数据(包含大量字段的JSON字段,不会全部平铺),因此治理难度比一般的业务主题要大。为了使数据成本不至于线性增长,我们要对下游已经不使用的埋点/资源位做下线处理,但是,哪些是没使用的构成了难题。

    1. 基于设备+APP版本判断:枚举所有设备类型的近20个APP版本,如果某埋点近3个月(一般每月都会至少发一次版)的打点日志都不在这近20个APP版本,则判断业务侧已不再分析,因此在最新版本的SDK中剔除了该埋点,且商分侧不再使用,因此没有反馈让SDK研发追加;
    2. 基于血缘治理(最常见):通过对一段时间内下游查询SQL的解析和统计分析,并采用分治法去归纳和降低分析难度,达到确定治理范围的效果。基于对业务的理解,我们知道大部分查询都会带上事件id/埋点id作为筛选条件,所以最适合作为治理依据的是埋点id字段。但是仍有相当可观数量的查询SQL是基于其他字段,有的甚至基于嵌套JSON内的字段做筛选,增加了统计的难度。首先,我们将下游查询SQL分为查埋点id的和不查埋点id的,后者里如果SQL里用于筛选的字段存在有限枚举值,我们维护枚举值和埋点id的映射关系,则可以将筛选条件转化成对埋点id的查询。剩下一部分存在无限可能的枚举值的筛选条件字段,我们再人肉去把这部分筛选条件拼接到一起(到这一步时已经较少),一次性查询,通过这种大部分自动化+部分人肉的方法,可以确定可治理的埋点数据的范围。

参考资料