您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

记一次 ClickHouse 性能测试

时间:2022-08-15 14:07:31  来源:  作者:劼哥stone

前言

在工作场景中,我们会采集工厂设备数据用于智能控制,数据的存储用了 InfluxDB,随着数据规模越来越大,InfluxDB 的性能越来越差,故考虑引入 ClickHouse 分担 InfluxDB 大数据分析的压力,再加上我们业务上也用到了 MySQL ,所以本文就来对比下 MySQL、InfluxDB、ClickHouse 在千万数据量下的写入耗时、聚合查询耗时、磁盘占用等各方面性能指标。

结论先行

最终的结论是,直接使用 ClickHouse 官网提供的 6600w 数据集来做对比测试,在 MySQL、InfluxDB、ClickHouse 同样分配 4c16g 资源的情况下,ClickHouse 无论是导入速度、磁盘占用、查询性能都完全碾压 MySQL 和 InfluxDB,具体对比指标如以下表格:

 

MySQL

InfluxDB

ClickHouse

导入耗时

大概耗时70分钟

大概耗时35分钟

75秒

磁盘空间

12.35 G

5.9 G

2.66 G

全表count

24366 ms

11674 ms

100 ms

全表max/min

27023 ms

26829 ms

186 ms

全表平均值

24841 ms

12043 ms

123 ms

全表方差

24600 ms

OOM

113 ms

复杂查询1

30260 ms

OOM

385 ms

复杂查询2

470 ms

200 ms

8 ms

为了确保测试结果相对准确,以上每条sql起码执行5次,然后取中间值。其中 InfluxDB 表现比想象中的要差,甚至还不如 MySQL,可能是数据样本和测试用例不太适合 InfluxDB 场景导致的,如果大家对测试结果有疑问,可以 git clone [
https://Github.com/stone0090/clickhouse-test.git](https://github.com/stone0090/clickhouse-test.git)项目,完整验证以上对比全过程。

数据库简介

MySQL

MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品,是最流行的关系型数据库管理系统之一。它所使用的 SQL 语言是用于访问数据库的最常用标准化语言。它采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库。《高性能MySQL》一书中开篇明义讲到的最核心的一句话是“MySQL并不完美,但是却足够灵活”,它是架构中的万金油,庞杂非单一的项目中总会有它的用武之地。

InfluxDB

InfluxDB 是一个由 InfluxData 公司开发的开源时序型数据库,专注于海量时序数据的高性能读、高性能写、高效存储与实时分析,在 DB-Engines Ranking 时序型数据库排行榜上位列榜首,广泛应用于DevOps监控、IoT监控、实时分析等场景。
传统数据库通常记录数据的当前值,时序型数据库则记录所有的历史数据,在处理当前时序数据时又要不断接收新的时序数据,同时时序数据的查询也总是以时间为基础查询条件,并专注于解决以下海量数据场景的问题:

  • 时序数据的写入:如何支持千万级/秒数据的写入;
  • 时序数据的读取:如何支持千万级/秒数据的聚合和查询;
  • 成本敏感:海量数据存储带来的是成本问题,如何更低成本地存储这些数据。

ClickHouse

ClickHouse 是 Yandex(俄罗斯最大的搜索引擎)开源的一个用于实时数据分析的基于列存储的数据库,其处理数据的速度比传统方法快 100-1000 倍。ClickHouse 的性能超过了目前市场上可比的面向列的 DBMS,每秒钟每台服务器每秒处理数亿至十亿多行和数十千兆字节的数据。它是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS),简单介绍一下 OLTP 和 OLAP。

  • OLTP:是传统的关系型数据库,主要操作增删改查,强调事务一致性,比如银行系统、电商系统。
  • OLAP:是仓库型数据库,主要是读取数据,做复杂数据分析,侧重技术决策支持,提供直观简单的结果。

那 ClickHouse OLAP 适用场景有:1)读多于写;2)大宽表,读大量行但是少量列,结果集较小;3)数据批量写入,且数据不更新或少更新;4)无需事务,数据一致性要求低;5)灵活多变,不适合预先建模。

环境准备

在阿里云买一台 16c64g 的服务器,操作系统 centos 7.8,使用 sealos 一键安装 k8s,使用 helm 一键安装 mysql(5.7)、influxdb(1.8)、clickhouse(22.3) ,每个应用各分配 4c16g 的资源。

# 下载 sealos$ wget https://github.com/labring/sealos/releases/download/v4.0.0/sealos_4.0.0_linux_amd64.tar.gz && tar zxvf sealos_4.0.0_linux_amd64.tar.gz sealos && chmod +x sealos && mv sealos /usr/bin# 初始化一个单节点 Kube.NETes$ sealos run labring/kubernetes:v1.24.0 labring/calico:v3.22.1 --masters [xxx.xxx.xxx.xxx] -p [your-ecs-password]# 去掉 master 的污点,允许安装应用到 master 和 control-plane$ kubectl tAInt nodes --all node-role.kubernetes.io/master-$ kubectl taint nodes --all node-role.kubernetes.io/control-plane-# 获取 mysql、influxdb、clickhouse 一键安装 Helm-Charts$ wget https://github.com/stone0090/clickhouse-test/archive/refs/tags/v1.0.0.tar.gz$ tar -zxvf v1.0.0.tar.gz# 安装 Kubernetes 包管理工具 Helm,以及 mysql、influxdb、clickhouse 3大数据库$ sealos run labring/helm:v3.8.2$ helm install mysql clickhouse-test-1.0.0/helm-charts/mysql/$ helm install influxdb clickhouse-test-1.0.0/helm-charts/influxdb/$ helm install clickhouse clickhouse-test-1.0.0/helm-charts/clickhouse/

数据导入

直接使用 ClickHouse 官方提供的测试数据
https://clickhouse.com/docs/zh/getting-started/example-datasets/opensky,此数据集中的数据是从完整的 OpenSky 数据集中派生和清理而来的,以说明 COVID-19 新冠肺炎大流行期间空中交通的发展情况。它涵盖了自2019年1月1日以来该网络超过2500名成员看到的所有航班,总数据量有6600w。

# 在服务器 /home/flightlist 目录执行以下命令,该目录会被挂载到 mysql-pod、influxdb-pod、clickhouse-pod 内$ wget -O- https://zenodo.org/record/5092942 | grep -oP 'https://zenodo.org/record/5092942/files/flightlist_d+_d+.csv.gz' | xargs wget# 批量解压 flightlist.gz 数据$ for file in flightlist_*.csv.gz; do gzip -d "$file"; done# 将 csv 处理成 influxdb 导入所需的 txt 格式(此过程大概耗时1小时)$ Python/ target=_blank class=infotextkey>Python clickhouse-test-1.0.0/influxdb_csv2txt.py

MySQL

# 进入 mysql pod$ kubectl exec -it [influxdb-podname] -- bash# 连上 mysql 建库、建表$ mysql -uroot -p123456$ use test;$ CREATE TABLE `opensky` (`callsign` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`number` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`icao24` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`registration` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`typecode` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`origin` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`destination` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`firstseen` datetime DEFAULT NULL,`lastseen` datetime DEFAULT NULL,`day` datetime DEFAULT NULL,`latitude_1` double DEFAULT NULL,`longitude_1` double DEFAULT NULL,`altitude_1` double DEFAULT NULL,`latitude_2` double DEFAULT NULL,`longitude_2` double DEFAULT NULL,`altitude_2` double DEFAULT NULL,KEY `idx_callsign` (`callsign`),KEY `idx_origin` (`origin`),KEY `idx_destination` (`destination`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;# 导入数据(大概耗时70分钟)$ load data local infile 'flightlist_20190101_20190131.csv' into table opensky character set utf8mb4 fields terminated by ',' lines terminated by 'n' ignore 1 lines;# 省略其他29条导入命令:load data local infile 'flightlist_*_*.csv' into table opensky character set utf8mb4 fields terminated by ',' lines terminated by 'n' ignore 1 lines;# 检查数据是否导入成功$ select count(*) from test.opensky;

InfluxDB

# 进入 influxdb pod$ kubectl exec -it [influxdb-podname] -- bash# 导入数据(大概耗时30分钟)$ influx -username 'admin' -password 'admin123456' -import -path=/tmp/flightlist/flightlist_20190101_20190131.txt -precision=ns;# 省略其他29条导入命令:influx -username 'admin' -password 'admin123456' -import -path=/tmp/flightlist/flightlist_*_*.txt -precision=ns;# 检查数据是否导入成功$ influx -username 'admin' -password 'admin123456'$ select count(latitude_1) from test.autogen.opensky;

ClickHouse

# 进入 clickhouse pod$ kubectl exec -it [clickhouse-podname] -- bash# 连上 clickhouse 建库、建表$ clickhouse-client$ create database test;$ use test;$ CREATE TABLE opensky(callsign String,number String,icao24 String,registration String,typecode String,origin String,destination String,firstseen DateTime,lastseen DateTime,day DateTime,latitude_1 Float64,longitude_1 Float64,altitude_1 Float64,latitude_2 Float64,longitude_2 Float64,altitude_2 Float64) ENGINE = MergeTree ORDER BY (origin, destination, callsign);$ exit# 导入数据(大概耗时75秒)$ cd /tmp/flightlist$ for file in flightlist_*.csv; do cat "$file" | clickhouse-client --date_time_input_format best_effort --query "INSERT INTO test.opensky FORMAT CSVWithNames"; done# 检查数据是否导入成功$ clickhouse-client$ SELECT count() FROM test.opensky;

测试场景

MySQL

$ mysql -uroot -p123456$ use test;-- 开启性能分析set profiling = 1;-- 查询磁盘空间select table_rows as `总行数`, (data_length + index_length)/1024/1024/1024 as `磁盘占用(G)` from information_schema.`TABLES` where table_name = 'opensky';-- 全表countselect count(latitude_1) from opensky;-- 全表max/minselect max(longitude_1),min(altitude_1) from opensky;-- 全表平均值select avg(latitude_2) from opensky;-- 全表方差select var_pop(longitude_2) from opensky;-- 复杂查询1:全表多个字段聚合查询select count(latitude_1),max(longitude_1),min(altitude_1),avg(latitude_2) from opensky;-- 复杂查询2:从莫斯科三个主要机场起飞的航班数量SELECT origin, count(1) AS c FROM opensky WHERE origin IN ('UUEE', 'UUDD', 'UUWW') GROUP BY origin;-- 输出分析结果show profiles;

InfluxDB

$ influx -username 'admin' -password 'admin123456'$ use test;-- 耗时统计,queryReqDurationNs 是累计查询时间,2次任务的时间相减就是耗时select queryReq,queryReqDurationNs/1000/1000,queryRespBytes from _internal."monitor".httpd order by time desc limit 10;-- 查询磁盘空间select sum(diskBytes) / 1024 / 1024 /1024 from _internal."monitor"."shard" where time > now() - 10s group by "database";-- 全表countselect count(latitude_1) from opensky;-- 全表max/minselect max(longitude_1),min(altitude_1) from opensky;-- 全表平均值select mean(latitude_2) from opensky;-- 全表方差select stddev(longitude_2) from opensky;-- 复杂查询1:全表多个字段聚合查询select count(latitude_1),max(longitude_1),min(altitude_1),mean(latitude_2) from opensky;-- 复杂查询2:从莫斯科三个主要机场起飞的航班数量SELECT count(latitude_1) AS c FROM opensky WHERE origin =~/^UUEE|UUDD|UUWW$/ GROUP BY origin;

ClickHouse

$ clickhouse-client$ use test;-- 耗时统计select event_time_microseconds,query_duration_ms,read_rows,result_rows,memory_usage,query from system.query_log where query like '%opensky%' and query_duration_ms <> 0 and query not like '%event_time_microseconds%' order by event_time_microseconds desc limit 5;-- 查询磁盘空间SELECT formatReadableSize(total_bytes) FROM system.tables WHERE name = 'opensky';-- 全表countselect count(latitude_1) from opensky;-- 全表max/minselect max(longitude_1),min(altitude_1) from opensky;-- 全表平均值select avg(latitude_2) from opensky;-- 全表方差select var_pop(longitude_2) from opensky;-- 复杂查询1:全表多个字段聚合查询select count(latitude_1),max(longitude_1),min(altitude_1),avg(latitude_2) from opensky;-- 复杂查询2:从莫斯科三个主要机场起飞的航班数量SELECT origin, count() AS c FROM opensky WHERE origin IN ('UUEE', 'UUDD', 'UUWW') GROUP BY origin;

ClickHouse 为什么快

1、列式存储

数据是按列存储,数据即是索引;查询只访问涉及的列,降低系统I/O;每一列都由一个线程来处理,高效利用CPU资源;还为向量化执行做好了铺垫。

2、数据压缩

数据压缩的本质是按照一定的步长对数据进行匹配扫描,当发现重复数据的时候就进行编码转换。
因为是列式存储,所以数据特征很相似,所以数据中的重复项多,则压缩率越高,则数据体量越小,则磁盘I/O压力越小,则网络中传输越快。

3、向量化执行引擎

SIMD(Single Instruction Multiple Data)即单条指令操作多条数据,它是通过数据并行以提高性能的一种方式,可以简单理解为在寄存器层面对程序中的数据做并行处理,Clickhouse 在能够提升计算效率的地方大量使用了 SIMD,通过使用 SIMD,基本上能带来几倍的性能提升。

4、多线程和分布式

分布式领域存在一条定律,计算移动比数据移动更加划算,这也是其核心所在,将数据的计算直接发放到数据所在的服务器,多机并行处理,再把最终的结果汇集在一起;另外 ClickHouse 也通过线程级别并行的方式为效率进一步提速,极致去利用服务器的资源。

5、多样的表引擎

MergeTree 存储结构对写入的数据做排序然后进行有序存储,有序存储主要有两大优势:

  • 列存文件在按块做压缩时,排序键中的列值是连续或者重复的,使得列存块的数据可以获得极致的压缩比;
  • 存储有序本身可以加速查询的索引结构,根据排序键中列的等值条件或者 rang 条件,我们可以快速找到目标所在的近似位置区间,并且这种索引结构是不会产生额外的存储开销。

MergeTree 是 ClickHouse 表引擎中最核心的引擎,其他引擎均以 MergeTree 引擎为基础,并在数据合并过程中实现了不同的特性,从而构成了 MergeTree 表引擎家族。

ClickHouse 的优缺点

优点:极致的查询分析性能,较低的存储成本,高吞吐的数据写入,多样化的表引擎,完备的 DBMS 功能;
缺点:不支持事务,不支持真正的删除/更新,分布式能力较弱;不支持高并发,官方建议 QPS 为100;非标准的 SQL,join 的实现比较特殊,且性能不好;频繁小批量数据操作会影响查询性能;
目前还没有一个 OLAP 引擎能够满足各种场景的需求,其本质原因是,没有一个系统能同时在查询效率、时效性、可维护性三个方面做到完美,只能说 ClickHouse 是为了极致查询性能做了一些取舍。
ClickHouse 优缺点都很明显,是否采用还是要取决于和实际业务场景的契合度,适合自己的架构才是最好架构。

参考引用

  • 识堂 | 笔记分享讨论社区,让知识说话
  • InfluxDB优化配置项_sqtce的技术博客_51CTO博客
  • influxDB系列(二)--查看数据库的大小 - 立志做一个好的程序员 - 博客园
  • Clickhouse技术分享_大数据_scalad_InfoQ写作社区


Tags:ClickHouse   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
从Clickhouse迁移到Doris,数据仓库性能大提升
从一个OLAP数据库迁移到另一个数据库是一项艰巨的工程。即使能找到一些有用的数据工具,您可能仍会犹豫是否对数据架构进行大手术,因为不确定如何运作。本文分享如何从ClickHou...【详细内容】
2023-11-17  Search: ClickHouse  点击:(202)  评论:(0)  加入收藏
从使用的角度看 ByConity 和 ClickHouse 的差异
Github: https://github.com/ByConity自 ClickHouse Inc 宣布其重要新功能仅在 ClickHouse Cloud 上开放以来,一些关注 ByConity 开源的社区小伙伴也来询问 ByConity 后续开...【详细内容】
2023-10-26  Search: ClickHouse  点击:(246)  评论:(0)  加入收藏
列式数据库ClickHouse,大宽表聚合、报表一下全搞定
一、前言现在数据库的种类也是特别的多,大致的类别包括: 关系型数据库( MySQL、Oracle、PostgreSQL)。 非关系型数据库(Redis、MongoDB、Cassandra、Neo4j)。 全文搜索引擎和分布...【详细内容】
2023-10-08  Search: ClickHouse  点击:(335)  评论:(0)  加入收藏
基于CLICKHOUSE的数据仓库分层规范
数据仓库分层架构数据仓库我们一般分为接入层、明细层、实体层、主题层、应用层。各层存储的数据粒度不同。接入层:一般存储接收的原始数据,并给接入的数据打上接收时间戳。明...【详细内容】
2023-08-05  Search: ClickHouse  点击:(317)  评论:(0)  加入收藏
ClickHouse 技术研究及语法简介
本文对 Clickhouse 架构原理、语法、性能特点做一定研究,同时将其与 mysql、elasticsearch、tidb 做横向对比,并重点分析与 mysql 的语法差异,为有 mysql 迁移 clickhouse 场景...【详细内容】
2023-06-21  Search: ClickHouse  点击:(223)  评论:(0)  加入收藏
字节跳动开源ByConity:基于ClickHouse的存算分离架构云原生数仓
采访嘉宾 | 陈星、翟鹿渊作者 | 蔡芳芳、王一鹏热闹纷繁的 OLAP 赛道,又迎来一个开源新玩家。这几年 OLAP 赛道持续火热,国内外不少开源项目和商业公司活跃其中。在一众玩家中...【详细内容】
2023-05-22  Search: ClickHouse  点击:(297)  评论:(0)  加入收藏
揭秘字节跳动解决ClickHouse复杂查询问题的技术方案
导读:ClickHouse已经成为行业主流且热门的开源引擎。随着业务数据量扩大,场景覆盖变广泛,在复杂query场景下,ClickHouse容易存在查询异常问题,影响业务正常推进。本次主要分享字...【详细内容】
2022-09-05  Search: ClickHouse  点击:(416)  评论:(0)  加入收藏
记一次 ClickHouse 性能测试
前言在工作场景中,我们会采集工厂设备数据用于智能控制,数据的存储用了 InfluxDB,随着数据规模越来越大,InfluxDB 的性能越来越差,故考虑引入 ClickHouse 分担 InfluxDB 大数据分...【详细内容】
2022-08-15  Search: ClickHouse  点击:(359)  评论:(0)  加入收藏
使用IDEA连接ClickHouse OLAP数据库
ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。来自于2011 年在纳斯达克上市的俄罗斯本土搜索引擎企业Yandex公司,诞生之初就是为了服务Yandex公司自家的W...【详细内容】
2022-01-18  Search: ClickHouse  点击:(2291)  评论:(0)  加入收藏
mybatis-plus整合clickhouse
公司使用mybatis-plus版本为3.0.7.1,mybatis-plus3.4.2对clickhouse是支持的,无奈怕升级影响大,只能在现有基础上调整mybatis-plus代码了。 mybatis 在项目中将mybatis-plus源...【详细内容】
2021-05-27  Search: ClickHouse  点击:(5081)  评论:(0)  加入收藏
▌简易百科推荐
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(2)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(6)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
站内最新
站内热门
站内头条