0
95
0
0
首页/专栏/ 版本发布/ 查看内容

ClickHouse 24.11 版本发布说明

 admin   发表于  2024-12-13 14:47
专栏 版本发布



新的一月,又迎来了新版本的发布!

发布概要

本次ClickHouse 24.11 版本包含了9个新功能🎁、15性能优化🛷、68个bug修复🐛

在本次更新中,并行哈希 Join 成为默认的 Join 策略,WITH FILL 支持 STALENESS 修饰符,可以预热标记缓存。同时,引入 BFloat16 数据类型,显著提升了向量搜索的速度。


新贡献者

正如往常,我们热烈欢迎 24.11 版本中的所有新贡献者!ClickHouse 的持续流行,很大程度上依赖社区的积极贡献。看到社区的不断壮大,令我们倍感荣幸。

以下是本次版本的新贡献者名单:

0xMihalich, Max Vostrikov, Payam Qorbanpour, Plasmaion, Roman Antonov, Romeo58rus, Zoe Steinkamp, kellytoole, ortyomka, qhsong, udiz, yun, Örjan Fors, Андрей


并行哈希 Join 成为默认策略  

贡献者:Nikita Taranov  

在本次版本中,并行哈希 Join 算法取代了哈希 Join,成为默认的 Join 策略。  

并行哈希 Join 是哈希 Join 的一种改进算法,通过将输入数据分片并并发地构建多个哈希表,实现了更快的 Join 操作,但需要更多内存资源。以下是该算法的查询管道示意图:  

关于并行哈希 Join 的更多技术细节,请参阅博客文章《ClickHouse Joins Under the Hood - Hash Join, Parallel Hash Join, Grace Hash Join》【https://clickhouse.com/blog/clickhouse-fully-supports-joins-hash-joins-part2】。  

除了默认启用外,本次更新还对该算法进行了性能优化。现在,线程间分发的块在并行处理时使用零拷贝技术,避免了每次复制块列所带来的额外开销。  


ORDER BY WITH FILL 引入 STALENESS 修饰符  

贡献者:Mikhail Artemenko  

本次版本为 WITH FILL 引入了 STALENESS 修饰符。以下是结合 MidJourney 数据集的使用示例。假设我们已经下载了 Parquet 文件,可以通过以下查询将数据填充到表中:  

CREATE TABLE images (    id String,    timestamp DateTime64,    height Int64,    width Int64,    size Int64
)ENGINE = MergeTreeORDER BY (size, height, width);

INSERT INTO images WITH data AS ( SELECT assumeNotNull(timestamp) AS ts, assumeNotNull(id) AS id, assumeNotNull(height) AS height, assumeNotNull(width) AS width, assumeNotNull(size) AS size, parseDateTime64BestEffort(ts) AS ts2 FROM file('data/0000{00..55}.parquet'))SELECT id, ts2 AS timestamp, height, width, sizeFROM data;

如果我们想统计 2023 年 3 月 24 日某一秒内生成的图像数量,可以通过参数定义起始和结束时间:  

SET param_start = '2023-03-24 00:24:02',     param_end = '2023-03-24 00:24:03';

接着,我们可以使用 WITH FILL 子句计算每 100 毫秒的计数,同时为空桶填充值 0:  

SELECT    toStartOfInterval(timestamp, toIntervalMillisecond(100)) AS bucket,    count() AS count, 'original' as originalFROM MidJourney.imagesWHERE (timestamp >= {start: String}) AND (timestamp <= {end: String})GROUP BY ALLORDER BY bucket ASCWITH FILLFROM toDateTime64({start:String}, 3)TO toDateTime64({end:String}, 3) STEP toIntervalMillisecond(100);
┌──────────────────bucket─┬─count─┬─original─┐│ 2023-03-24 00:24:02.000 │     0 │          ││ 2023-03-24 00:24:02.100 │     0 │          ││ 2023-03-24 00:24:02.200 │     0 │          ││ 2023-03-24 00:24:02.300 │     3 │ original│ 2023-03-24 00:24:02.400 │     0 │          ││ 2023-03-24 00:24:02.500 │     0 │          ││ 2023-03-24 00:24:02.600 │     1 │ original│ 2023-03-24 00:24:02.700 │     1 │ original│ 2023-03-24 00:24:02.800 │     2 │ original│ 2023-03-24 00:24:02.900 │     0 │          │└─────────────────────────┴───────┴──────────┘

本次更新新增的 STALENESS 子句,其功能定义如下(摘自文档):  

当定义了 STALENESS const_numeric_expr 时,查询将生成连续的行,直到前一行与当前行的时间差超过 const_numeric_expr。  

在查询中,STALENESS 和 WITH FILL...FROM 子句不能同时使用,因此我们需要移除 WITH FILL...FROM。移除后,查询将如下所示:

SELECT    toStartOfInterval(timestamp, toIntervalMillisecond(100)) AS bucket,    count() AS count, 'original' as originalFROM MidJourney.imagesWHERE (timestamp >= {start: String}) AND (timestamp <= {end: String})GROUP BY ALLORDER BY bucket ASCWITH FILLTO toDateTime64({end:String}, 3) STEP toIntervalMillisecond(100);

删除 WITH FILL...FROM 子句意味着结果集将从第一个实际存在的值开始,而不是从指定的时间戳回填 0 值。

┌──────────────────bucket─┬─count─┬─original─┐│ 2023-03-24 00:24:02.300 │     3 │ original│ 2023-03-24 00:24:02.400 │     0 │          ││ 2023-03-24 00:24:02.500 │     0 │          ││ 2023-03-24 00:24:02.600 │     1 │ original│ 2023-03-24 00:24:02.700 │     1 │ original│ 2023-03-24 00:24:02.800 │     2 │ original│ 2023-03-24 00:24:02.900 │     0 │          │└─────────────────────────┴───────┴──────────┘

如果为 STALENESS 设置 200 毫秒的值,查询将仅填充空行,直到前一行与当前行的时间差超过 200 毫秒:  

SELECT    toStartOfInterval(timestamp, toIntervalMillisecond(100)) AS bucket,    count() AS count, 'original' as originalFROM MidJourney.imagesWHERE (timestamp >= {start: String}) AND (timestamp <= {end: String})GROUP BY ALLORDER BY bucket ASCWITH FILLTO toDateTime64({end:String}, 3) STEP toIntervalMillisecond(100)STALENESS toIntervalMillisecond(200);
┌──────────────────bucket─┬─count─┬─original─┐│ 2023-03-24 00:24:02.300 │     3 │ original│ 2023-03-24 00:24:02.400 │     0 │          ││ 2023-03-24 00:24:02.600 │     1 │ original│ 2023-03-24 00:24:02.700 │     1 │ original│ 2023-03-24 00:24:02.800 │     2 │ original│ 2023-03-24 00:24:02.900 │     0 │          │└─────────────────────────┴───────┴──────────┘

此时,以下行将从结果集中被移除:  

│ 2023-03-24 00:24:02.500 │     0 │          │



HTTP 接口错误检测  

贡献者:Sema Checherinda  

从现在起,HTTP 接口可以在结果流式传输给客户端之后,仍然可靠地检测到错误。在之前的版本中,如果我们在 ClickHouse Server 上运行以下查询:  

curl http://localhost:8123/?output_format_parallel_formatting=0 -d "SELECT throwIf(number > 100000) FROM system.numbers FORMAT Values"

我们会先看到值流输出,随后附加如下的错误消息:  

Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(number, 100000) :: 2) -> throwIf(greater(number, 100000)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 24.3.1.465 (official build))

退出代码为 0,这表明查询被认为成功运行。而从 24.11 版本开始,我们将会看到如下输出:  

Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(__table1.number, 100000_UInt32) :: 0) -> throwIf(greater(__table1.number, 100000_UInt32)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 24.11.1.2557 (official build))curl: (18) transfer closed with outstanding read data remaining

并且返回了非零退出代码 18。  


Mark 缓存预热  

贡献者:Anton Popov  

Mark 文件将主键映射到每列文件的偏移量,是表索引的一部分。每个表的列都对应一个 mark 文件。这些文件可能占用大量内存,并会按需加载到 mark 缓存中。  

从 24.11 版本开始,你可以通过 mark_cache_prewarm_ratio 参数预热 mark 缓存,该参数默认值为 95%。  

服务器会在每次插入、合并或提取数据部分时主动将 mark 文件加载到内存缓存中,直到缓存几乎填满。  

此外,新增了一个系统命令 SYSTEM PREWARM MARK CACHE t,可以立即将所有 mark 文件加载到缓存中。  


BFloat16 数据类型  

贡献者:Alexey Milovidov  

BFloat16 数据类型由 Google Brain 团队开发,专用于表示向量嵌入。顾名思义,它由 16 位组成,其中 1 位为符号位,8 位为指数,7 位为尾数(小数部分)。  

这一数据类型的指数范围与 Float32(单精度浮点数)相同,但尾数位数较少(7 位,而非 23 位)。  

现在,ClickHouse 已支持 BFloat16 数据类型,非常适合用于 AI 和向量搜索场景。要使用这一新类型,需要进行以下参数配置:  

SET allow_experimental_bfloat16_type=1;

我们在 AWS c7a.metal-48xl 实例上进行了一项性能测试,对 28 百万个 384 维向量进行完整扫描的最近邻搜索,结果如下:  

clickhouse-benchmark --query "WITH[-0.02925783360957671,-0.03488947771094666,...,0.032484047621093616]::Array(BFloat16)AS center SELECT d FROM (SELECT cosineDistance(vector, center) AS d    FROM hackernews_llama_memory ORDER BY d LIMIT 10) SETTINGS allow_experimental_bfloat16_type = 1"
BFloat16: 0.061 sec, 301 GB/sec.Float32: 0.146 sec, 276 GB/sec.



注册ClickHouse中国社区大使,领取认证考试券

ClickHouse社区大使计划正式启动,首批过审贡献者享原厂认证考试券!


路过

雷人

握手

鲜花

鸡蛋

版权声明:本文为 clickhouse 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论