上周组内技术分享我选择了ClickHouse这个主题,对我来说,是个纯新的技术,从零开始,无论是原理理解上,还是环境搭建,碰到了很多问题,顶多是踉踉跄跄踏入了ClickHouse,
ClickHouse,作为一款开放源代码,可用SQL进行实时查询的列式分析型数据库(OLAP)系统,号称比传统的数据库管理系统快100到1000倍,每秒处理数亿到10亿行和几十千兆字节的数据。
其实这种说法,还得看具体场景,提升应该主要体现在OLAP的场景,如下图所示,这是行式数据库的读取模拟,
这是列式数据库的读取模拟,
针对分析类查询,通常只需要读取表的一小部分列。从上图,可以很直观看到,在行式数据库中,数据在数据块中按照行存储的,因此即使只需要几列,都得读取整行。在列式数据库中可以只读取需要的数据,举个例子,只读取100列中的5列,这将最少减少20倍的I/O消耗。而且,由于数据是打包成批量读取的,所以压缩是非常容易的,数据按列分别存储更容易压缩,这进一步降低了I/O的体积,由于I/O的降低,这将让更多的数据被系统缓存,一步快,步步快。
我们说说ClickHouse的历程,2009年,有“俄罗斯谷歌”之称的互联网公司Yandex为了解决实时海量数据下,高效快速进行网络流量分析的问题而建立了一个叫Metrica的项目,其中产生了一个具有独特技术的数据库,该数据库无需提前聚合数据,就可以创建关于一系列实时分析指标报告。之后Metrica演变成了ClickHouse,即英语“Clickstream Data Warehouse ”的缩写,翻译过来就是点击流的数据仓库,
2019年,Yandex的搜索排名是第5,
2016年6月15日,为了用开源方式继续发展ClickHouse,Yandex选择了开源,随着社区贡献者的不断增加以及企业用户的参与,让社区的影响力逐渐提升。
GitHub的ClickHouse已经有2万多颗Star,Fork了将近4千次,
P.S. https://github.com/ClickHouse/ClickHouse
DB-Engines的排名是45,
ClickHouse的代码主要采用C ,还有少量的Python、Shell和js,追求性能的应用,还是倾向这种偏底层的语言,这可能是其他语言不具备的优势,
开源数据库ClickHouse社区在 2021年8月注册成立了商业化公司,紧接着不到2个月的时间内,以惊人的速度完成了A轮5千万和B轮2.5亿美金的巨额融资,让ClickHouse一夜之间成为全球开源圈的新贵。
最近越来越多的这种OLAP或者HTAP的数据库得到投资者的青睐,例如巴菲特参投的SnowFlake、MySQL推出的HeatWave,说明对数据的价值得到了进一步的重视。
ClickHouse目前的用户,遍布全球,而且有很多来自国内的厂商,说明我们参与开源产品的场景越来越多,在开源领域的话语权越来越重,
https://clickhouse.com/docs/zh/introduction/adopters/
ClickHouse的官网,https://clickhouse.com/#quick-start,有很多实用资料,从介绍来看,最新的是21.11版本,
最新的这个21.11支持异步插入,进一步提升数据插入和存储的性能,
这个链接,https://clickhouse.com/benchmark/dbms/,可以比对ClickHouse和其他一些在线分析型数据库的性能,
(1) Compare可以选择比对的数据库。
(2) Dataset size可以选择测试的数据集,1000万、1亿、10亿。
(3) Run可以选择第一次执行(cold cache,应该是指未经过缓存的)、第二次执行、第三次执行。
显示不同的SQL在这两个数据库中的执行速度,以及倍数,
从执行的链接,可以看到,应该就是执行了一个GET请求,
这篇文章,则比对了ClickHouse和内置了列式存储的MariaDB 10.5的性能对比,MariaDB 10.5内置的列式存储,可以在同一个实例中,将数据从InnoDB实时复制到列式存储中,这就是所谓的"hybrid transactional and analytical processing",混合式交易分析处理,
https://www.percona.com/blog/2020/07/27/clickhouse-and-columnstore-in-the-star-schema-benchmark/
ClickHouse的文档,非常丰富,而且支持中文,一方面可能是由于国内厂商的参与度很高,另一方面可能来自于中俄的战略伙伴关系,好邻居,
https://clickhouse.com/docs/en/
https://clickhouse.com/docs/zh/
ClickHouse的特性,我们参考文档,
https://clickhouse.com/docs/zh/introduction/distinctive-features/
(1) 真正的列式数据库管理系统
在一个真正的列式数据库管理系统中,除了数据本身外不应该存在其他额外的数据。这意味着为了避免在值旁边存储他们的长度«number»,你必须支持固定长度数值类型。例如,10亿个UInt8类型的数据在未压缩的情况下大约消耗1GB左右的空间,如果不是这样的话,这将对CPU的使用产生强烈影响。即使是在未压缩的情况下,紧凑的存储数据也是非常重要的,因为解压缩的速度主要取决于未压缩数据的大小。
这是非常值得注意的,因为在一些其他系统中也可以将不同的列分别进行存储,但由于对其他场景进行的优化,使其无法有效的处理分析查询。例如:HBase,BigTable,Cassandra,HyperTable。在这些系统中,你可以得到每秒数十万的吞吐能力,但是无法得到每秒几亿行的吞吐能力。
需要说明的是,ClickHouse不单单是一个数据库, 他是一个数据库管理系统。因为他允许在运行时创建表和数据库、加载数据和运行查询,而无需重新配置或重启服务。
(2) 数据压缩
在一些列式数据库管理系统中(例如:InfiniDB CE 和 MonetDB) 并没有使用数据压缩。但是, 若想达到比较优异的性能,数据压缩确实起到了至关重要的作用。
除了在磁盘空间和CPU消耗之间进行不同权衡的高效通用压缩编解码器之外,ClickHouse还提供针对特定类型数据的专用编解码器,这使得ClickHouse能够与更小的数据库(如时间序列数据库)竞争并超越他们。
(3) 数据的磁盘存储
许多的列式数据库(如 SAP HANA, Google PowerDrill)只能在内存中工作,这种方式会造成比实际更多的设备预算。
ClickHouse被设计用于工作在传统磁盘上的系统,他提供每GB更低的存储成本,但如果可以使用SSD和内存,他也会合理的利用这些资源。
(4) 多核心并行处理
ClickHouse会使用服务器上一切可用的资源,从而以最自然的方式并行处理大型查询。
(5) 多服务器分布式处理
上面提到的列式数据库管理系统中,几乎没有一个支持分布式的查询处理。 在ClickHouse中,数据可以保存在不同的shard上,每一个shard都由一组用于容错的replica组成,查询可以并行地在所有shard上进行处理。这些对用户来说是透明的
(6) 支持SQL
ClickHouse支持一种基于SQL的声明式查询语言,他在许多情况下与ANSI SQL标准相同。
支持的查询GROUP BY, ORDER BY, FROM, JOIN, IN以及非相关子查询。
相关(依赖性)子查询和窗口函数暂不受支持,但将来会被实现。
(7) 向量引擎
为了高效的使用CPU,数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,这样可以更加高效地使用CPU。
(8) 实时的数据更新
ClickHouse支持在表中定义主键。为了使查询能够快速在主键中进行范围查找,数据总是以增量的方式有序的存储在MergeTree中。因此,数据可以持续不断地高效的写入到表中,并且写入的过程中不会存在任何加锁的行为。
(9) 索引
按照主键对数据进行排序,这将帮助ClickHouse在几十毫秒以内完成对数据特定值或范围的查找。
(10) 适合在线查询
在线查询意味着在没有对数据做任何预处理的情况下以极低的延迟处理查询并将结果加载到用户的页面中。
(11) 支持近似计算
ClickHouse提供各种各样在允许牺牲数据精度的情况下对查询进行加速的方法:
1. 用于近似计算的各类聚合函数,如:distinct values, medians, quantiles
2. 基于数据的部分样本进行近似查询。这时,仅会从磁盘检索少部分比例的数据。
3. 不使用全部的聚合条件,通过随机选择有限个数据聚合条件进行聚合。这在数据聚合条件满足某些分布条件下,在提供相当准确的聚合结果的同时降低了计算资源的使用。
(12) Adaptive Join Algorithm
ClickHouse支持自定义JOIN多个表,他更倾向于散列连接算法,如果有多个大表,则使用合并-连接算法。
(13) 支持数据复制和数据完整性
ClickHouse使用异步的多主复制技术。当数据被写入任何一个可用副本后,系统会在后台将数据分发给其他副本,以保证系统在不同副本上保持相同的数据。在大多数情况下ClickHouse能在故障后自动恢复,在一些少数的复杂情况下需要手动恢复。
更多信息,参见数据复制。
(14) 角色的访问控制
ClickHouse使用SQL查询实现用户帐户管理,并允许角色的访问控制,类似于ANSI SQL标准和流行的关系数据库管理系统。
ClickHouse的限制同样明显,
(1) 没有完整的事务支持。
(2) 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合GDPR。
(3) 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。
有朋友问ClickHouse的性能,官方文档给出一些说明,
https://clickhouse.com/docs/zh/introduction/performance/
(1) 单个大查询的吞吐量
吞吐量可以使用每秒处理的行数或每秒处理的字节数来衡量。如果数据被放置在page cache中,则一个不太复杂的查询在单个服务器上大约能够以2-10GB/s(未压缩)的速度进行处理(对于简单的查询,速度可以达到30GB/s)。如果数据没有在page cache中的话,那么速度将取决于你的磁盘系统和数据的压缩率。例如,如果一个磁盘允许以400MB/s的速度读取数据,并且数据压缩率是3,则数据的处理速度为1.2GB/s。这意味着,如果你是在提取一个10字节的列,那么他的处理速度大约是1-2亿行每秒。
对于分布式处理,处理速度几乎是线性扩展的,但这受限于聚合或排序的结果不是那么大的情况下。
(2) 处理短查询的延迟时间
如果一个查询使用主键并且没有太多行(几十万)进行处理,并且没有查询太多的列,那么在数据被page cache缓存的情况下,他的延迟应该小于50毫秒(在最佳的情况下应该小于10毫秒)。否则,延迟取决于数据的查找次数。如果你当前使用的是HDD,在数据没有加载的情况下,查询所需要的延迟可以通过以下公式计算得知:查找时间(10 ms) * 查询的列的数量 * 查询的数据块的数量。
(3) 处理大量短查询的吞吐量
在相同的情况下,ClickHouse可以在单个服务器上每秒处理数百个查询(在最佳的情况下最多可以处理数千个)。但是由于这不适用于分析型场景。因此我们建议每秒最多查询100次。
(4) 数据的写入性能
我们建议每次写入不少于1000行的批量写入,或每秒不超过一个写入请求。当使用tab-separated格式将一份数据写入到MergeTree表中时,写入速度大约为50到200MB/s。如果您写入的数据每行为1Kb,那么写入的速度为50,000到200,000行每秒。如果您的行更小,那么写入速度将更高。为了提高写入性能,您可以使用多个INSERT进行并行写入,这将带来线性的性能提升。
ClickHouse作为一款开源产品来讲,得到风投认可,已经说明了一定的价值,从官网、官方文档,可以看出他对开发者的友好,基本上通过自学,就可以了解很多关于ClickHouse的知识,这点确实是我们做产品时值得借鉴的,