乐趣区

关于机器学习:ClickHouse-存算分离架构探索

背景

ClickHouse 作为开源 OLAP 引擎,因其杰出的性能体现在大数据生态中失去了宽泛的利用。区别于 Hadoop 生态组件通常依赖 HDFS 作为底层的数据存储,ClickHouse 应用本地盘来本人治理数据,官网举荐应用 SSD 作为存储介质来晋升性能。但受限于本地盘的容量下限以及 SSD 盘的价格,用户很难在容量、老本和性能这三者之间找到一个好的均衡。JuiceFS 的某个客户近期就遇到了这样的难题,心愿将 ClickHouse 中的温冷数据从 SSD 盘迁徙到更大容量、更低成本的存储介质,更好地撑持业务查问更长时间数据的需要。

JuiceFS 是基于对象存储实现并齐全兼容 POSIX 的开源分布式文件系统,同时 JuiceFS 的数据缓存个性能够智能治理查问热点数据,非常适合作为 ClickHouse 的存储系统,上面将具体介绍这个计划。

MergeTree 存储格局简介

在介绍具体计划之前先简略理解一下 MergeTree 的存储格局。MergeTree 是 ClickHouse 最次要应用的存储引擎,当创立表时能够通过 PARTITION BY 语句指定以某一个或多个字段作为分区字段,数据在磁盘上的目录构造相似如下模式:

$ ls -l /var/lib/clickhouse/data/<database>/<table>
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202102_1_3_0
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202102_4_6_1
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202103_1_1_0
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202103_4_4_0

202102_1_3_0 为例,202102 是分区的名称,1 是最小的数据块编号,3 是最大的数据块编号,0 是 MergeTree 的深度。能够看到 202102 这个分区不止一个目录,这是因为 ClickHouse 每次在写入的时候都会生成一个新的目录,并且一旦写入当前就不会批改(immutable)。每一个目录称作一个「part」,当 part 逐步变多当前 ClickHouse 会在后盾对多个 part 进行合并(compaction),通常的倡议是不要保留过多 part,否则会影响查问性能。

每个 part 目录外部又由很多大大小小的文件组成,这外面既有数据,也有一些元信息,一个典型的目录构造如下所示:

$ ls -l /var/lib/clickhouse/data/<database>/<table>/202102_1_3_0
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnA.bin
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnA.mrk
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnB.bin
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnB.mrk
-rw-r--r--  1 test  test     ?? Mar  8 14:06 checksums.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 columns.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 count.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 minmax_ColumnC.idx
-rw-r--r--  1 test  test     ?? Mar  8 14:06 partition.dat
-rw-r--r--  1 test  test     ?? Mar  8 14:06 primary.idx

其中比拟重要的文件有:

primary.idx:这个文件蕴含的是主键信息,但不是以后 part 全副行的主键,默认会依照 8192 这个区间来存储,也就是每 8192 行存储一次主键。
ColumnA.bin:这是压缩当前的某一列的数据,ColumnA 只是这一列的代称,理论状况会是实在的列名。压缩是以 block 作为最小单位,每个 block 的大小从 64KiB 到 1MiB 不等。
ColumnA.mrk:这个文件保留的是对应的 ColumnA.bin 文件中每个 block 压缩后和压缩前的偏移。
partition.dat:这个文件蕴含的是通过分区表达式计算当前的分区 ID。
minmax_ColumnC.idx:这个文件蕴含的是分区字段对应的原始数据的最小值和最大值。

基于 JuiceFS 的存算拆散计划

因为 JuiceFS 齐全兼容 POSIX,所以能够把 JuiceFS 挂载的文件系统间接作为 ClickHouse 的磁盘来应用。这种计划下数据会间接写入 JuiceFS,联合为 ClickHouse 节点配置的缓存盘,查问时波及的热数据会主动缓存在 ClickHouse 节点本地。整体计划如下图所示。

ClickHouse 在写入时会产生大量的小文件,因而如果写入压力较大这个计划对写入和查问性能都会有肯定影响。倡议在写入数据时增大写入缓存,尽量一次写入更多数据来防止这个小文件过多的问题。最简略的做法是应用 ClickHouse 的 Buffer 表,基本上不须要批改利用代码就能够解决小文件过多的问题,适宜当 ClickHouse 宕机时容许大量数据失落的场景。这样做的益处是存储和计算齐全拆散,ClickHouse 节点齐全无状态,如果节点故障能够很快复原,不波及任何数据拷贝。将来能够让 ClickHouse 感知到底层存储是共享的,实现主动的无数据拷贝迁徙。

同时因为 ClickHouse 通常利用在实时剖析场景,这个场景对于数据实时更新的要求比拟高,在剖析时也须要经常性地查问新数据。因而数据具备比拟显著的冷热特色,即个别新数据是热数据,随着时间推移历史数据逐步变为冷数据。利用 ClickHouse 的存储策略(storage policy)来配置多块磁盘,通过肯定条件能够实现主动迁徙冷数据到 JuiceFS。整体计划如下图所示。

这个计划中数据会先写入本地磁盘,当满足肯定条件时 ClickHouse 的后盾线程会异步把数据从本地磁盘迁徙到 JuiceFS 上。和第一个计划一样,查问时也会主动缓存热数据。留神图中为了辨别写和读因而画了两块磁盘,理论应用中没有这个限度,能够应用同一个盘。尽管这个计划不是齐全的存储计算拆散,然而能够满足对写入性能要求特地高的场景需要,也保留肯定的存储资源弹性伸缩能力。上面会具体介绍这个计划在 ClickHouse 中如何配置。

ClickHouse 反对配置多块磁盘用于数据存储,上面是示例的配置文件:

<storage_configuration>
    <disks>
        <jfs>
            <path>/jfs</path>
        </jfs>
    </disks>
</storage_configuration>

下面的 /jfs 目录即是 JuiceFS 文件系统挂载的门路。在把以上配置增加到 ClickHouse 的配置文件中,并胜利挂载 JuiceFS 文件系统当前,就能够通过 MOVE PARTITION 命令将某个 partition 挪动到 JuiceFS 上,例如:

ALTER TABLE test MOVE PARTITION 'xxx' TO DISK 'jfs';

当然这种手动挪动的形式只是用于测试,ClickHouse 反对通过配置存储策略的形式来将数据主动从某个磁盘挪动到另一个磁盘。上面是示例的配置文件:

<storage_configuration>
    <disks>
        <jfs>
            <path>/jfs</path>
        </jfs>
    </disks>
    <policies>
        <hot_and_cold>
            <volumes>
                <hot>
                    <disk>default</disk>
                    <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                </hot>
                <cold>
                    <disk>jfs</disk>
                </cold>
            </volumes>
            <move_factor>0.1</move_factor>
        </hot_and_cold>
    </policies>
</storage_configuration>

下面的配置文件中有一个名为 hot_and_cold 的存储策略,其中定义了两个 volume,名为 hot 的 volume 是默认的 SSD 盘,名为 cold 的 volume 即是上一步 disks 中定义的 JuiceFS 盘。这些 volume 在配置文件中的程序很重要,数据会首先存储到第一个 volume 中,而 max_data_part_size_bytes 这个配置示意当数据 part 超过指定的大小时(示例中是 1GiB)主动从以后 volume 挪动到下一个 volume,也就是把数据从 SSD 盘挪动到 JuiceFS。最初的 move_factor 配置示意当 SSD 盘的磁盘容量超过 90% 时也会触发数据挪动到 JuiceFS。

最初在创立表时须要显式指定要用到的存储策略:

CREATE TABLE test (...) ENGINE = MergeTree
...
SETTINGS storage_policy = 'hot_and_cold';

当满足数据挪动的条件时,ClickHouse 就会启动后盾线程去执行挪动数据的操作,默认会有 8 个线程同时工作,这个线程数量能够通过 background_move_pool_size 配置调整。

除了配置存储策略以外,还能够在创立表时通过 TTL 将超过一段时间的数据挪动到 JuiceFS 上,例如:

CREATE TABLE test (
  d DateTime,
  ...
) ENGINE = MergeTree
...
TTL d + INTERVAL 1 DAY TO DISK 'jfs'
SETTINGS storage_policy = 'hot_and_cold';

下面的例子是将超过 1 天的数据挪动到 JuiceFS 上,联合存储策略一起能够非常灵活地治理数据的生命周期。

写入性能测试

采纳冷热数据拆散计划当前数据并不会间接写入 JuiceFS,而是先写入 SSD 盘,再通过后盾线程异步迁徙到 JuiceFS 上。然而咱们心愿间接评估不同存储介质在写数据的场景有多大的性能差别,因而这里在测试写入性能时没有配置冷热数据拆散的存储策略,而是让 ClickHouse 间接写入不同的存储介质。

具体测试方法是将实在业务中的某一张 ClickHouse 表作为数据源,而后应用 INSERT INTO 语句批量插入千万级行数的数据,比拟间接写入 SSD 盘、JuiceFS 以及对象存储的吞吐。最终的测试后果如下图:

以 SSD 盘作为基准,能够看到 JuiceFS 的写入性能与 SSD 盘有 30% 左右的性能差距,然而相比对象存储有 11 倍的性能晋升。 这里 JuiceFS 的测试中开启了 writeback 选项,这是因为 ClickHouse 在写入时每个 part 会产生大量的小文件(KiB 级),客户端采纳异步写入的形式能显著晋升性能,同时大量的小文件对于查问性能也会造成肯定影响。

在理解了间接写入不同介质的性能当前,接下来测试冷热数据拆散计划的写入性能。通过理论业务测试,基于 JuiceFS 的冷热数据拆散计划体现稳固,因为新数据都是间接写入 SSD 盘,因而写入性能与下面测试中的 SSD 盘性能相当。SSD 盘上的数据能够很快迁徙到 JuiceFS 上,在 JuiceFS 上对数据 part 进行合并也都是没有问题的。

查问性能测试

查问性能测试应用实在业务中的数据,并选取几个典型的查问场景进行测试。其中 q1-q4 是扫描全表的查问,q5-q7 是命中主键索引的查问。测试后果如下图:

能够看到 JuiceFS 与 SSD 盘的查问性能根本相当,均匀差别在 6% 左右,然而对象存储相比 SSD 盘有 1.4 至 30 倍的性能降落。 得益于 JuiceFS 高性能的元数据操作以及本地缓存个性,能够主动将查问申请须要的热数据缓存在 ClickHouse 节点本地,大幅晋升了 ClickHouse 的查问性能。须要留神的是以上测试中对象存储是通过 ClickHouse 的 S3 磁盘类型进行拜访,这种形式只有数据是存储在对象存储上,元数据还是在本地磁盘。如果通过相似 S3FS 的形式把对象存储挂载到本地,性能会有进一步的降落。

在实现根底的查问性能测试当前,接下来测试冷热数据拆散计划下的查问性能。区别于后面的测试,当采纳冷热数据拆散计划时,并不是所有数据都在 JuiceFS 中,数据会优先写入 SSD 盘。

首先选取一个固定的查问工夫范畴,评估 JuiceFS 缓存对性能的影响,测试后果如下图:

跟固定工夫范畴的查问一样,从第二次查问开始因为缓存的建设带来了 78% 左右的性能晋升。不同的中央在于第四次查问因为波及到查问新写入或者合并后的数据,而 JuiceFS 目前不会在写入时缓存大文件,会对查问性能造成肯定影响,之后会提供参数容许缓存写入数据来改善新数据的查问性能。

总结

通过 ClickHouse 的存储策略能够很简略地将 SSD 和 JuiceFS 联合应用,实现性能与老本的两全计划。从写入和查问性能测试的后果上来看 JuiceFS 齐全能够满足 ClickHouse 的应用场景,用户不用再放心容量问题,在减少大量老本的状况下轻松应答将来几倍的数据增长需要。JuiceFS 目前曾经反对超过 20 家私有云的对象存储,联合齐全兼容 POSIX 的个性,不须要改变 ClickHouse 任何一行代码就能够轻松接入云上的对象存储。

瞻望

在以后越来越强调云原生的环境下,存储计算拆散曾经是大势所趋。ClickHouse 2021 年的 roadmap 上曾经明确把存储计算拆散作为了次要指标,尽管目前 ClickHouse 曾经反对把数据存储到 S3 上,但这个实现还比拟毛糙。将来 JuiceFS 也会与 ClickHouse 社区严密单干独特摸索存算拆散的方向,让 ClickHouse 更好地辨认和反对共享存储,实现集群伸缩时不须要做任何数据拷贝。

举荐浏览:
Elasticsearch 存储老本省 60%,稿定科技干货分享

退出移动版