ClickHouse 为何如此快?


ClickHouse 为何如此快?

文章插图
ClickHouse 具有 ROLAP、在线实时查询、完整的 DBMS、列式存储、不需要任何数据预处理、支持批量更新、拥有非常完善的 SQL 支持和函数、支持高可用、不依赖 Hadoop 复杂生态、开箱即用等许多特点 。特别是它那夸张的查询性能,我想大多数刚接触 ClickHouse 的人也一定会因为它的性能指标而动容 。在一系列官方公布的基准测试对比中,ClickHouse 都遥遥领先对手,这其中不乏一些我们耳熟能详的名字 。
所有用于对比的数据库都使用了相同配置的服务器,在单个节点的情况下,对一张拥有133个字段的数据表分别在1000万、1亿和10亿三种数据体量下执行基准测试,基准测试的范围涵盖43项SQL查询 。在1亿数据集体量的情况下,ClickHouse的平均响应速度是 Vertica 的2.63倍、InfiniDB的17倍、MonetDB 的27倍、Hive 的126倍、MySQL 的429倍以及 Greenplum 的10倍 。详细的测试结果可以查阅https://clickhouse.yandex/benchmark.html 。
很多用户心中一直会有这样的疑问,为什么 ClickHouse 这么快?因为ClickHouse 是列式存储数据库,所以快;也因为 ClickHouse 使用了向量化引擎,所以快 。这些解释都站得住脚,但是依然不能消除全部的疑问 。因为这些技术并不是秘密,世面上有很多数据库同样使用了这些技术,但是依然没有ClickHouse这么快 。所以我想从另外一个角度来探讨一番ClickHouse的秘诀到底是什么 。
首先向各位读者抛出一个疑问:在设计软件架构的时候,做设计的原则应该是自顶向下地去设计,还是应该自下而上地去设计呢?在传统观念中,或者说在我的观念中,自然是自顶向下的设计,通常我们都被教导要做好顶层设计 。而ClickHouse 的设计则采用了自下而上的方式 。ClickHouse 的原型系统早在2008年就诞生了,在诞生之初它并没有宏伟的规划 。相反它的目的很单纯,就是希望能以最快的速度进行 GROUP BY 查询和过滤 。他们是如何实践自下而上设计的呢?
ClickHouse 为何如此快?

文章插图
着眼硬件,先想后做
首先从硬件功能层面着手设计,在设计伊始就至少需要想清楚如下几个问题 。
  • 我们将要使用的硬件水平是怎样的?包括CPU、内存、硬盘、网络等 。
  • 在这样的硬件上,我们需要达到怎样的性能?包括延迟、吞吐量等 。
  • 我们准备使用怎样的数据结构?包括 String、HashTable、Vector 等 。
  • 选择的这些数据结构,在我们的硬件上会如何工作?
如果能想清楚上面这些问题,那么在动手实现功能之前,就已经能够计算出粗略的性能了 。所以,基于将硬件功效最大化的目的,ClickHouse 会在内存中进行GROUP BY,并且使用 HashTable 装载数据 。与此同时,他们非常在意 CPU L3级别的缓存,因为一次L3的缓存失效会带来70~100ns的延迟 。这意味着在单核 CPU 上,它会浪费4000万次/秒的运算;而在一个32线程的 CPU 上,则可能会浪费5亿次/秒的运算 。所以别小看这些细节,一点一滴地将它们累加起来,数据是非常可观的 。正因为注意了这些细节,所以 ClickHouse 在基准查询中能做到1.75亿次/秒的数据扫描性能 。
ClickHouse 为何如此快?

文章插图
算法在前,抽象在后
常有人念叨:“有时候,选择比努力更重要 。”确实,路线选错了再努力也是白搭 。在 ClickHouse 的底层实现中,经常会面对一些重复的场景,例如字符串子串查询、数组排序、使用 HashTable 等 。如何才能实现性能的最大化呢?算法的选择是重中之重 。以字符串为例,有一本专门讲解字符串搜索的书,名为“Handbook of Exact String Matching Algorithms”,列举了35种常见的字符串搜索算法 。各位猜一猜 ClickHouse 使用了其中的哪一种?答案是一种都没有 。这是为什么呢?因为性能不够快 。在字符串搜索方面,针对不同的场景,ClickHouse 最终选择了这些算法:对于常量,使用 Volnitsky 算法;对于非常量,使用 CPU 的向量化执行 SIMD,暴力优化;正则匹配使用 re2 和hyperscan 算法 。性能是算法选择的首要考量指标 。
ClickHouse 为何如此快?

文章插图
勇于尝鲜,不行就换
除了字符串之外,其余的场景也与它类似,ClickHouse 会使用最合适、最快的算法 。如果世面上出现了号称性能强大的新算法,ClickHouse 团队会立即将其纳入并进行验证 。如果效果不错,就保留使用;如果性能不尽人意,就将其抛弃 。


推荐阅读