概述
Clickhouse引擎二: MergeTree 家族引擎
MergeTree 系列的表引擎是 ClickHouse 数据存储功能的核心。它们提供了用于弹性和高性能数据
检索的大多数功能:列存储,自定义分区,稀疏的主索引,辅助数据跳过索引等。 基本 MergeTree 表引擎可以被认为是单节点 ClickHouse 实例的默认表引擎,因为它在各种用例中通用 且实用。
除了基础表引擎 MergeTree 之 外,常用的表引擎还有 ReplacingMergeTree、SummingMergeTree、
AggregatingMergeTree、CollapsingMergeTree 和 VersionedCollapsingMergeTree。每一种合并树的 变种,在继承了基 础 MergeTree 的能力之后,又增加了独有的特性。其名称中的“合并” 二字奠定 了所有类型 MergeTree 的基因,它们的所有特殊逻辑,都是在 触发合并的过程中被激活的。
对于生产用途,ReplicatedMergeTree 是必经之路,因为它为常规 MergeTree 引擎的所有功能增加了高
可用性。一个额外的好处是在数据提取时自动进行重复数据删除,因此如果插入过程中出现网络问题, 该软件可以安全地重试。
该 MergeTree 系列(*MergeTree)的引擎和其他引擎是最强大的 ClickHouse 表引擎。 该 MergeTree
系列中的引擎旨在将大量数据插入表中。数据快速地逐个部分地写入表中,然后应用规 则在后台合并这些部分。这种方法比插入期间连续重写存储中的数据效率更高。
主要特点:
存储按主键排序的数据。 这使您可以创建一个小的稀疏索引,以帮助更快地查找数据。
如果指定了分区键,则可以使用分区。ClickHouse 支持的某些分区操作比对相同数据,相同结果的常规操作更有效。ClickHouse 还会自动切 断在查询中指定了分区键的分区数据。这也提高了查询性能。
数据复制支持。 ReplicatedMergeTree 表族提供数据复制。有关更多信息.
数据采样支持。 如有必要,可以在表中设置数据采样方法。
Merge Tree 引擎
MergeTree 在写入一批数据时,数据总会以数据片段的形式写入磁 盘,且数据片段不可修改。为了避
免片段过多,ClickHouse 会通过后 台线程,定期合并这些数据片段,属于相同分区的数据片段会被合 成 一个新的片段。这种数据片段往复合并的特点,也正是合并树名称的由来。
MergeTree 表引擎除了常规参数之外,还拥有一些独有的配置选 项。接下来会着重介绍其中几个
重要的参数,包括它们的使用方法和工作原理。
(1)PARTITION BY [选填]:分区键,用于指定表数据以何种标 准进行分区。分区键既可以是单个列
字段,也可以通过元组的形式使 用多个列字段,同时它也支持使用列表达式。如果不声明分区键,则ClickHouse 会生成一个名为 all 的分区。合理使用数据分区,可以有效 减少查询时数据文件的扫描范 围,更多关于数据分区的细节会在 6.2 节 介绍。
(2)ORDER BY [必填]:排序键,用于指定在一个数据片段内, 数据以何种标准排序。默认情况下主
键(PRIMARY KEY)与排序键相 同。排序键既可以是单个列字段,例如 ORDER BY CounterID,也可以 通 过元组的形式使用多个列字段,例如 ORDER BY(CounterID,EventDate)。当使用多个列字段排序时, 以 ORDER BY(CounterID,EventDate)为例,在单个数据片段内,数据首先会以 CounterID 排序,相 同 CounterID 的数据再按 EventDate 排序。
(3)PRIMARY KEY [选填]:主键,顾名思义,声明后会依照主键 字段生成一级索引,用于加速表查
询。默认情况下,主键与排序键 (ORDER BY)相同,所以通常直接使用 ORDER BY 代为指定主键,无须 刻 意通过 PRIMARY KEY 声明。所以在一般情况下,在单个数据片段内,数 据与一级索引以相同的规 则升序排列。与其他数据库不同,MergeTree 主键允许存在重复数据(ReplacingMergeTree 可以去重)。
(4)SAMPLE BY [选填]:抽样表达式,用于声明数据以何种标准 进行采样。如果使用了此配置项,
那么在主键的配置中也需要声明同 样的表达式。
(5)SETTINGS:index_granularity [选填]: index_granularity 对于 MergeTree 而言是一项非常重
要的参数,它表 示索引的粒度,默认值为 8192。也就是说,MergeTree 的索引在默认情 况下,每间 隔 8192 行数据才生成一条索引。8192 是一个神奇的数字,在 ClickHouse 中大量数值参数都有它的 影子,可以被其整除(例如最小压 缩块大小 min_compress_block_size:65536)。通常情况下并不需要修改此参 数,但理解它的工作原 理有助于我们更好地使用 MergeTree。关于索引 详细的工作原理会在后续阐述。
(6)SETTINGS:index_granularity_bytes [选填]:在 19.11 版本之前,ClickHouse 只支持固定大小
的索引间隔,由 index_granularity 控制,默认为 8192。在新版本中,它增加了自适应 间隔大小的 特性,即根据每一批次写入数据的体量大小,动态划分间 隔大小。而数据的体量大小,正是由 index_granularity_bytes 参数控 制的,默认为 10M(10×1024×1024),设置为 0 表示不启动自适应 功 能。
ReplacingMergeTree
这个引擎是在 MergeTree 的基础上,添加了“处理重复数据”的功能,该引擎和 MergeTree 的不
同之处在于它会删除具有相同主键的重复项。数据的去重只会在合并的过程中出现。合并会在未知的 时间在后台进行,所以你无法预先作出计划。有一些数据可能仍未被处理。因此,ReplacingMergeTree 适用于在后台清除重复的数据以节省空间,但是它不保证没有重复的数据出现。 ENGINE = ReplacingMergeTree(ver)
CollapsingMergeTree
假设现在需要设计一款数据库,该数据库支持对已经存在的数据实 现行级粒度的修改或删除,你会怎
么设计?一种最符合常理的思维可能 是:首先找到保存数据的文件,接着修改这个文件,删除或者修 改那些 需要变化的数据行。然而在大数据领域,对于 ClickHouse 这类高性能分 析型数据库而言,对 数据源文件修改是一件非常奢侈且代价高昂的操 作。相较于直接修改源文件,它们会将修改和删除操 作转换成新增操 作,即以增代删。
CollapsingMergeTree 就是一种通过以增代删的思路,支持行级数 据修改和删除的表引擎。它通过定 义一个
sign 标记位字段,记录数据行 的状态。如果 sign 标记为 1,则表示这是一行有效的数据;如 果 sign 标 记为-1,则表示这行数据需要被删除。当 CollapsingMergeTree 分区合 并时,同一数据分 区内,sign 标记为 1 和-1 的一组数据会被抵消删除。 这种 1 和-1 相互抵消的操作,犹如将一张瓦楞 纸折叠了一般。
VersionedCollapsingMergeTree
取消字段和数据版本同事使用,避免取消行数据无法删除的问题 为了解决 CollapsingMergeTree
乱序写入情况下无法正常折叠问题,VersionedCollapsingMergeTree 表引 擎在建表语句中新增了一列 Version,用于在乱序情况下记录状态行与取消行的对应关系。
主键相同, 且 Version 相同、Sign 相反的行,在 Compaction 时会被删除。 与 CollapsingMergeTree
类似, 为了获得正确结果,业务层需要改写 SQL,将 count()、sum(col)分别改 写为 sum(Sign)、sum(col * Sign)。
SummingMergeTree
假设有这样一种查询需求:终端用户只需要查询数据的汇总结 果,不关心明细数据,并且数据的汇总
条件是预先明确的(GROUP BY 条件明确,且不会随意改变)。 对于这样的查询场景,在 ClickHouse 中如何解决呢?最直接的方 案就是使用 MergeTree 存储数据,然 后通过 GROUP BY 聚合查询,并利用 SUM 聚合函数汇总结果。
这种方案存在两个问题:
1 存在额外的存储开销:终端用户不会查询任何明细数据,只关心汇总结果,所以不应该一直保
存所有的明细数据。
2 存在额外的查询开销:终端用户只关心汇总结果,虽然 MergeTree 性能强大,但是每次查询都 进行实时聚合计算也是一种性能消耗。
SummingMergeTree 就是为了应对这类查询场景而生的。顾名思义,它能够在合并分区的时候按照预先
定义的条件聚合汇总数据,将同一分组下的多行数据汇总合并成一行,这样既减少了数据行,又降低 了后续汇总查询的开销。
在先前介绍 MergeTree 原理时曾提及,在 MergeTree 的每个数据分区内,数据会按照 ORDER BY 表达
式排序。主键索引也会按照 PRIMARY KEY 表达式取值并排序。而 ORDER BY 可以指代主键,所以在 一般情形下,只单独声明 ORDER BY 即可。此时,ORDER BY 与 PRIMARY KEY 定义相 同,数据排 序与主键索引相同。
如果需要同时定义 ORDER BY 与 PRIMARY KEY,通常只有一种可能,那便是明确希望 ORDER BY 与
PRIMARY KEY 不同。这种情况通常只会在使用 SummingMergeTree 或 AggregatingMergeTree 时才 会出现。这是为何呢?这是因为 SummingMergeTree 与 AggregatingMergeTree 的聚合都是根据 ORDER BY 进行的。由此可以引出两点原因:主键与聚合的条件定义分离,为修改聚合条件留下空间。
AggregatingMergeTree
“数据立方体”,这是一个 在数据仓库领域十分常见的模型。 它通过以空间换时间的方法提升查询性能,
将需要聚合的数据预先计算出来,并将结果保存起来。在 后续进行聚合查询的时候,直接使用结果数据。
AggregatingMergeTree 就有些许数据立方体的意思,它能够在合并分区的时候,按照预先定义的条件聚
合数据。同时,根据预先定义的聚合函数计算数据并通过二进制的格式存入表内。将同一分组下的多 行数据聚合成一行,既减少了数据行,又降低了后续聚合查询的开销。可以说,AggregatingMergeTree 是 SummingMergeTree 的升级版,它们的许多设计思路是一致的,例如同时定义 ORDER BY 与 PRIMARY KEY 的原因和目的。但是在使用方法上,两者存在明显差异,应该说 AggregatingMergeTree 的定义方式是 MergeTree 家族中最为特殊的一个。
最后
以上就是无聊早晨为你收集整理的Clickhouse引擎二: MergeTree 家族引擎Merge Tree 引擎ReplacingMergeTreeCollapsingMergeTreeVersionedCollapsingMergeTreeSummingMergeTreeAggregatingMergeTree的全部内容,希望文章能够帮你解决Clickhouse引擎二: MergeTree 家族引擎Merge Tree 引擎ReplacingMergeTreeCollapsingMergeTreeVersionedCollapsingMergeTreeSummingMergeTreeAggregatingMergeTree所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复