介绍
该文章是本人在用户流量数仓工作一段时间后,将工作内容中一些通用且有价值的内容拿出来做分享。因网上关于用户流量数仓的分享资料多是基于产品经理的角度去解释概念,或者从纯技术角度解释用户流量数仓的技术架构,缺少分享用户流量数仓中对于通用指标的计算思路的,明明大部分公司的用户流量数仓都统计相同的指标。对于同样面向用户流量工作的你,如果觉得有意义或有意见请给予反馈,帮助我继续产出更好的用户流量数仓文章!
当前互联网公司的用户流量数仓建设思路大同小异,不管在电商行业还是在教育行业,用户流量数仓基本都是基于用漏斗模型这个用户增长模型的5个阶段来设计指标和建设,核心目标都是用户流量数仓落地后可以更直观地观察用户增长的可量化指标、趋势和因果关系,帮助数据运营团队更针对性地执行广告投放或电销等策略。
建设需求
用户流量数仓的需求,可以用《数据仓库工具箱》的作者Kimball列的数仓的6个基本需求来回答:
| 序号 | 需求 | 在用户流量数仓的体现 |
|---|---|---|
| 1 | 收集了海量数据,但无法对其进行访问 | 用户流量要把比业务数据更庞大和冗杂的用户行为日志数据进行精筛和处理,转化成可以访问和使用的数据资产 |
| 2 | 需要以各种方式方便地对数据进行切片/切块 | 可能是最契合用户流量数仓的需求,用户流量的核心需求就是支持在各种维度下对用户群体进行上卷或下钻的分析,大部分用户流量数仓的建模必然涉及到繁多的维度,必须上层有一个健壮的OLAP模型去管理这些数据 |
| 3 | 业务人员需要方便地获得(满足格式、范围要求的)数据 | 用户流量的对内需求,即建设公司级的用户流量数仓,为其他部门或业务线,提供用户流量按主题、按粒度、按层级去按需查询的能力,而不是都从源数据去获取 |
| 4 | 会议上自始至终争论谁的数据正确 | 对数据准确性和指标同名同义性和一致性的要求,可能会时不时会被拉去做指标对齐的会议,同一指标不同部门可能有各自的一套计算链路。当不一致时得拉会对齐指标,搞清楚计算逻辑的差异,合理化差异,或者排查出问题 |
| 5 | 支持更多基于事实数据的决策制定 | 对外需求,提供核心指标量化事实以帮助决策,比如提供活动前后的用户活跃指标对比,让用户判断营销事件效果 |
| 6 | 将最重要的事情展示给用户 | 对外需求,每天提供用户最关心的核心指标,一般为用户增长模型各阶段的可量化指标,比如各端DAU,每日注册数和激活数等等,方便业务线分析用户增长情况 |
建模思路
用户流量数仓,是作为用户行为分析系统(用户使用产品过程中,把产生的行为数据通过分析生成的报表工具)的中间层而建模,上游承接各应用各端SDK产生的用户行为埋点数据,下游则输出各种指标报表或可视化视图。
输入数据,一般是行为日志这种非机构化数据,被批次地或实时地上报到日志服务器,经过清洗、解析和筛选等操作后,作为结构化数据发送到数据库落表并存储。数据表以实时或离线的计算频率调度计算引擎执行复杂的计算,调度后再将经过处理的数据发送到各类OLAP平台上,用户流量的报表基于各自维度组合调接口查询OLAP的预聚合数据或明细数据,并展示在报表上。
用户流量数仓从主体域建设上来看的话,可以被认为基于通用的数据运营模型——漏斗模型(也叫海盗模型AARRR,因为其掠夺式增长),因为大部分公司的用户增长业务都基于该模型实现拉新(用户增长)。该模型分为:获取-> 激活 -> 留存 -> 收益 -> 推荐 5个阶段,其中获取可能又包含投放主题,留存又包含召回主题,收益可能包含付费、退款等复杂又敏感的主题,等等。
因为大部分公司报表都看这几个主题的指标,比如投放广告组一般关心投放广告后的新增激活情况(反馈),品牌方/业务方一般关心每天的用户活跃情况,大部分数据使用方都关注留存情况。故一般用户流量数仓的建设都可以:在指标层(DM层)每个主题都最好单独对应一套计算链路,在数仓层(DW层),需要把行为日志明细数据以各种组合和关联的形式保存,比较考验建模能力。一般认为,打点日志行为表内一个用户产生一条记录即表示该用户在该时间活跃了,因为只要上报了就表示相关设备/账户有操作行为,即打点日志底表可直接表示活跃,故活跃主题可以作为DW层最基础的明细表。其他主题如激活、留存等都可以基于活跃去计算得到,具体计算思路在后面讨论。
计算的锚
在统计各端SDK产生的用户行为日志的uv,pv时,一般需要一个具有设备唯一性或账户唯一性的标识id,使得每个设备或账户都能唯一对应上一个标识id,且该标识id生成规则最好能在公司内部所有APP的SDK保持一致,使得账号打通,统计各应用的重合度等指标成为可能。一般账户id需要上报到服务端注册成功才能生成,较好统计和保证唯一性,设备id各公司的计算方法各不相同,比如Android设备可能基于imei,oaid等设备唯一标识符来生成。当我们为每个用户都建立起唯一的独立设备标识后,我们可以基于此向用户提供个性化推荐或大数据杀熟等功能。 当我们统计某个APP的活跃情况时,我们可以选择统计设备id的uv,pv,也可以统计账户id的uv,pv,这两个id的对应关系一般是1个账户id对应多个设备id,故基于账户id统计可能更能准确反应APP某天的用户使用情况。
指标计算设计
活跃
统计某APP在某段时间或某活动的活跃情况时,一般会直接计算uv(比如一天时间的DAU)或pv,当前主流的计算引擎或者OLAP工具都对计算提供了支持。比如当你使用Spark Core编写计算逻辑时,Spark带有的RoaringBitmap库提供计算函数支持对唯一标识做bitmap去重统计,如果你使用Hive/SparkSQL编写计算脚本,可以引用BrickHouse jar包,该包有Bloomfilter udf方法也支持把唯一标识放到bitmap统计。如果你在计算引擎输出时仍保留明细数据,把uv,pv计算留到OLAP,则Doris是个好的选择,当你把数据导到Doris时,只要指定了维度和指标,Doris会在导数的过程中自动把唯一标识作为指标导到bitmap数据结构里并进行去重,并支持从bitmap输出所有输入元素或输出元素的数量。
激活/注册
激活/注册,即统计一段时间内新增激活(即首次启动该app并上报)/注册的唯一标识,一般我们倾向从APP上线那天起统计,只要用户唯一标识在历史没出现过,则当前为首次出现,算作当前时间段的激活。众所周知,用户流量数仓因为其每天产生的用户行为日志数据的庞大,基本都建模成增量表,按特定时间周期分成一个个增量分区。为了计算激活用户,我们还需要维护一个全量全历史用户表,用于判断当前时间段的用户是否是首次出现。这个全量全历史表的建模如果建得好,可以在用途上很强大。
如果只关心计算用户是否新增的计算性能,可以建模一张只包含全量全历史唯一标识的表,每次计算时把该字段放到bitmap里(见Spark Core和Hive BrickHouse 的bloomfilter库),去筛选当前时间段已经在历史中出现的唯一标识。筛完后再将新增的唯一标识合并到旧的全量表,生成新的全量标识表。
如果想要该全量表在计算其他指标时也发挥作用,则表需要包含唯一标识和唯一标识对应的用户维度,比如设备品牌,设备版本,用户地域,用户年龄,投放渠道等信息,用户唯一标识作为主键。有两种建模(主键去重)思路,一种是每次合并新增数据和旧全量时,如果遇到重复的唯一标识的记录,则丢弃,这样就维护了一张用户首次激活/注册的全量历史表,当需要计算的指标关心用户首次出现的渠道等维度时,可以用这张表进行计算。另一种是保留最新出现时的维度,即当合并新增数据和旧全量时,如果遇到重复的唯一标识记录则用新的替换旧的,当计算召回指标时,一般计算思路是把召回算在最新的活跃渠道上,所以可以用这种建模方式。
如果还想让该表支持类似用户流失的统计,则可以把该表做成历史拉链表,每个用户唯一标识都包含一个首次活跃时间和最后活跃时间,用户维度可以基于上面的考量选择最新或最早的,这样我们可以通过计算当前时间和最早活跃时间的差值,判断该用户是否被定义成流失用户。
留存/召回
该指标是大部分数据使用方都关注的指标,因为涉及到关键的流量/用户的流失率及数据运营的转化效率。用户之前使用过该产品(活跃过),经过一段时间后,仍然活跃,即是留存用户。召回是成功将已经流失的用户(即一段时间内不活跃了)又召回到我们的平台。
这里的指标定义有些细节值得商榷,比如,留存时间的统计方式,可以分为第N天留存和N天内留存,即从某次活跃后又过了N天刚好又有活跃(神策提供的是该留存计算方式),以及某次活跃后N天内有至少一次活跃。还有就是(渠道)归因,即用户对应维度是取较早活跃的用户维度还是最晚活跃的用户维度,一般计算召回用户都会倾向于把召回的效果归功于最新活跃的用户维度(可能是某些投放渠道、营销活动的效果,又把用户拉回来),计算留存都倾向于用最早活跃的用户维度。
不同公司计算留存的方式可能各不相同,这里提供一个留存计算的思路,即针对每个用户唯一标识和用户维度,都维护一个bitmap位图来保存该用户近N天的活跃状态。比如用户X,第一天在小米渠道上活跃,第二天在华为渠道上活跃,第三天又在小米渠道上活跃,则我们的用户bitmap表针对该用户会维护两条记录,1条的渠道是小米,bitmap的活跃状态为“101”,其中1表示活跃0表示否;1条的渠道是华为,bitmap的活跃状态为“010”。这个bitmap的长度取决于我们留存/召回计算的最大时间跨度,一般第一位表示统计当天(最新日期),后N位表示的是N天后用户活跃的情况,因为每个用户的每个维度组合都会维护一个bitmap,这个表的数据量可能意外的大,建模时要考虑可能出现的计算瓶颈。
至于如何计算留存/召回,如上图所示,在用户的bitmap下,找到当天活跃的用户(即bitmap最新1位为1),往前倒N位看是否为1,如果为1则该用户算作N天留存。召回则是找到当天活跃的用户,且往前N位都不为活跃,则可以算做N天召回。
付费
待补充
推荐
待补充
总结
因付费和推荐两个计算链路接触得还不够多,没有特别好的思路提炼出来分享,故等后面做熟了再补充。
通过我前面的叙述应该可以体会到,用户流量数仓指标的高度雷同,故如何把指标计算做到更准确更高效,应该不同公司有很多不同的尝试,值得好好交流。用户流量数仓还有其他核心的内容,比如作为数据源的埋点数据的处理和选择,以及上层OLAP技术的选型,都是值得大书特书的。
另,作业帮数据仓库团队 用户流量数仓团队仍需要新的同仁加入,有兴趣的可以私信我,我帮你内推。