最近在优化游戏内用户行为事件上报的项目,遇到了传统架构设计上的一些性能瓶颈。主要表现在数据查询性能上,由于用户在应用内行为的事件数据体量非常庞大,表总行数百亿级,
即使在项目中用上了性能强悍的ClickHouse做数据查询加速也显得有点“杯水车薪”,在无法无限堆积硬件性能和马上影响业务之际,我还是“垂死挣扎”了一番,改变了一下思路(其实是大佬
们给的思路),把原来从DB捞数据的方式改造成数据源头直接流式处理的方式,这种方式主流程上不依托DB介质的查询,“没有中间商赚差价”,数据处理效率成倍增长,解决了当下项目的
“囧境”。
我们先了解一下这个项目的原来的一些数据流程
从上面可以看到,我们的用户在应用内的行为数据是会经过ETL清洗后落库,落库后的数据会被程序根据用户既定的一些规则捞出来,汇总后上报给第三方。整个流程看似很正常,也符合
传统的一些架构设计特征,项目运行好一段时间都比较稳定。
但最近出了几起故障,整个数据流变得不稳定,以至于上报给第三方的数据出现了延迟,影响了业务。后续对此深查分析了一波,发现近一段时间ClickHouse的查询变得越来越缓慢,原来
一整批次的规则查询任务都能在15分钟内完成,现在慢得竟然需要1个多小时才能完成(PS:业务得要求需要半小时内完成),因此频频出现上报延迟故障。
在联合DBA分析了各种可能得原因发现,这个库并非项目独立使用,除了我们自身使用外,还有别的项目在使用,而且有大批量的更新行为,引发了CK集群的大量数据merge动作,造成了
极大的性能消耗,此处有个知识点,有兴趣的同学可以自行去翻阅一下资料,CK自身的特性,大批量更新是性能消耗的“头号杀手”。
二、方案改造
在遇到问题后,其实我们做了很多优化的工作,比如依托已有的缓存,减少点查,降低查询并发数,清理历史数据等等,这些工作虽然能带来一些优化提升,但整体效果提升不大,CK查询依然很慢。
怎么办呢?在煎熬了一阵子之后,也集思广益了很多大佬的想法(感谢各位大佬的建议和优化思路),也分析了用户既定规则的一些特性,最后决定改变一下现有架构的数据流程。既然DB介质存在瓶颈,
那我们就摒弃现有DB介质的查询,直接做成流式处理,在ETL节点直接加旁路处理,识别出可流式处理的规则,把命中规则的用户行为数据直接放上报队列里进行上报,如下图:
这里面有个小小的背景,用户既定的规则里面存在两种规则,一种是汇总类的规则,需要对数据进行汇总查询,此类规则暂时没法做成流式处理,另外一种是触发型规则,只要用户触发了此类事件就可以直接
进行上报,不需要汇总查询,此类规则就能做成直接流式处理。
此次改造,整体处理性能提高了不少,分两部分,如下:
非流式规则部分
原来每批次查询CK的任务数由7000+降到了2900+,降幅达到了60%,整批次任务执行时间由原来1个多小时降到基本15分钟内
流式规则部分
原来靠每批次查询捞出数据进行上报,改造成现在基本实时上报模式,上报及时性更高
1、此次改造把60%左右的规则做成了流式处理,剩余40%的规则还需要靠DB做汇总查询,后续还有优化的空间
2、由于做了流式处理,数据来一条处理一条,期间如果需要做加工,得提前做好规划,如基础信息补全等数据需提前加载到高速缓存,否则查询穿透到DB还是会有瓶颈
3、ClickHouse介质不适合做大批量更新操作,如果数据还需继续保存需考虑别的介质,如数据部正在推行的hologres