如何实现海量数据下有序漏斗秒查

近期易观公司举办了一个OLAP大赛,我们队伍非常幸运地获得了第一名,成为本次比赛最大黑马。此篇文章主要是从技术角度,来分享一下我们是如何解决有序漏斗秒查问题的

比赛地址:2017易观OLAP算法大赛

参赛情况:  https://www.analysys.cn/media/detail/20018458/

1.  题目分析:

在以上示例场景下,我们在易观提供的6亿测试数据集上,在4台UCloud云主机(16core,16G ram)机器下从24s优化到了0.5s。而在正式比赛的26亿数据集上,使用相同硬件环境,耗时1.6s。

2.  解题分析:

题目描述的有序漏斗问题可以归结为 带滑动时间窗口的最左子序列问题, 比如我们需要寻找,2017年7月份中,在3小时的时间窗口下, [A,B,C,D] 漏斗路径下的转化情况, 单个用户只能有  NULL , [a], [A,B], [A,B,C], [A,B,C,D]  五种转化结果,对应的漏斗深度我们称之为level,在[A,B,C,D]漏斗路径下,level的取值可以有[0,1,2,3,4] 四个值,题目的要求即算出所有用户的满足条件下最大level汇总结果。

理解问题之后,我们梳理了一下流程图:

我们将问题解决分为5个步骤:

filter阶段 :根据时间区间和事件属性对数据进行过滤

group阶段: 根据用户Id进行group汇总

sort阶段: 按照时间进行排序

algorithm aggregate 阶段: 带时间窗口的子序列搜索

合并结果

3.  数据库选型:

根据以上分析,需要filter,group,sort,aggregate等操作,数据库是必备的核心,而在OLAP领域,开源的数据库选型有很多,比如:mysql, druid, kylin hdfs + (hive,spark,presto),imapla, kudu etc。

但在这个场景下,结合以往对其他数据的深入研究分析对比经验,我们几乎毫不犹豫就选择了 ClickHouse (纵然它不支持udaf),,我们相信ClickHouse是目前cpu领域最快的olap开源数据库,它最突出的优点就是快,如果你是第一次用,相信ClickHouse会让你感到非常惊艳。

ClickHouse 由俄罗斯Yandex开发,09年原型,12年生产可用,16年开源,目前最大的线上部署实例是 Yandex.Metrica: 472个节点,每秒处理2T数据,实时在线分析。ClickHouse 在OLAP上的查询性能非常彪悍,平均查询性能几乎是vertica的三倍。

ClickHouse不仅速度快,它系统架构灵活,性能优越,代码优雅, 非常适合大数据下需要极致性能的应用场景。虽然ClickHouse目前暂不支持UDAF,但没关系,由于它的架构非常好,我们可以通过修改源代码并重新编译来实现自定义AggregateFunction (即使我还是一个 c++ 菜鸟 ~~ )。

以上就是针对漏斗场景的代码修改情况,可以看出我们只用了不到300行代码就为ClickHouse加入了漏斗计算(aggregate function path)的功能, 修改的代码可以在文章末尾看到。

对比官方的presto + hdfs 方案实现的24s速度,使用ClickHouse之后,我们在测试环境下跑的速度达到了8s,这仅仅是一个基础版本的性能。

下面开始我们的正式优化过程

4. 按照用户ID分区:

我们注意到,漏斗的计算中,每个用户都是相互独立的,所以我们可以将数据按照uid来分区,这样就将数据分散到了四台机器上,我们可以分别向每个数据库节点发送请求,然后将数据进行汇总,得到最终结果。

通过这次优化,我们在测试环境下跑的速度达到了1.6s。

5. 以(uid,timestamp)作为primary key

ClickHouse中primary key代表了数据的组织排序方式

左边的以(timestamp,uid)为主键,时间是有序的,方便做时间精准过滤,但uid压缩率低;右边的以(uid,timestamp) 为主键,uid压缩率高,方便做uid group, 但对时间过滤支持不够好。

通过测试对比,我们发现以 (uid,timestamp) 作为主键性能略快,查询时间达到了 1.4s。

6. 分组预排序

当我们以 (uid,timestamp) 作为primary key后, 分组内的数据其实已经有序了, 我们可以去掉代码中的sort方法,来提高性能,经过这个优化,查询时间达到了 0.9s。

7. 带时间窗口的子序列搜索优化

这里主要是用了一些 剪枝的策略,当我们从左往右去搜索 a,b,c,d 漏斗的时候,我们需要找到最大的深度,必须一直去搜索以a开头的子序列;但我们从右往左搜索时, 我们只要考虑比当前结尾更大的子串即可, 比如我们找到了 a,b,c, 后面我们只需要考虑以d结尾的串,这样减小了搜索的复杂度,查询时间达到了0.8s。

8. 数据结构优化

事件ID到数组下标Index的映射,我们直接遍历了数组搜索,而不使用std::unordered_map, 因为在events数据量不大的情况下, 数组搜索O(1)比O(n)慢。

使用纯C++数组存储事件序列,不使用std::vector,去掉了vector的开销,灵活控制内存分配。

经此优化,查询时间达到了0.6s。

9. 部分压缩

数据库通常会对字段进行压缩,这样做节省了硬盘空间,但却浪费了cpu计算,为了提供性能,我们对字段进行了部分压缩,经此优化,查询时间达到了最终的0.5s。

uid  => 压缩

timestamp => 不压缩

event_id => 不压缩

event_name => 压缩

event_tag => 压缩

date => 不压缩

最后:

我们已经将代码和PPT开源:https://github.com/analysys/olap

为了满足通用漏斗的查询,结合电商分析的场景,新版的 windowFunnel 函数已提交给ClickHouse 官方,已被官方采纳  Add AggregateFunction windowFunnel  by sundy-li · Pull Request #2352 · yandex/ClickHouse通过这次比赛,0.5s的性能非常突出,但这绝不会是极限,如今GPU数据库大道横行,技术变革也愈演愈烈, 前路漫长,预测未来最好的方法就是自己创造未来,各位技术大牛们,一起努力!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容