文章作者:朱凯
编辑整理:Hoh 转自 | Datafuntalk
内容来源:《ClickHouse原理解析与应用实践》
导读:随着业务的迅猛增长,Yandex.Metrica目前已经成为世界第三大Web流量分析平台,每天处理超过200亿个跟踪事件。能够拥有如此惊人的体量,在它背后提供支撑的ClickHouse功不可没。ClickHouse已经为Yandex.Metrica存储了超过20万亿行的数据,90%的自定义查询能够在1秒内返回,其集群规模也超过了400台服务器。虽然ClickHouse起初只是为了Yandex.Metrica而研发的,但由于它出众的性能,目前也被广泛应用于Yandex内部其他数十个产品上。
初识ClickHouse的时候,我曾产生这样的感觉:它仿佛违背了物理定律,没有任何缺点,是一个不真实的存在。一款高性能、高可用OLAP数据库的一切诉求,ClickHouse似乎都能满足,这股神秘的气息引起了我极大的好奇。但是刚从Hadoop生态转向ClickHouse的时候,我曾有诸多的不适应,因为它和我们往常使用的技术"性格"迥然不同。如果把数据库比作汽车,那么ClickHouse俨然就是一辆手动挡的赛车。它在很多方面不像其他系统那样高度自动化。ClickHouse的一些概念也与我们通常的理解有所不同,特别是在分片和副本方面,有些时候数据的分片甚至需要手动完成。在进一步深入使用ClickHouse之后,我渐渐地理解了这些设计的目的。某些看似不够自动化的设计,反过来却在使用中带来了极大的灵活性。与Hadoop生态的其他数据库相比,ClickHouse更像一款"传统"MPP架构的数据库,它没有采用Hadoop生态中常用的主从架构,而是使用了多主对等网络结构,同时它也是基于关系模型的ROLAP方案。本文就让我们抽丝剥茧,看看ClickHouse都有哪些核心特性。
ClickHouse是一款MPP架构的列式存储数据库,但MPP和列式存储并不是什么"稀罕"的设计。拥有类似架构的其他数据库产品也有很多,但是为什么偏偏只有ClickHouse的性能如此出众呢?通过上一章的介绍,我们知道了ClickHouse发展至今的演进过程。它一共经历了四个阶段,每一次阶段演进,相比之前都进一步取其精华去其糟粕。可以说ClickHouse汲取了各家技术的精髓,将每一个细节都做到了极致。接下来将介绍ClickHouse的一些核心特性,正是这些特性形成的合力使得ClickHouse如此优秀。
1. 完备的DBMS功能
ClickHouse拥有完备的管理功能,所以它称得上是一个DBMS ( Database Management System,数据库管理系统 ),而不仅是一个数据库。作为一个DBMS,它具备了一些基本功能,如下所示。
DDL ( 数据定义语言 ):可以动态地创建、修改或删除数据库、表和视图,而无须重启服务。
DML ( 数据操作语言 ):可以动态查询、插入、修改或删除数据。
权限控制:可以按照用户粒度设置数据库或者表的操作权限,保障数据的安全性。
数据备份与恢复:提供了数据备份导出与导入恢复机制,满足生产环境的要求。
分布式管理:提供集群模式,能够自动管理多个数据库节点。
这里只列举了一些最具代表性的功能,但已然足以表明为什么Click House称得上是DBMS了。
2. 列式存储与数据压缩
列式存储和数据压缩,对于一款高性能数据库来说是必不可少的特性。一个非常流行的观点认为,如果你想让查询变得更快,最简单且有效的方法是减少数据扫描范围和数据传输时的大小,而列式存储和数据压缩就可以帮助我们实现上述两点。列式存储和数据压缩通常是伴生的,因为一般来说列式存储是数据压缩的前提。
按列存储与按行存储相比,前者可以有效减少查询时所需扫描的数据量,这一点可以用一个示例简单说明。假设一张数据表A拥有50个字段A1~A50,以及100行数据。现在需要查询前5个字段并进行数据分析,则可以用如下SQL实现:
SELECT A1,A2,A3,A4,A5 FROM A
如果数据按行存储,数据库首先会逐行扫描,并获取每行数据的所有50个字段,再从每一行数据中返回A1~A5这5个字段。不难发现,尽管只需要前面的5个字段,但由于数据是按行进行组织的,实际上还是扫描了所有的字段。如果数据按列存储,就不会发生这样的问题。由于数据按列组织,数据库可以直接获取A1~A5这5列的数据,从而避免了多余的数据扫描。
按列存储相比按行存储的另一个优势是对数据压缩的友好性。同样可以用一个示例简单说明压缩的本质是什么。假设有两个字符串abcdefghi和bcdefghi,现在对它们进行压缩,如下所示:
压缩前:abcdefghi_bcdefghi压缩后:abcdefghi_(9,8)
可以看到,压缩的本质是按照一定步长对数据进行匹配扫描,当发现重复部分的时候就进行编码转换。例如上述示例中的 (9,8),表示如果从下划线开始向前移动9个字节,会匹配到8个字节长度的重复项,即这里的bcdefghi。
真实的压缩算法自然比这个示例更为复杂,但压缩的实质就是如此。数据中的重复项越多,则压缩率越高;压缩率越高,则数据体量越小;而数据体量越小,则数据在网络中的传输越快,对网络带宽和磁盘IO的压力也就越小。既然如此,那怎样的数据最可能具备重复的特性呢?答案是属于同一个列字段的数据,因为它们拥有相同的数据类型和现实语义,重复项的可能性自然就更高。
ClickHouse就是一款使用列式存储的数据库,数据按列进行组织,属于同一列的数据会被保存在一起,列与列之间也会由不同的文件分别保存 ( 这里主要指MergeTree表引擎 )。数据默认使用LZ4算法压缩,在Yandex.Metrica的生产环境中,数据总体的压缩比可以达到8:1 ( 未压缩前17PB,压缩后2PB )。列式存储除了降低IO和存储的压力之外,还为向量化执行做好了铺垫。
3. 向量化执行引擎
坊间有句