Skip to content

Latest commit

 

History

History
127 lines (74 loc) · 6.55 KB

数据产品的统一复盘.md

File metadata and controls

127 lines (74 loc) · 6.55 KB
date tags
2019-07-01
软件

工作也有三年了,自己曾较深度的做过三个数据相关的产品,虽然是断续的三段经验,但是他们还是很有共性的。复盘一下,趁着还没忘干净。

数据产品的核心组件

  • 上报sdk:
    • 也有可能没有上报sdk,直接从一众日志,或者现成的队列里拿数据。
  • 数据处理:
    • 包括数据清洗,数据的分布式计算。
    • 本质上是某种方式的离线数据或者实时数据转换成某种方式的在线数据,在线数据保证了查询的速度。核心是时间和冗余换查询速度的思想。
  • 数据展示:
    • 选择合适的可视化组件。

上报sdk

一般来讲分为两种sdk:

  • 用户行为上报。
  • 性能指标上报。

其实他们在前端的大概实现思路是一致的,那为什么要分开做呢?

  • 一般来事件监控跟性能监控不是同一波人维护的。
  • 性能数据几乎不需要自定义维度,事件监控几乎都有自定义维度,它是一种业务数据。
  • 性能数据可能需要采样,事件监控几乎不采样。
  • 性能指标可通过指标名自定义聚合方法,它支持传值(比如ttfb为300ms)。事件监控其实就是简单的累加,但实际上它的产品形态更复杂,这个后面再说。

上报sdk通用技术点

日志上报sdk的一些通用的需要注意的点。

1)找一种跨域的上报方式

因为数据服务往往不与网站主体同域名,不占并发,也容易统一管理。

  • 使用动态插入的img标签,写一个这样的http接口即可/_.gif?
  • 使用cors。

2)对于退出事件的处理

因为退出时的请求失败率很高,需要些特殊的手段,或者折中方案。

  • sendBeacon。This method addresses the needs of analytics and diagnostics code that typically attempts to send data to a web server prior to the unloading of the document.
  • 使用jsBridge交给native上传。
  • 使用替代模型达到同样的数据表达效果。

最后一点需要解释一下。这是我在上一家公司时用过的一个方案,大家接受度也比较高,但还是把它算作一种折中吧。页面加载后的第5s 10s 30s 60s 分别打点,收集到的打点次数这里标记为t5,t10等。然后画一个频度分布直方图,从左到右分别是pv-t5,t5-t10,t30-t10,t60-t30,t60。这个图可以直观的反应页面停留效果,左高右低效果不好,右边较高说明效果较好。绕过了退出问题,也提供了一个更好的可视化模型,缺点是用户上报了好几次,费公司的流量。

3)navigation-timing

主要参考navigation-timing,也需要参考一些约定,甚至公司内的黑话(可能稍有不同),比如我们这边是这样定义的。

  • 白屏(blank): responseEnd - navigationStart
  • 可交互(domready): domInteractive - navigationStart
  • 完全加载(load): loadEventEnd - navigationStart

4)加载代码,版本控制

  • 不同业务方的诉求不同,有的希望稳重些,他们会固定版本,有的希望激进些,版本是latest。需要告知不同加载模式的写法。
  • 一般来说加载都是异步的形式,这就要求加载代码中最好自带一个buffer,buffer肯定是同步的,等真正的异步sdk程序加载之后再把buffer flush到服务端。

数据处理

这方面不是我擅长的,简单说下。

影响方案选择的有这几个要素:

  • 实时性要求。
  • 查询速度要求。
  • 精度要求。

主要影响两个基础设施的选型:

  • 计算框架。
  • 存储方案。

1)第一个项目,天级别实时性,高查询速度,高精度。

没用计算框架,最开始用的是ETL把数据从hive写到在线的mysql里面,后来用了高级些的Apache Kylin,本质上都是使用冗余索引提高查询速度的存储,对于较多数据的查询,Apache Kylin要优于mysql。

2)第二个项目,实时计算,高查询速度,中高精度。

使用storm+kafka,实时计算,前期存储到mysql,后期使用es。

es很强大,比如它能很方便的支持时间粒度聚合,支持分位数查询。当然这依赖于公司强大的基础设施支持,我本人对这方面了解很浅。

中高精度意味着可以使用storm,storm是可能多算的,简单解释,它的数据是树形衍生的,某节点失败,整个树重新衍生。

采样,对于极大流量的应用,通常是十亿级别的上报,一般会从sdk层就做配置下发,控制采样率,队列都不让他进。

3)第三个项目,小时级别,高查询速度,低精度。

使用spark分析用户日志,数据以kv的形式存储到hbase中。

这个项目根本不要求精度,它是官方对外的一种口径,指标只要符合整体趋势即可,比如最近“特朗普”很火,那“特朗普”在系统中的热度要更高。

由于最高支持小时粒度的,所以最开始这个系统是使用key来替代常规索引的,其实它是一种类hash索引的实现。比如A指标今天在北京,全品类的数据,它的key对应,20190202.beijing.all.A。看上去很挫但是很简单好用的方案。

数据展示

说起数据展示,有些值得注意的细节。

1)柱状图饼图折线图的使用。

饼图和柱状图中的各个维度之间的关系往往是平行的,饼图最能直接的反应维度在整体中的比例,柱状图最能反应维度指标的高低,对于细微的差距,也可以通过减小y轴的起点来放大,这是饼图不具备的。

饼图可以作为柱状图的辅助,像highchart支持将饼图compose到柱状图。

柱状图还有一种功能是它能更好的描述频度分布,在上面解决退出问题的例子中,柱状图整体的形状其实反映了用户参与效果。

饼图和柱状图都支持分组,其实差别很大,饼图的分组可以理解为二级分类,也可以叫做旭日图,用在知识图谱展示上。柱状图的分组往往跟主维度不相关,它们的关系是组合的,是笛卡尔积。

折线图往往是时间维度的趋势,这个其实没什么可说的。

2)二次开发

有时候需要二次开发,你需要提前确保框架有二次开发的能力,举两个例子。

需要让chart.js支持圆角,需要做一些hook处理,比如说要实现Chart.js的圆角

vis.js的绘制hook,beforeDrawing