常来看看的小伙伴都知道我最近在搞个分析系统。

 

已经停下来好些天了,最近重点在尝试各种存储情况来进行最终选型。

 

我们常规使用的各种sql库,是行式存储,这个就不必多说了,都知道。

我重点尝试了一下列式存储clickhouse。

 

先说亮点吧,聚合速度大概是暴力优化过的mariadb/mysql的几十到几百倍。我说的聚合是通过原始数据经过一系列最大、最小等计算得到结果数据。

批量载入数据(也就是把几十G的csv文件填充进库里)的速度等同于你硬盘速度,读取完也就载入完了。而这个事情,mariadb的速度慢了百倍到二百倍左右。

有mysql协议兼容层,现有sql只做很小改动或者不改动就可以直接用clickhouse,甚至用mysql客户端可直接连clickhouse。。。

我想起十几年前做idc的时候,有个骚货为了挖墙脚,就开着车等在机房门口,现场谈客户。。。

数据压缩存储,我这47.6g的数据,选的是zstd,放这个库里只用11g。。。

 

然后缺点,内存使用量很高,而且后台压缩、排序什么的对机器要求高,vps普遍玩不转。

 

列式存储,顾名思义就是与行式存储反过来的,行式存储的单位是每一条数据,列式存储的单位是每一列数据。

而多数时候,我们要进行数据分析的话,都是针对一部分字段,而这个clickhouse在存储方面做了可以说是能想到的最大优化,甚至机械盘用它都能把硬盘性能发挥到极致。。。他把数据安排的首先是顺序排列,也就相当于mysql的索引,然后写在连续的硬盘空间,所以机械硬盘连续读取的话效率最大化。

 

之前我这的测试数据是基于mariadb+aria表+全内存,就是把mariadb的整个库放内存里了,注意不是用的内存表,是把myisam/aria这种表放在内存盘里。这样的代价是成本很高,效果就是速度快到极限。

而用clickhouse的话,我这里物理机4个2t的接近砖头盘了,做的raid 0,聚合速度居然比mariadb还快。。。

 

终于在今天,我这里技术方面的细节,分析模式算是暂时完成了,想了想有点不服气,又做了一个尝试,结果我又犹豫了。。。

 

两市日线数据是1800多万,放mariadb里也就1.3--1.4g的样子,做了几种情况的实际分析策略的实景测试。

 

e5 1650v3,内存64g,硬盘4个2t的砖头盘,数据量1800多万,分析策略提取数据大概6万多轮,不到6.5万,总使用k线数据量大概3.8亿,这中间还要计算几轮指标,总数据量大概估算是7到8亿左右。

rust+rhai+clickhouse,耗时 164秒

rust+rhai+mariadb内存存储+未优化,耗时没完成,因为当时给脚本设置的500秒超时,所以超时退出了。。。

rust+rhai+mariadb内存存储+全字段索引,129秒

rust+rhai+mariadb硬盘存储+全字段索引+一个cpu比较强的vps环境,119秒

 

好吧,看到这个结果,你大概就能猜出我为什么纠结了。

因为clickhouse在各种优化设置以后,如果分配的内存少于一定数量,还是会不定时报错内存超限,所以用这个的代价其实也不低。只是特别适合我这个机械盘+大内存的场景。

而我用vps尝试以后,我发现小内存+受限硬盘(vps的硬盘被限速300M),实际上也能打赢列式存储的王者。。。

而打赢的原因是做了全自动索引,再加上我的场景是全自动提取。我记得豆包跟我提过一嘴,说全字段索引实际上相当于列式存储。。。

我又详细问了一下,它给我解释的原因是这样,索引还是行式存储,但是经过存储优化和排列优化,就相当于一个数据块,虽然读取的时候仍然会遍历每一行,但是不用回表,而且因为存储优化,所以也是顺序读取,所以虽然io效率仍然比列式略低,但是“扫描覆盖索引” 和 “列式存储只读需要的列”,在IO 开销和计算效率上几乎无差别—— 因为不需要回表,索引就是你的 “数据本体”。

而我这里只有8个字段,每次使用都是全字段提取,所以列式存储的优点在我这完全不适用。。。

所以,这种情况下虽然技术上不完全等同,但实际效果和列式存储其实差别很小,甚至有时候会反超。

这样做的优点就是mariadb+aria表的内存使用是很少的,缺点是硬盘使用量比clickhouse大了很多倍,比如47.6g数据的话,索引我估计也要44g以上,这就是90g+,而clickhouse只用11g……

性能上,因为前面的对比是clickhouse+硬盘 vs mariadb+内存,所以明天还要再做一次mariadb+硬盘存储的对比,才能最终下决心。。。

 

因为程序设计的时候就考虑了多数据源,所以目前可以按需分配pgsql/mariadb/clickhouse,做到这一步我都在考虑做一个自己的数据抽象层了,但是实测下来pgsql的效率贼差,而且特难用,所以pgsql的部分已经没再维护了,后面考虑一下要不要做个文件数据源,然后自己做压缩什么的,按道理说,可能不会差太多。。。

 


实践出真知啊。

 

全换成相同机械盘阵列环境,数据如下:

单策略执行:

clickhouse没跑,就是上面的164秒

mariadb:126秒

 

多策略15并发:

clickhouse:1177到1183秒

mariadb:302到319秒

 

我这机器6核12线程,15并发已经严重超过cpu并发极限了,而且还算上数据库的话,整个系统是持续满载的。

跟我预期完全不同,实践数据胜于一切狡辩。。。

道理上来说,这种更擅长数据分析的列式存储,不应该啊。。。

ai提醒我,可能是我的用法全踩到clickhouse的肋骨了。。。

算了,适合自己的才是最好的。

 

一个逗事,第一次mariadb 500秒触发超时,我直接改了5000设置,起床发现仍然超时了,我以为这砖头盘加上超大文件,大概是真不行吧。。。

后来无意间发现忘了改设置,当时程序仍然请求的是clickhouse,而clickhouse我当时已经关掉了,所以他其实一直在等待。。。

 

所以,最终,mariadb才是最适合我的。

作者 听涛

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注