ClickHouse新功能之WAL(Write-Ahead-Log )

​ClickHouse新版本开始支持Write-Ahead-Log(WAL) 功能。
在这里插入图片描述
介绍 WAL 之前,先重温一下 MergeTree 最基本的合并过程。

MergeTree的高频写问题?

CREATE TABLE test
(
    id UInt8,
    name String,
    age UInt8,
    shijian Date)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(shijian)
ORDER BY id;

insert into test values(1001,'张三','18',now());
insert into test values(1002,'李四','28',now());
insert into test values(1003,'王五','38',now());

​ 此时,MergeTree 会生成 3 个分区目录:

在这里插入图片描述

​ 手动合并之后的分区目录

在这里插入图片描述

​ 对于 ClickHouse MergeTree 引擎,在数据的写入过程中,数据总会以数据片段的形式被写入磁盘,且数据片段不可修改。每一批次的写入(每执行一次INSERT)MergeTree都会按照分区规则在磁盘上生成一个全新的分区目录(part),为了避免片段过多,在未来的某一时刻,属于相同分区的数据片段会被合并成一个全新的分区目录,这种数据分区往复合并的特点正是合并树的名称由来。其中如果有多个客户端,每个客户端写入的数据量较少、次数较频繁的情况下,就会引发以下错误提示。

Too many parts (N). Merges areprocessing significantly slower than inserts.

​ WAL预写日志解决了这个问题,提高写入性能,在 ClickHouse 的新版本中,MergeTree 多了这么几个参数:

	M(SettingUInt64, min_bytes_for_wide_part, 0, xxxxxxxx, 0) \
	M(SettingUInt64, min_rows_for_wide_part, 0, xxxxxxxxx, 0) \
	M(SettingUInt64, min_bytes_for_compact_part, 0, xxxxx, 0) \
	M(SettingUInt64, min_rows_for_compact_part, 0, xxxxxx, 0) \
	M(SettingBool, in_memory_parts_enable_wal, true, xxxx, 0) \
	M(SettingUInt64, write_ahead_log_max_bytes, 1024 * 1024 * 1024, xxxx, 0) \

​ 其中 in_memory_parts_enable_wal 默认为 true,这说明预写日志默认就是开启状态的。

CREATE TABLE default.test1
(
    id UInt8,
    name String,
    age UInt8,
    shijian Date
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(shijian)
ORDER BY id
SETTINGS min_rows_for_compact_part = 2, index_granularity = 8192;

​ min_rows_for_compact_part = 2 表示数据首先会被写到内存和 WAL中,当触发 Merge 的时候,如果数据大于 2 行,就直接把合并后的分区写到磁盘。

insert into test1 values(1001,'张三','18',now());
insert into test1 values(1002,'李四','28',now());
insert into test1 values(1003,'王五','38',now());

​ 写入之后还没有触发 Merge 动作,磁盘目录情况:

在这里插入图片描述

clickhouse-client -m

	optimize table test1;

在这里插入图片描述

​ 在此之前,MergeTree 只有一种 wide 布局,也就是每个列字段都拥有一组独立的文件,例如下图所示:

在这里插入图片描述

​ 由于现在添加了wal新特性,致使MergeTree的分区布局也得到了扩展,插入过程中,数据首先进入内存,满足阈值之后,会将内存中的数据刷到磁盘。在这里插入图片描述

CREATE TABLE default.test2
(
    id UInt8,
    name String,
    age UInt8,
    shijian Date
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(shijian)
ORDER BY id
SETTINGS min_rows_for_compact_part = 2, min_rows_for_wide_part = 10, index_granularity = 8192;
insert into test2 values(1001,'张三','18',now());
insert into test2 values(1002,'李四','28',now());
insert into test2 values(1003,'王五','38',now());
optimize table test2;

在这里插入图片描述

​ 所有的的数据写到了同一个 data.bin 文件中,所有列的标记文件也都写到了同一个.mark文件。当列字段很多,数据又很少的时候,可以考虑使用这种布局模式的分区。

详情了解更多欢迎关注公众号
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值