DoubleCloud 即将停止服务。利用 ClickHouse 限时免费迁移服务迁移至 ClickHouse。立即联系我们 ->->

博客 / 工程

ClickHouse 23.3 版本发布

author avatar
ClickHouse 团队
2023 年 4 月 13 日

v 23.3.png

发布列车继续前进。我们非常高兴地分享 23.3 LTS 中的更新。

并且,我们已经确定了 23.4 版本的发布日期,请立即注册参加 4 月 27 日上午 9:00(太平洋标准时间)/ 下午 6:00(中欧夏令时)的社区电话会议。

版本摘要

  • 新增 22 个功能。
  • 性能优化 14 项。
  • 修复了 61 个错误。

下面列出了一些突出显示的功能子集。但不要错过内存中的压缩标记、扩展的临时表以及查看已取消查询的结果的功能(以及更多其他功能)。

并行副本,用于充分利用副本的强大功能 (Nikita Mikhailov)

使用并行副本,数据可以由同一分片的多个副本并行处理。

在 ClickHouse 集群中,当总数据量无法容纳在单个主机上或使用单个主机进行数据处理速度过慢时,可以使用分片:数据以分片(数据块的集合)的形式分布在多个主机上。

这允许查询性能进行扩展,因为不同的数据子集可以由多个 ClickHouse 主机并行处理。通常,分布式表用于将查询路由到所有分片。我们在下面进行了简要说明

在某些情况下,拥有多个分片是不切实际的或不必要的。例如,当您在几乎无限的共享对象存储(如ClickHouse Cloud)之上运行 ClickHouse 时,所有 ClickHouse 实例都可以访问相同物理数据,并且实际上是单个(无限)分片的多个副本。使用新的 ClickHouse 并行副本功能,您可以利用这些副本来并行化数据处理。我们在下面进行了可视化

上图显示,使用设置allow_experimental_parallel_reading_from_replicas = true,查询将发送到一个(随机的)发起者副本节点,该节点将查询转发到所有参与的副本(数量通过max_parallel_replicas配置)。然后,每个副本并行处理整个分片数据中不同的数据范围子集(由发起者节点动态分配),并将本地结果发送回发起者节点,发起者节点将本地结果合并到最终结果中。

在 ClickHouse Cloud 中,存储和计算的分离允许动态增加(或减少)副本节点的数量,以(理想地)线性甚至超线性地调整查询处理时间。无需任何物理分片或实际数据的重新平衡!

并行副本功能也适用于由多个分片组成的自管理 ClickHouse 集群,每个分片有多个副本。然后,每个分片的多个副本将并行处理分片数据范围的不同子集

因此,可以通过添加数据的额外副本(副本)来调整数据处理速度。

具有动态分片的并行副本 (Antonio Andelic)

通过处理数据的不同子集,每个并行副本都可以被视为一个分片,而无需对数据进行物理分片。

动态分片现在允许用户控制这些虚拟分片是如何形成的,以及查询是如何分布的。现在可以配置并行副本,以便通过在发起者节点上基于parallel_replicas_custom_key表达式自动添加不同的过滤器来拆分工作,然后再将查询转发到所有参与的副本

这对于特定查询可能很有益。例如,对于 GROUP BY 查询,如果 group by 列用作parallel_replicas_custom_key表达式,则发起者节点无需合并来自参与副本的本地结果,因为本地结果中不会出现组重叠(因此,如果设置了parallel_replicas_custom_key,则distributed_group_by_no_merge会自动设置为 2)。

此外,您现在还可以通过parallel_replicas_custom_key_filter_type设置配置parallel_replicas_custom_key表达式如何用于在参与的副本节点之间拆分工作。当设置为default时,将在发起者节点上的查询中添加一个使用节点数模数的“除法的余数”SQL谓词(我们假设每个参与的NODE_COUNT节点在范围0 到 NODE_COUNT - 1内都有一个唯一的标识符NODE_NUM

WHERE parallel_replicas_custom_key % NODE_COUNT = NODE_NUM

parallel_replicas_custom_key_filter_type设置为range时,parallel_replicas_custom_key表达式的整个值空间将通过为每个副本添加一个“范围”谓词来均匀地拆分到副本节点之间,该谓词简化后如下所示(对于范围过滤器,parallel_replicas_custom_key表达式需要是无符号整数类型)

WHERE parallel_replicas_custom_key >= NODE_NUM * (MAX_OF_VALUE_SPACE / NODE_COUNT)
  AND parallel_replicas_custom_key < (NODE_NUM + 1) * (MAX_OF_VALUE_SPACE / NODE_COUNT)

如果数据根据parallel_replicas_custom_key进行本地分布(排序),并且键的值在其数据类型的整个域中均匀分布(例如,使用哈希值时),则这种“范围”工作拆分配置是节省 IO 时间的优化。

对于那些希望详细了解并行副本以及如何利用基于对象存储的集群的全部功能的读者,敬请期待我们即将发布的更深入的博文。

轻量级删除现已正式发布 (Jianmei Zhang 和 Alexander Gololobov)

在我们最近的一篇博文中,我们探讨了在 ClickHouse 中删除和更新数据的策略。作为其中的一部分,我们讨论了一项最新功能,该功能使在 ClickHouse 中删除数据成为一项更轻量级的操作——恰如其分地命名为“轻量级删除”。在社区的强烈需求和期待下,我们现在宣布此功能已普遍可用,并已准备好用于生产环境。

这种删除数据的方法现在代表了从 ClickHouse 中删除数据的首选和最有效的方式。通过 DELETE FROM table 语法公开,用户可以指定条件以删除特定行,如下所示

DELETE FROM table WHERE col1 = 'Hi' AND col2 = 2

用户应该知道,此功能利用内部列来标记已删除的行。然后在常规合并周期中删除这些行。这有一些含义,主要是行将仅**最终**从磁盘中删除。虽然已从搜索结果中排除,但已删除的行将保留在磁盘上,直到其部分内容被合并。发生这种情况所需的时间不是确定性的。这意味着

  • 节省空间不会像发出删除通过常规变异操作那样立即。如果节省空间至关重要(例如,磁盘空间不足),请考虑使用变异操作。
  • 由于没有删除保证,因此具有合规性要求的用户可能希望使用变异操作来确保数据被删除。

除了这两种用例之外,我们建议用户今天开始将其删除工作负载迁移到 ClickHouse。

MySQL 兼容性 (Robert Schulze, Flynn)

虽然 ClickHouse 多年来一直支持 MySQL 线路协议,但方言和支持的功能是不同的。这是故意的,因为它允许用户更轻松地编写分析查询。但是,随着诸如Google Looker之类的第三方工具需要广泛的 MySQL 兼容性,我们一直在改进我们在这方面的支持。虽然对诸如SELECT 'ClickHouse' REGEXP 'M?ouse$';之类的运算符的支持对于完整的语法支持非常重要,但其他函数(如parseDateTime)为 ClickHouse 带来了新的功能。此特定函数通过允许用户在MySQL 语法中指定日期格式来增强 ClickHouse 的日期解析功能,对于那些经典的parseDateTimeBestEffort函数无法正确确定日期时间的情况。

例如,假设您遇到使用一年中的某一天来表示特定日期的格式

SELECT parseDateTimeBestEffort('1994-127 23:23:23')

0 rows in set. Elapsed: 0.103 sec.

Received exception from server (version 23.3.1):
Code: 41. DB::Exception: Received from localhost:9000. DB::ParsingException. DB::ParsingException: Cannot read DateTime: unexpected number of decimal digits after year: 3: While processing parseDateTimeBestEffort('1994-127 23:23:23'). (CANNOT_PARSE_DATETIME)

现在可以使用 MySQL 格式解析此格式

SELECT parseDateTime('1994-127 23:23:23', '%Y-%j %H:%M:%S')

┌─parseDateTime('1994-127 23:23:23', '%Y-%j %H:%M:%S')─┐
│                              	1994-05-07 23:23:23    │
└──────────────────────────────────────────────────────┘

对于我们的 Java 用户,我们还支持函数parseDateTimeInJodaSyntax,允许使用众所周知的Joda 语法

SELECT parseDateTimeInJodaSyntax('1994-127 23:23:23', 'YYYY-DDD HH:mm:ss')

┌─parseDateTimeInJodaSyntax('1994-127 23:23:23', 'YYYY-DDD HH:mm:ss')─┐
│                                             	1994-05-07 23:23:23   │
└─────────────────────────────────────────────────────────────────────┘

所有这些改进都释放了无限的可能性,尤其是在 BI 工具方面。

Grafana 中的跟踪

作为我们最近一篇博文关于在 ClickHouse 上构建可观察性解决方案的一部分,我们关注了跟踪,并意识到它们在我们官方 Grafana 插件中的渲染可以得到显著改进。通过少量更改,最新版本现在支持使用跟踪面板探索视图在 Grafana 中可视化跟踪。虽然这显然有助于理解您自己服务和应用程序的行为,但正如博客所强调的那样,我们还发现这是一种探索 ClickHouse 中查询的有效工具。

ClickHouse 允许为任何查询生成跟踪数据,设置opentelemetry_trace_processorsopentelemetry_start_trace_probability。为查询设置这些内容会导致在系统表opentelemetry_span_log中生成跟踪。每个跟踪都由跨度组成,表示为上述表中的行。这些跨度中的每一个都显示了代码级别的查询执行,允许用户识别查询中代价高昂的执行步骤。使用此数据和以下步骤,用户现在可以在 Grafana 中可视化这些步骤。

启用跟踪,运行查询并记下查询 ID。我们明确地将 max_threads 设置为 1 以限制跟踪数据的可视化目的

// enable tracing
SET opentelemetry_trace_processors=1;
SET opentelemetry_start_trace_probability=1;


// run a query
SELECT
	toStartOfMonth(upload_date) AS month,
	sum(view_count) AS `Youtube Views`,
	bar(sum(has_subtitles) / count(), 0.55, 0.7, 100) AS `% Subtitles`
FROM youtube
WHERE (month >= '2020-08-01') AND (month <= '2021-08-01')
GROUP BY month
ORDER BY month ASC
SETTINGS max_threads = 1

Query id: 77931e25-b1a0-4eb1-82dc-786d95629f89

为了确保以正确的格式返回查询 ID 的跟踪数据,请从 Grafana Explore 中运行以下内容。确保在查询编辑器中设置Format=Trace

WITH '<query_id>' AS my_query_id
SELECT
	toString(trace_id) AS traceID,
	toString(span_id) AS spanID,
	if(toString(parent_span_id)='0', Null, parent_span_id) AS parentSpanID,
	'ClickHouse' AS serviceName,
	operation_name AS operationName,
	start_time_us/1000 AS startTime,
	finish_time_us/1000 AS finishTime,
	(finish_time_us - start_time_us)/1000 AS duration,
	arrayMap(key -> map('key', key, 'value', attribute[key]), mapKeys(attribute)) AS serviceTags
FROM clusterAllReplicas('default', 'system', 'opentelemetry_span_log')
WHERE trace_id IN (
	SELECT trace_id
	FROM clusterAllReplicas('default', 'system', 'opentelemetry_span_log')
	WHERE (attribute['clickhouse.query_id']) = my_query_id
)
ORDER BY startTime ASC

请注意,我们仅对 ClickHouse Cloud 使用clusterAllReplicas函数。本地用户可以直接使用opentelemetry_span_log表。

Markdown Image

下一个合乎逻辑的问题是如何使用这些跟踪来调试您的查询……敬请期待内容!同时,要将此新功能与您自己的服务一起使用,请立即安装最新的 ClickHouse Grafana 插件。对于那些不熟悉跟踪并希望了解更多信息的人,请参阅我们最近的一篇博文。有关安装和使用 Grafana 插件的更多信息也可以在这里找到这里

分享此帖子

订阅我们的时事通讯

随时了解功能发布、产品路线图、支持和云产品!
正在加载表单…
关注我们
Twitter imageSlack imageGitHub image
Telegram imageMeetup imageRss image