Hello,大家好,欢迎使用Webfunny前端监控、前端埋点系统。
最近一段时间,我们整个团队都在忙着改造webfunny的clickhouse版,改造的内容非常之多,工作量非常之大,大家都忙得焦头烂额的。所以很多小伙伴提的优化建议,在这段时间都搁置了,除非是比较严重的bug,基本上都延后了,我能感受到大家着急的心情。其实,我比你们更着急,只是这块“骨头”太大,我们真的是啃了好久,到目前为止,基础版本至少已经接近尾声了。趁着喘息之机,我来记录下,同时也向那些提了建议,却没有得到满足的小伙伴表达歉意,敬请理解哈。
一、 为什么webfunny要做改造呢?
如果大家所知,Webfunny的部署非常简便。在准备好数据库后,我们的部署几乎可以通过一键完成。我们采用Node.js和MySQL来处理服务器层和持久化存储,同时Node.js也作为静态服务器。这一设置极大地简化了整个系统的部署流程,因为只需一个命令,就能启动一整套集收集、存储、分析、展示和警报于一体的分析体系。此外,Node.js对前端开发人员非常友好且轻量,而MySQL则无需赘述,两者组合虽然高效,但也有一些明显的弊端。
首先、查询压力大:mysql当初并不是为了大数据存储而设计的,面对高并发和海量数据存储的场景都显得尤为吃力。同时,mysql单张表的数据存储达到千万级别后,查询效率也变成了一大难题。在webfunny的使用场景中,或者说用户更期待的是即席查询,这就让本就已经不堪重负的mysql数据库更是雪上加霜了。所以我们不得不采取按天分表的策略来存储日志,这就导致了webfunny每天要创建很多日志表。
其次、日志表数量庞大,硬盘消耗快:日志表的数量创建过多,就会增加管理成本。虽然表的数量不会影响mysql的性能,但是服务器的文件数量一般会有限制。随着时间的推移,可能会产生几万张表,这就导致了存储周期没办法设置太长,一般只能设置在30内。另外,由于mysql没有设计数据压缩的机制,所以面对海量日志数据的时候,硬盘就会吃紧。如果存储时间过长,很快硬盘就会撑不住了。
最后、mysql不适合做集群化。基于上述两点,如果msyql不做集群化,那么webfunny的数据量级也只能保持在千万级,想要突破 亿级/天显得非常的困难了,所以、为了提升的支持的数量级,我们不得不做一些改变了。
二、 Mysql能不能做集群化呢?
mysql不适合做集群化,并不代表它不能做集群化。对于webfunny的场景来说,集群化最大的难点是不好区分用户UV数据,导致数据无法进行归类和分析,也就比较难做集群。
本来准备尝试阿里云的mysql集群版,后来发现这个集群版跟我们想象的不太一样。我们可以先看下阿里云上售卖的mysql集群版的结构图,实际它只有一个主节点,剩下的是备节点,可以简单理解为读写分离。所以它并不能做到集群化,且不能明显提升数据存储的量级。
那么,在webfunny的场景下,mysql该怎么做集群化呢?如下图所示:
首先、单个节点中,利用userId的特征分发到不同的数据库中,这样就可以保证每个userId只会存入到唯一的数据库里,再进行分库查询,然后综合统计数据就可以了。
其次、由于单个节点的承受能力是有限的,所以必然要面临扩容的情况,但是同一个项目数据必须上报到同一个节点中,否则多个节点之间是无法聚合查询的。因此我们需要在多个节点上层再增加一个分发逻辑,来保证同一个项目一定会进入固定的节点中。
这样就可以完成集群化了,且具备了扩容的能力,但是要加代码中加入很多聚合逻辑。
三、 用Clickhouse改造会有哪些优势呢?
虽然、在上一条中,我们说了,webfunny其实是可以做mysql的集群版,但是需要耗费高昂的成本,对我们来说并不是最优方案。所以我们最终选定,使用clickhouse进行改造。
1. 查询效率高、clickhouse号称10亿数据,毫秒级查询返回结果,也有各路前辈做到了20万亿行数据,1秒返回。让我们不得不心动。
2. 数据压缩率高、它采用了列式存储,同一列的数据相同率很高,所以列式存储对数据压缩有天然优势,节省硬盘资源。
3. 集群化、clickhouse天生支持集群化,同时有分区和分片设计,已经涵盖了我们按天分表的设计,能够让webfunny存储更大的数据量级。
四、 压力测试效果
压力测试效果仅以单机测试效果为例:
mysql版:2C4G,单机,最高峰支持2.8万/分钟的日志并发量
clickhouse版:4C16G,单机,最高峰支持20万+/分钟的日志并发量
从测试效果来看,clickhouse的效果更好,当然机器硬件有区别,但是这个数据量级的提升还是很明显的。
写在最后、webfunny改造完成后,能够支持更大的数据量级,在使用体验方便也会有更大的提升,欢迎继续关注。