在数据采集上的痛苦、幻想与失望
作者:桑文锋,神策数据创始人兼 CEO,前百度大数据部技术经理
在这一年来接触了我个人接触了 200 家创业公司,发现都在数据采集上遇到多多少少的问题,我把它们归结为三类:
1、不知道怎么采,包括采集什么数据以及用什么技术手段采集;
2、埋点混乱,出现埋错、漏埋这样的问题;
3、数据负责人员和业务工程团队配合有问题,很难推动业务工程团队配合,往往项目功能升级的优先级大于数据采集的优先级。
上面这三类问题让数据同学相当痛苦,进而有些幻想出现不用做数据采集的方案,结果做了些尝试后,进而是更大的失望。我这里对这三类问题的现状及应对之策做一下分析。
不知道怎么采
一般创业公司是数据采集上,可以分为三种方式:
第一种是直接使用友盟、百度统计这样的第三方统计工具,通过嵌入 App SDK 或 JS SDK,然后就可以看统计数据了。这种方式的好处是简单、免费,因此使用非常普及。对于看一些网站访问量、活跃用户量这样的宏观数据需求,基本能够满足。但是,现在一些订单相关的产品,越来越不满足于看这些宏观统计数据,还想做一些深度的用户渠道转化、留存、多维度交叉分析等操作,这个时候就会发现很难满足。这里的问题倒不是出在分析能力的薄弱,而是出现数据采集的不完整。
通过这种 SDK 只能够采集到一些基本的用户行为数据,比如设备的基本信息,用户执行的基本操作等。但是服务端、数据库中的数据并没有采集,对于一些提交操作,比如提交订单对应的成本价格、折扣情况等信息也没有采集,这样就导致后续的分析成了“巧妇难为无米之炊”。
通过客户端 SDK 还有一个问题就是经常觉得统计的不准,和自己的业务数据库数据对不上,出现丢数据的情况。这是前端数据采集的先天缺陷,因为网络异常,或者统计口径不一致,都会导致数据对不上。
第二种是直接使用业务数据库做统计分析。一般的互联网的产品,后端都是有业务数据库,里面存储了订单、用户注册信息等数据,基于这些数据,一些常用的统计分析都能够搞定了。这种方式天然的就能分析业务数据,并且是实时、准确的。但不足之处有两点:一是业务数据库在设计之初就是为了满足正常的业务运转,给机器读写访问的。为了提升性能,会进行一些分表等操作。一个正常的业务都要有几十张甚至上百张数据表,这些表之间有复杂的依赖关系。这就导致业务分析人员很难理解表含义。即使硬着头皮花了两三个月时间搞懂了,隔天工程师又告诉你因为性能问题拆表了,你就崩溃了。二是业务数据表的设计在于高并发低延迟的小操作,而数据分析常常是针对大数据进行批量操作,这样就导致性能很差。
第三种是通过 Web 日志进行统计分析。这种方式相比基于业务数据库的方式,完成了解耦,使业务运行和统计分析两个数据流相分离。这里的问题是打印日志往往是工程师顺便搞搞,完全是以 Debug 的需求来打印日志字段,但在业务分析上,往往发现缺斤少两。并且从打印日志到处理日志到输出统计结果,整个过程很容易出错,我在百度就花了几年的时间解决这一问题。
以上三种方式都多多少少解决了一部分数据采集的问题,但又都解决的不彻底。
埋点混乱
我曾经接触了一家做了七八年的老牌互联网公司,它们的数据采集有 400 多个点。每次数据产品经理提了数据采集的需求,工程师就会按照要求给做了,然后交给数据产品经理去验证。数据产品经理在试用的时候也感觉不到异常,可等上线之后,发现埋的不对,再进行升级发版操作,整个效率就比较低了。一个公司发展到一定程度,没有专人去负责埋点管理工作,数据采集完全没有准确性可言。还有时产品上线之后,才发现数据采集的工作没有做,也就是漏埋了。
于是数据相关的同学甚至管理者都在幻想,既然埋点这么容易出问题,有没有不埋点就可以解决所有问题?这就像寻找可以祈求风调雨顺的神灵。在 2010 年时,百度 MP3 团队曾经做了一个叫 ClickMonkey 的产品,只要页面上嵌入 SDK,就可以采集下来页面上所有的点击行为,然后就可以绘制出用户点击的热力图,这种方式对于一些探索式的调研还是比较有用的。后来在 2013 年,国外有家数据分析公司叫 Heap Analytics,把这种方式更近一步,将 App 的操作尽量多的采集下来,然后通过界面配置的方式对关键行为进行定义,这样就可以不用工程师的配合就可以完成数据采集操作了,这是其中的一个优点。这里要说明的是,要使用这种方案,必须在产品里实现嵌入 SDK,等于做了一个统一的埋点,所以“无埋点”这种叫法本身就不严谨。我更愿意把这种方式叫做“全埋点”。
这种方式只能是进行前端的数据采集,后端服务器和数据库中的数据,依旧是无可奈何的。即使进行前端的数据采集,也不能够进行细粒度的数据采集。比如对于提交订单操作,订单的运费、成本价格之类的维度信息,等于都丢失掉了,只剩下提交这么一个行为类型。
对于非技术人员,容易被这种方式的名称和直接优势所吸引,但很快又会发现许多深度数据分析需求无法直接满足,进而有种被忽悠的感觉,会感到失望。其实不止是非技术人员,即使是技术人员,也都会让我解释一下“可视化埋点”的原理,当我讲解之后,一般都会恍然大悟。这里说一下关键点:一是事先在产品上埋一个 SDK,二是通过可视化的方式,生成配置信息,也就是事件名称之类的定义,三是将采集的数据按照配置重命名,进而就能做分析了。
数据团队和业务工程团队的配合问题
公司到了 A 轮以后,一般都会有专门的数据团队或者兼职数据人员,会对公司的一些业务指标负责。即使为了拿到这些基本的业务指标,一般也要工程团队去配合做一些数据采集工作。这个时候雷军的“快”理念就起到作用了,天下武功唯快不破。于是所有事情都要给产品迭代升级让路,快的都没有时间做数据采集。须知没有数据指标,又怎么衡量这个功能升级是不是对的呢?互联网产品并不是加更多的功能就好,还是要基于数据做验证,然后学习新知识,用于下一轮的迭代。
数据团队和业务工程团队是平级的团队,而数据团队看起来总是给业务工程团队增加麻烦事儿,似乎也不能直接提升工程团队的 KPI,所以就导致配合起来特别费劲。数据团队的需求总是被更高优先级的事情挤掉,导致数据的事情迟迟没有进展。
解决之道
前面分析了以上三类问题,我们来看一下应对之道。
对于不知道数据怎么采的问题,首先从意识上要重视数据采集工作。数据的事情归结起来就两点:数据采集和数据分析。可不能只看到数据分析但没看到数据采集。事实上我个人在百度做数据的几年里,最大的心得就是数据这个事情要做好,最重要的就是数据源,数据源整好了,那就成功了一半。数据采集的基本原则是全和细。全就是要把多种数据源都要进行采集,而不只是客户端的用户数据。细就是强调多维度,把事件发生的一系列维度信息,比如订单运费、成本价格等,尽量多的记录下来,方便后续交叉分析。
其次,要有一个数据架构师,对数据采集工作负责,每次增加或变更数据采集点,都经过审核管理,不是顺便搞搞的事,要系统化。最后,我这里要推荐 Event 数据模型,针对用户行为数据,简化成一张宽表,将用户的操作归结为一系列的事件。
对于埋点混乱的问题,前面提到的数据架构师的角色,要负责对这块的管理。如果前面完成对 Event 的梳理,这里的埋点就会清晰很多。这里还要推荐尽量从后端进行埋点,这样就不用多个客户端埋了。当然,如果有行为只在客户端发生,还是要在客户端进行的。对于业务复杂的情况,只有负责人还不够。目前我们神策分析针对这个问题,也是推出了埋点管理功能,对于每个采集点的数据收集情况,都能够做到监控,并且可以针对一些无效采集点进行禁用。总之是希望把这个问题尽量好的去解决。
对于数据团队和工程团队的配合问题,我这里是想说给创业公司的创始人听的。如果让两个平行的部门去推动,那是很难的。数据的事情一定要自上而下的推动,也就是创始人一定要重视数据,把数据的优先级提升,这样在项目排期时,能够把数据的需求同时做了。我们知道两军对战,情报收集工作的重要性。在做产品时,数据收集工作的重要性就不言而喻了。
最后,期望越来越多的创始人,从拍脑袋做决策逐步向数据驱动决策做出转变。
------------- 原文End
知乎的一个回答,几代采集方式
第一代的采集:服务端访问日志
第二代的采集:页面埋点上报
第三代的采集:基于xpath(页面结构)的“无埋点”
第四代的采集:基于事件抽象的全量日志
第五代的采集:基于本地存储和客户端分析的全量日志
名词解析xpath : 分为精确路径和概略路径两种做法
精确路径 : body>div[0]>div[3]>ul>li[5]>a[0] ,从被点击的元素不断向上查找到根节点,并记录过程中每个节点的。
概略路径:body>div.header>div.nav>a[23],在前者的基础上省略上溯路径中非白名单中的节点如果把报表和可视化的问题加入考虑范围的话,我们会发现精确路径存在在一个缺点,就是同一个链接,可能因为头部加了一个公告或者dom结构上做了细微的调整,数组下标就会发生变化,让看多天数据变得困难。概略路径在一定程度上能够屏蔽这种变化带来的影响,但依然只是程度上的区别,并且需要有较强的开发规范的把控。
事件抽象:用户在网站上的所有操作都可以被抽象为事件(静止不动和页面失去焦点都是事件),上报的日志不再是定向的埋点结果,而是对所有发生的事件进行上报。
在事件的模型中我们可以把事件分为:瞬发事件和持续事件
瞬发事件:例如常见的点击
持续事件:例如常见的页面滚动
全量日志:对页面采集到的所有事件进行上报。全量日志由于不光考虑瞬发事件,还加入了持续事件,不做处理的情况下比前一代基于点击事件的上报要增加20-50倍的日志量,因此需要加入节流函数提升性能,和加入阈值机制把价值过低的事件放弃上报,以减少服务端对日志清洗的负担。
第四代和前三代最大的区别在于,无需因为分析方法和对象的改变而新增埋点,还有埋点上了之后还得等待几天的数据才能进行新的分析的等待过程。并且脱离了对业务代码、dom结构的侵入,以观察者的身份提交页面中发生的全量事件。拥有了全量信息的情况下数据分析方法的改变,立刻就可以进行。
第五代采集,目前处于设想和原型的阶段,已经跟身边的一些同事、朋友分享过,争议很大,姑且还是称做第五代采集。得益于localstorage、indexdb和v8引擎,浏览器端具备了简单的数据存储和分析能力。
第四代采集中因为性能、流量考虑而被抛弃掉的日志依然可以保留下来,以5m本地存储来计算,保留一个用户近1星期甚至近1个月的操作日志都是可行的,服务端下发计算规则,浏览器在完成计算后上报计算的结果,而每次的计算结果可以作为一个单独的快照保留,在规则没有变化的情况下做增量的分析直到规则变化重新生成快照。
能做到和为什么要这样做是两个问题,说说第五代为什么要这样设计:
简单的用户识别可以在浏览器端完成在拥有本地日志的情况下, 前端可以提供用户更好的体验分散服务端集中处理的压力
解决了用户隐私的伦理问题
假设一个重交互应用场景:对于第一次访问的用户,我们可以给出新手引导对于已经访问过,但操作让不熟练的用户,我们可以提供有针对性的提示对于熟练操作的用户,我们可以隐藏大多数的提示让操作界面变紧凑,甚至按照他的使用习惯调整页面结构。
简略说明一下熟练和不熟练的区别,任意两个事件可以组成一个任务,任务完成时间就以两个事件的事件差计算,通过任务的完成时间说明用户的熟练程度。再假设一个性能优化应用场景:通过全量日志我们可以知道,用户在访问a页面后最有可能的第一个操作是什么,做dns的预解析,静态资源的预测性加载。
伦理的问题,第五代和第四代的区别是全量日志是存本地的还是存服务端,第五代是把日志留在本地让用户自己可以进行管理,服务端得到的是计算后的结果。
最后提出一个假设:解决单个用户的“体验问题”,未必需要海量用户的参照。
----------------------提问补充-----------------------
关于评论中对第五代设计上的一些疑问:
方案中不排斥全量日志上报到服务器端,只是提供了两种可能性:
- 浏览器端对数据进行预处理
- 前端可以通过本地日志提供更及时的“响应”过去产品迭代的链条数据采集-->报表-->发现问题(人)-->决策(人)-->开发变更(人)-->发布-->采集新一轮数据。
我认为这当中有三个环节特别低效:发现问题、决策、开发变更。因为都依赖人,每个人对同一个问题有不同的理解,解决问题的能力也有高有低,开发周期不可控。当上述的链条只能做到1周一次或者2周一次的情况下,一年下来对业务的改善往往是极其微弱的。本地的全量日志,让浏览器端具备了简单的模式分析的能力,页面展现层可以在一个可控范围之内做出即时的调整,从而让用户的这次访问遇到的问题这次就得到响应,而不需要等待下一次的版本发布。至于更远的未来中如何结合AI来做即时响应的事情,现在拿出来讨论太早,先做着就好了。