01、背景
用户在App上的行为都通过埋点记录了下来,那在统计部分行为相关指标时,比如曝光人数、点击率等相关指标,就会因为缓存的影响导致统计的结果并没有真实反应用户的情况。就会导致曝光人数偏高、点击率偏低,在进行分析对比时就有可能得出错误的结论,进而导致决策的失败。因此需要一个方案来解决缓存对埋点数据的干扰。
02、缓存机制
App的功能在设计时,会考虑到用户的体验问题,一般会在App一级模块页面建立缓存机制,确保用户打开APP的瞬间能看到内容,而不是一个空白的页面。
缓存就是指用户访问App的某个功能或者页面时,客户端会向服务端请求最 新的数据进行展示,那这个请求到展示的过程是需要时间的,一般情况是毫秒级别完成这个过程,但是遇到用户没有联网或者在网络信号较差的环境,等待新数据加载出来的时间比较久。如果这个时候给用户一个空白页面的话,用户体验较差。所以大部分情况下展示用户上一次访问这个功能或者页面时的内容,等最 新的数据请求成功后再对数据进行替换。这样的设计能让用户使用App时体验更好,因此大部分App都会有缓存机制存在,这其实也造成大家安装的App体积变越来越大的一部分原因。
由于缓存机制是App先展示上一次访问的内容,请求成功后再替换成新的内容。那对于埋点采集来说,这个时候先展示旧的内容也是发生了一次曝光,那等新的内容加载完成又会产生一次曝光,也就是会上报2次曝光的埋点采集记录。那对于实际用户来说,只要网络顺畅的情况,缓存内容替换最 新的内容花费的时间是毫秒级别的,肉眼是无法真正看到缓存的内容,一般只能看到被替换后的新的内容。因此这个时候埋点采集的缓存曝光就是无效曝光,用户并没有实际看到,也是无法进行点击。这样的数据业务方直接进行使用时就会容易造成错误的决策。特别是首屏直接能看到的内容,缓存影响的情况比较严重,跟其他非首屏的内容进行对比时,点击率会特别偏低,从而可能错误的以为内容不够好。
03、如何过滤缓存曝光数据
1. 简单方案
埋点数据中有一个参数是此内容的服务器下发时间的,因此可以用服务器下发时间和客户端本地的曝光时间进行对比,只要是非当天的内容就内容是缓存数据,对其进行过滤。
此项方案有比较多的缺点,首先对于当天的缓存曝光数据无法正确的过滤,另外对于有些接口请求失败的case来说下,跨天的曝光数据也是真正发生曝光的正常数据。这样是相对比较简单粗暴的进行缓存数据过滤,在执行了一段时间之后就放弃此方案,此方案的唯 一优先就是开发成本极低。
2. 精细化方案
缓存的本质就是用户访问时,是否请求接口之前展示的数据,因此客户端可以根据这个逻辑进行缓存曝光的标记。客户端对用户访问的曝光进行监控,接口请求之前的日志标记为缓存日志,接口请求结束后的日志标记为正常日志,如果请求失败则会把缓存日志重新标记为正常日志。这样就能真正意义上去设别曝光数据是否为缓存曝光。并且对于网络不佳,虽然展示缓存内容的曝光,可以正确的标记为正常曝光,因为这种场景下用户也是正常看到了展示的缓存内容,对于数据统计来说确实需要标记为正常曝光。
04、如何验证缓存日志标记的准确度
精细化方案标记缓存日志的方案,由于整个埋点架构方案设计的比较合理,使得进行缓存标记时客户端的实现成本并不高。但是这个曝光数据对于业务来说是非常重要的数据,如果保证客户端的缓存标记的准确度是足够的,才能让这个标记上线。
1. 缓存刷新逻辑
页面的缓存实现逻辑可以分为进入页面刷新和定时刷新这2种逻辑。进入页面刷新代表打开页面时会先展示缓存内容然后请求接口后替换为新的内容,以返回的形式打开页面或者App退到后台后回到前台的形式打开页面的2种case不会触发刷新逻辑。定时刷新是指打开页面距离上次打开的时间超过一定时间就会刷新(一般是10分钟左右),并且杀死App后重新打开App时,不管距离上次打开页面有多久都会强制刷新一次。
2, 数据验证方案
基于上面2种页面的缓存刷新逻辑设计一套数据验证方案,核心验证的点就是:该标记为缓存日志的没有正确标记,不该标记为缓存日志的却错误标记。
1) 不该标记为缓存日志的却错误标记
不该标记为缓存日志的却错误标记的情况是比较不能容忍的,因为这个会丢失正常曝光的数据,因此目标是这个错误标记的概率希望能维持在万分之一以内。验证逻辑为:由于对曝光数据大部分情况下都是统计人数,很少去曝光次数这个指标,因此只需要保证服务器下发时间和曝光的触发时间在定时刷新的时间之内的缓存曝光日志在当天非缓存的曝光日志中有一条相同的日志即可,因为只我们统计人数,不关心次数,因此同一天就算有错误标记的曝光日志也没有影响,只需要在非缓存曝光日志找到一条相同的结果就不会影响人数的统计。另外再去掉杀死App重新打开case的缓存日志这种正常标记的情况,就可以得到错误标记的比例情况。
2) 该标记为缓存日志的没有正确标记
该标记为缓存日志的没有正确标记的情况相对的容忍度会好一些,并且不会影响正常曝光日志的统计,只会把一些缓存曝光错误的统计为正常数据,跟当前对全部曝光日志进行统计的情况而言只是过滤缓存没有百分比到位,也已经比统计全部曝光日志更贴近真实情况了,因此目标是错误标记的概率维持在百分之一以内即可。
验证逻辑为:我们先默认服务器下发时间和曝光的本地时间超过定时刷新的时间日志就应该标记为缓存日志,然后再排除从下级页面返回上级页面的case;另外没有定时刷新逻辑页面还需要排除前后台切换的case,就能得到错误标记的比例情况。
根据上面2种验证方式就可以得到错误标记的日志,就可以根据这个用户的全部埋点日志去还原其行为情况,从而找到为什么标记错误的原因,对于bug部分就行修正,对于如果说是正常的case就在前面验证方案里面加上此case的排除,这个部分问题原因的寻找,是十分消耗精力的,整个项目最耗时的部分就这里。
经过各种bug修复最终得到符合预期的错误标记比例后,缓存曝光的标记就达到上了可以上线的标准。
05、曝光统计口径更变
数仓直接在ODS层的日志进行缓存数据的过滤,这样下游就不需要任何的变动,就可以让所有的报表曝光相关指标都替换为去掉缓存的统计口径。由于这个缓存的标记是由客户端进行的,因此是需要发版本处理的,导致无法对历史数据进行重刷,只能上线当天开始生效,也就是这个切换日志前后同个指标统计的口径是不一致的。基于这个情况一定需要对使用数据的业务方进行宣导,要不然后面非常容易的产生排查,各种业务方来咨询我的业务数据怎么下降了。
06、缓存标记监控
对于缓存标记当下的bug都已经解决了,但是在客户端版本迭代的过程中难免会发生开发业务 需求时导致缓存标记出现了bug,数据组需要保证这个缓存标记是稳定可靠的,因此可以基于缓存标记验证的方案设计一套埋点缓存标记的监控体系,确保所有有缓存机制页面的缓存标记的准确度都在阈值之内,在发生异常情况时,及时联系客户端开发工程师寻找问题修复bug。
07、最后
数据组有责任保证所有提供的数据是准确可靠的,对于这种缓存曝光的统计虽然不是数据开发问题导致的不合理统计结果,但是数据组还是有责任去推动送缓存曝光过滤的项目落地,给业务方更真实的统计结果,确保业务方能使用正确的数据做出合适的决策,驱动业务增长。
作者介绍——@杭州:阿坤,母婴电商行业数据分析师兼数据产品经理;致力于研究电商行业的数据驱动增长;以及数据产品从0到1的搭建;“数据人创作者联盟”成员。