当前位置: 首页 >> ClickHouse >> MergeTree引擎

MergeTree引擎

2020-10-07 15:17:58 星期三  阅读:6576


表引擎是ClickHouse设计实现中的一大特色。表引擎决定了一张数据表最终的“性格”,比如数据表拥有何种特性、数据以何种形式被存储以及如何被加载。
截止现在,其共拥有合并树、外部存储、内存、文件、接口和其他6大类20多种表引擎。

MergeTree在写入一批数据时,数据总会以数据片段的形式写入磁盘,且数据片段不可修改。为了避免片段过多,ClickHouse会通过后台线程,定期合并这些数据片段,属于相同分区的数据片段会被合成一个新的片段。这种数据片段往复合并的特点,也正是合并树名称的由来。

数据写入过程

数据写入的第一步是生成分区目录,伴随着每一批数据的写入,都会生成一个新的分区目录。在后续的某一时刻,属于相同分区的目录会依照规则合并到一起;接着,按照index_granularity索引粒度,会分别生成primary.idx一级索引(如果声明了二级索引,还会创建二级索引文件)、每一个列字段的.mrk数据标记和.bin压缩数据文件。

示例:从分区目录201403_1_34_3能够得知,该分区数据共分34批写入,期间发生过3次合并。

数据读出过程

数据查询的本质,可以看作一个不断减小数据范围的过程。在最理想的情况下,MergeTree首先可以依次借助分区索引、一级索引和二级索引,将数据扫描范围缩至最小。然后再借助数据标记,将需要解压与计算的数据范围缩至最小。

MergeTree的创建方式

跟一般表的创建方式相同,只是需要将engine参数声明为MergeTree()

  1. CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (
  2. name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
  3. name2 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
  4. 省略...
  5. ) ENGINE = MergeTree()
  6. [PARTITION BY expr]
  7. [ORDER BY expr]
  8. [PRIMARY KEY expr]
  9. [SAMPLE BY expr]
  10. [SETTINGS name=value, 省略...]

数据存储

各列独立存储:每个列都有一个与之对应的.bin的数据文件。数据是经过压缩的。目前支持lz4/zstd/multiple/delta等几种算法。
一个.bin文件是由1至多个压缩数据块组成的,每个压缩块大小在64KB~1MB之间。多个压缩数据块之间,按照写入顺序首尾相接,紧密地排列在一起。

数据标记

在查询某一列数据时,MergeTree无须一次性加载整个.bin文件,而是可以根据需要,只加载特定的压缩数据块。而这项特性需要借助标记文件中所保存的压缩文件中的偏移量。
在读取解压后的数据时,MergeTree并不需要一次性扫描整段解压数据,它可以根据需要,以index_granularity的粒度加载特定的一小段。为了实现这项特性,需要借助标记文件中保存的解压数据块中的偏移量。

数据TTL

TTL即Time To Live,顾名思义,它表示数据的存活时间。在MergeTree中,可以为某个列字段或整张表设置TTL。当时间到达时,如果是列字段级别的TTL,则会删除这一列的数据;如果是表级别的TTL,则会删除整张表的数据;如果同时设置了列级别和表级别的TTL,则会以先到期的那个为主。
无论是列级别还是表级别的TTL,都需要依托某个DateTime或Date类型的字段。

列级别的TTL
  1. CREATE TABLE ttl_table_v1(
  2. id String,
  3. create_time DateTime,
  4. code String TTL create_time + INTERVAL 10 SECOND,
  5. type UInt8 TTL create_time + INTERVAL 10 SECOND
  6. )
  7. ENGINE = MergeTree
  8. PARTITION BY toYYYYMM(create_time)
  9. ORDER BY id

create_time是日期类型,列字段code与type均被设置了TTL,它们的存活时间是在create_time的取值基础之上向后延续10秒。

表级别TTL
  1. CREATE TABLE ttl_table_v2(
  2. id String,
  3. create_time DateTime,
  4. code String TTL create_time + INTERVAL 1 MINUTE,
  5. type UInt8
  6. )ENGINE = MergeTree
  7. PARTITION BY toYYYYMM(create_time)
  8. ORDER BY create_time
  9. TTL create_time + INTERVAL 1 DAY

多路径存储策略

MergeTree实现了自定义存储策略的功能,支持以数据分区为最小移动单元,将分区目录写入多块磁盘目录
目前有三种策略

  • 1.默认策略
    2.JBOD策略:每执行一次INSERT或者MERGE,所产生的新分区会轮询写入各个磁盘
    3.HOT/COLD策略:这种策略适合服务器挂载了不同类型磁盘的场景。将存储磁盘分为HOT与COLD两类区域。HOT区域使用SSD这类高性能存储媒介,注重存取性能;COLD区域则使用HDD这类高容量存储媒介,注重存取经济性。

存储配置需要预先定义在config.xml配置文件中,由storage_configuration标签表示。

MergeTree系列表引擎

MergeTree有两层含义:

其一,表示合并树表引擎家族;
其二,表示合并树家族中最基础的MergeTree表引擎。

而在整个家族中,除了基础表引擎MergeTree之外,常用的表引擎还有

  1. ReplacingMergeTree
  2. SummingMergeTree
  3. AggregatingMergeTree
  4. CollapsingMergeTree
  5. VersionedCollapsingMergeTree

每一种合并树的变种,在继承了基础MergeTree的能力之后,又增加了独有的特性。其名称中的“合并”二字奠定了所有类型MergeTree的基因,它们的所有特殊逻辑,都是在触发合并的过程中被激活的。