10月20日,荣之联实战课堂第4期的《解读大数据分析:新技术,新实践》主题沙龙上,神策数据联合创始人兼cto曹犟跟大家分享了神策数据用户行为分析产品的设计与实现。
一个用户行为分析产品的设计与实现
用户行为分析产品。所谓的用户行为分析相当于是在ga组织上更进一步,看到基本的pv、uv基础数据之外,还能从事筛选多维分析,支持漏斗衡量流程转化,像分析产品使用情况,点击分析,对产品约束,技术目标能够支持亿级dau,所处理数据量每天大概几百亿条数据左右,希望在庞大的数据规模下面,能够实现两个秒级: 秒级入库;秒级查询。
第二,当时客户端概念成熟,除了常见的网页、安卓、app,各种小程序、h5界面,结合技术需求产品需求,希望用户行为分析产品可以支持各类客户端采集,实现同一个用户在不同端不同频上把控。
第三,重要的产品数据功能需易于扩充,对数据不需要太大的改进。同时,作为一个分析产品,而不是统计产品,功能应该易于扩充,技术设计更开放扩展能力,就无需增加新的分析功能,重新重构数据等等。
第四,需要灵活的分析功能,任何分析功能都可以下钻、筛选,维度指标无需预先指定,灵活定义。
第五,数据完全对客户开放。
流程分析界面。所有初始行为、后续行为,描述了分析功能需要非常灵活。整个数据处理过程分为五个环节,从最开始的数据接入,到数据如何传输,到数据建模存储,数据查询,数据可视化/反馈。
上图是系统的逻辑模块架构,基本上按照数据处理五个环节进行描述。
数据接入。作为用户行为分析产品,采集的数据主要包括三类。第一类是前端操作,即客户端操作,可理解为一个用户在app或者网页上的各种点击、提交等操作,然后提供从全埋点到可视化埋点、代码埋点。全埋点是采集所有的页面浏览、控件操作、app启动等。可视化埋点在全埋点基础上,预先通过可视化方式的采集指定控件操作,无法自定义属性。代码埋点,可以自定义属性,在每个埋点写相应的强代码,采集文秘从低到高支撑,从简单到困难的三个埋点方案。
此外,还要做客户端采集,面临通过公网具体传输数据的问题,针对ios、安卓sdk的数据发送策略,保证用户体验是优于保证数据准确性的,宁愿可以牺牲一部分数据的实效性,也希望sdk不去影响整个客户的app使用的体验。同时由于公网进行网络传输不可能采集一个数据之后,立刻通过一些post之类方式进行数据的传输,是需要先把数据缓存在本地,很多app可以离线使用,虽然中国网络条件比较好,大量客户做app出海,分布在印度、非洲,会碰到2g、2.5g网络环境。因此,立刻发送数据会直接影响产品本身用户体验,默认情况下只在条件良好时发送数据,并且在发送数据对数据进行打包压缩。
另外,为了保证效果,虽然在网络环境非常好情况下发送数据,但是对关键数据,例如:了解产品激活,通过某些推广方式带来假的激活,产品打开立刻被退出被卸载了,或是坚持仅在网络良好,就会遗漏。若尝试发送时不考虑网络,最终提供强制发送的接口,除了前端操作之外,技术条件良好的企业能够意识到日志重要性,知道如何打日志。
神策也提供一种方式采集后端日志,相比于前端操作,后端日志采集内网在可控的网络条件下面,面临安全性准确性小很多,后端日志从后端模块采集,对后端模块变更上线反应更快。app更新有漫长审核流程,无法保证15天有多少客户更新,但在后端日志控制,除了用户操作,后端日志之外,有很多有订单或者线下业务比较重的客户,数据都存在业务数据库里面,所以需要提供这些数据采集。
这就需要相应的数据导入工具,简单来说,后端导入一方面提供代码埋点,帮助客户找出合理数据,另外通过各种导入工具批量采集数据输出。
id-mapping。当然系统内部会有唯一的id,比较支持客户调用相应接口,将不停id贯通起来。这时要保证整个数据的时效性,保证整个回溯的过程。如果需要回溯,那么整个数据需要重做,这里对id-mapping会有约束和限制,虽然是理想的,部分功能可以直接导入80%以上,却带来性能上的保证,这就是功能和性能的折中。
nginx。所有sdk采集工具,不管通过公网内网,通过cps协议发送协议调用相同api,在数据接收用nginx作为整个数据接收方式,nginx接收这些数据,落到日志文件,能够保证良好的可靠性和性能。同时,接收上也能保证良好的可靠性和性能,让数据接收、数据采集配合接收能支持很高的容量,那么,采集的数据在最快的情况下,即使id-mapping处理不过来,可以研发模块实时读取日志,并且把接口发到卡里面,包括数据格式校验,属性识别,以及一些类似于ip设备型号。同时,神策可以提供接口,整个数据处理过程开放给客户来做自定义。
kafka。前边提到nginx做到5万tps,但是在做数据处理并写到存储的时候,处理性能无法达到,中间需要有数据的缓冲,同时也是近期数据的备份,存储写的过程出现丢了数据等等,可以从kafka找回。如果kafka上数据是错的,可以从备份中调取,所以说宁愿去存一些看起来信息上有冗余的数据,也要保证数据本身可靠,除此之外,kafka提供对外访问api。那么在数据接入之后,相当于对数据做 etl并且写入存储。
存储要跟数据模型本身配合。这里把用户行为相关数据抽象到两个,第一个用户做了什么,大概有event、user id + properties,追加为主,不可修改,有限的删除能力。存储中有两个核心的存储引擎,一个是kudu,它是目前开源存储,用作wos,选择kudu逐条导入。选择parquet把它作为ros,查询扫描优化查出,结合应用场景,产品特性,可以按照日期、事件分partition。
首先按照日期分目录,日期按照不同事件分目录,同一个目录包括多个文件,写存储,会产生碎文件,在这个过程中又有后台程序负责把碎文件合并,保证合理的大小,从而提高整个数据扫描的过程。同时,在一个个合理文件大小内部,又结合自身的应用场景。做用户行为分析对于整个产品查询非常重要,所以简单理解为每个产品内部在user-id的hash有序,再按照user-id有序,最后按照事件时间排序,单独的搜索文件记录每个user-id对应行为数据的位置,具体分析时候只需要三四面,也能大大减少对于存储扫描空间,从而提高查询效率。
写多少秒,例如开始往一个表里面写,写到一百万条可以做标记开始往表1写,表1写到一百万条往表2里面写,相当于总有一个表写,后台会有程序定期把表1所有没有处理的表里面的数据扔到parquet,转的过程遵循partition定义的方案,可能会带来很碎的文件,由于sdk传输方案,今天上午10点接到前天数据,对应只有一条数据,就会产生只有几k碎文件,影响整体性能,所以会有刚提到的过程。
从kafka中订阅数据写到kudu就可以被查到了,相当于写入流程从nginx写到kudu,保证在十几秒钟,如果有流量暴涨,处理跟不上导致带来处理上面时效的延迟,所以还能够保证数据能够接收,能够被储存,只是没有及时处理。在查询选择时,每个查询消耗时间保证在毫秒级,没有选择这两个开源组件有两个原因,而且漏斗必须用sql描绘,因此选择impala。通过每个pv从用户每条行为计算,扫描全表,因为有各种查询优化让这个过程并不是特别慢。选择impala保证公司能够支持,产品定位给产品运用整个应用是合适的,保证在秒级无法保证在毫秒级,这是查询,前端产品界面可以选择各种查询条件等,会发给wubservre。
查询优化。首先修改 impala 代码,由于 impala不支持udf,聚合函数替代join,partition与用户分桶,减少数据扫描量,按照用户抽样,快速尝试,最终才能准确结果,也就是,在产品设计应用层面上规避查询响应时间的设计。在应用层面上缓存,只对有变化的数据才重查。比如,早晨8点查询过去30天销量,当时花了30秒数据,下午2点有另一个人提交了查询,可以判断从上午8点到下午2点,前三天数据有变化,27天没有变化。第一次从缓存取过去27天数据,剩下三天数据从存储查询。
元数据。数据流从数据采集到数据的接入,再到etl,写到存储,再到存储查询的过程。神策数据支持私有化部属,部属在客户环境下面,需要做额外的工作,针对元数据,mysql/zookeeper/redis,schema、维度字典,概览、漏斗、分寸、预测的配置,任务调度信息。
monitor。神策自主研发,主要用于对内部模块做语义监控,定期检查模块是否存活,检查各个强度任务情况等等,而对一些外部组件,通过api去做监控,可以获取所有的监测数据,也可以发给客户的运维,并且对内部模块做修复。例如,发现内存使用上限,自动调到内存把它重启,看起来不太起眼,但是在实际实践中,可以减少运维工作量,让用户有更好的体验。除此之外,神策的产品是按照licensee进行处理的。
运维工具。由于神策的产品是私有化部属,大部分时间不需要到用户现场做运维,除了用户愿意开通远程桌面等协助方式,会给客户提供工具做运维,这些工具包括基本数据清理工具,有些数据没有意义,可以删除到数据虚拟工具,提供一个月到两个月迭代。
荣之联微信可下载ppt