这是我们的一个界面,当数据注入之后,可以对数据进行一些维度上的分析。这是简单查询的例子,图的右边是一些维度的定义,比如查询来自于哪个平台,它的查询语言是什么,它来自于哪个页面,在这个例子当中看到对于这个查询日志数据来说来自于 iOS 平台、英语国家数量是最多的。 整个界面也是我们自主开发的数据可视化的模块,叫做 Superset,在 GitHub 上已经开源了,可以支持很多数据源,比如我们这里用的数据源,可以把实际数据发掘出来显示在图形上,同时有许多其他的数据源支持,还支持各种不同的可视化模块,比如说支持这样持续的线状图,基于地图的可视化,或者一些热点图、饼状图等等,这是一个非常好用的图形可视化服务。 异常检测 最后一点,我们还需要对数据进行一些异常的检测。 这是一个非常实际的例子,比如在某年 9 月 22 日上线了日期的选择组件,右边是我们 Airbnb 的主页,主页的第一行给大家显示了需要搜索哪里的房源,入住日期和退房日期是怎样的,让用户快捷地定义这个组件。我们打开了 AB 测试,有 50% 的用户可以看到这个新的组件,50% 的用户还是使用旧的日期组件。一个星期之后,9 月 29 日实验结果表明新组件导致搜索下降 14%,这是个糟糕的结果,我们就下线了新组件,搜索指标恢复。 这个例子的目的在于,一旦发生了错误,如何分析原因?这是一个繁琐的过程,基于很多因素,依赖于经验、试错和运气,经常开发中遇到上线新的产品、新的功能之后,发现指标比如订单量、搜索量下降了,需要找到根源所在。对于具体的例子来说原因是,如果把搜索的下降量按照国家、地区分类、搜索来自的平台,比如是网页版或者手机版,并且把搜索的下降按页面来分类发现,原来在手机平台上、意大利语页面搜索下降是最多的,而其他平台或其他维度没有受到影响。我们最后发现原来是新的 JS 组件,在特定的环境下、特定的语言平台下有 Bug,导致整个数据搜索量的下降。 我们开发环境中经常碰到这样的问题,怎样不这么繁琐、费人工的查找问题?开发了一个 Curiosity 系统对于顶层聚合指标进行自动异常检测。如何判定异常检测的组合,我们有策略地尽可能去尝试各种不同的组合,比如对于任何一个顶层聚合指标来说,有很多维度,如搜索的国家、操作系统、渠道,每一个日志数据会有不同的维度,这些维度会产生成百上千的维度组合,如何在不同的维度组合下发现聚合指标产生异常呢?这就是 Curiosity 要解决的问题。分几个步骤: 第一个,获取实际的数据源; 第二个,可以想象成一个广度搜索的过程,对不同的维度组合进行广度搜索,每次给定一个维度,对这个维度进行两个方向的异常检测,一个是水平方向,一个是垂直方向。所谓水平方向,时间序列方向,比如搜索来自的语言,在这个时间轴方向是不是有大的波峰或者波谷,我们就认为产生了异常。垂直方向就是给定一个时间段,对维度不同的取值是否异常,比如在这个时间段内来自于一种语言的搜索比其他语言的搜索行为更加可疑,就是个异常; 第三个,把水平异常检测结果和垂直异常检测结果结合起来进行裁剪,比如发现在水平维度上,只有英语国家产生了异常,就可以裁剪这个维度其他值,使得广度搜索不会指数级的增长。当我们对一个维度分析完毕之后,会把这个维度异常的值和下一个维度合并,进行下一个广度的搜索。 具体到实现,我们抽象了具体的设计接口,开奖,是因为虽然对于异常的检测,不同的系统需要不同的算法、不同的数据源,比如数据具有季节性,因此一个简单的检测波峰和波谷按照阈值的检测不一定能够有效,我们就会用其他的一些算法。所以在实现 Curiosity 的时候,每个模块都进行了接口化的设计,数据源的获取,水平异常检测,垂直异常检测,然后维度裁剪,广度搜索。对于每个接口我们有基本的实现,比如对于数据源实现了 Druid 数据源,对于检测我们实现了基本的算法,比如基于阈值或者 Kalman Filter,算法都是可定制化的。最后把广度搜索分片,基于 Spark 支持分布式运行,加快异常检测的过程。 (责任编辑:本港台直播) |