ClickHouse 22.5 版本深度解析:新特性、性能优化与稳定性改进全览
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
本文基于 docs/changelogs/archive/v22.5.1.2079-stable.md 官方 Changelog 整理而成,并深入对应源码确认实现细节。ClickHouse 22.5 是 2022 年发布的稳定版本,引入了 GROUPING SETS、MeiliSearch 存储引擎、Prometheus 输出格式、MySQLDump 输入格式、wyHash64 哈希函数等一批重要能力,同时在 JIT 编译、Join 并行、聚合性能等方面做了深度优化。读完本文,你将掌握 22.5 版本的核心新语法与配置项、关键性能改进的底层原理,以及需要重点关注的破坏性变更与修复清单。
一、Backward Incompatible Change:升级前必读
22.5 版本包含两个需要升级用户特别关注的破坏性变更。
1. FIPS 合规的 BoringSSL
本版本将 BoringSSL 模块升级为官方 FIPS 合规版本,从而使 ClickHouse 整体达到 FIPS(Federal Information Processing Standards)合规要求。对于有合规需求的政企或金融用户,这意味着可以在启用 FIPS 模式的系统中正常运行 ClickHouse 的 TLS 链路,而无需额外的兼容层。
2. 后台任务与 SelectedRows/SelectedBytes 指标语义变化
此前,后台合并(merges)、变更(mutations)以及OPTIMIZE操作会同时累计SelectedRows和SelectedBytes指标。自 22.5 起:
- 后台 merges、mutations 和
OPTIMIZE不再递增SelectedRows与SelectedBytes; - 它们(仍然)像之前一样递增
MergedRows和MergedUncompressedBytes。
这意味着依赖SelectedRows/SelectedBytes监控前台查询负载的用户,升级后这些指标会显著变小(不再混入后台任务量),需要相应调整告警阈值与容量规划模型。
二、New Feature:22.5 的新能力全景
1. GROUPING SETS:GROUP BY 多维分组
22.5 正式支持在GROUP BY子句中使用GROUPING SETS,并支持对多个 grouping sets 进行并行处理。这是对多维度汇总报表(如同时按天、按天+城市、全量聚合)的核心语法补充。
从源码实现看,优化器对只有单个分组的GROUPING SETS做了重写简化。在 src/Interpreters/GroupingSetsRewriterVisitor.h 中可以看到其规则:
GROUPING SETS (foo)→GROUP BY fooGROUPING SETS ((foo, bar))→GROUP BY foo, bar- 而
GROUPING SETS (foo, bar)(两个分组)不会被重写,保留多维语义。
-- 一次查询得到三种粒度的统计 SELECT toDate(event_time) AS day, city, count() FROM events GROUP BY GROUPING SETS ( (day), (day, city), () );2. MeiliSearch 存储引擎与表函数
本版本新增了MeiliSearch的存储引擎(StorageMeiliSearch)和对应的表函数实现,使得 ClickHouse 可以直接读写外部 MeiliSearch 全文检索引擎中的数据,实现"ClickHouse 聚合分析 + MeiliSearch 全文检索"的组合架构。
3. SYSTEM SYNC DATABASE REPLICA:同步 Replicated 库元数据
Replicated 数据库的元数据同步是异步的,这可能导致副本间表结构短暂不一致。22.5 新增SYSTEM SYNC DATABASE REPLICA查询,用于显式同步指定 Replicated 数据库的元数据:
SYSTEM SYNC DATABASE REPLICA replicated_database_name;该命令在 src/Parsers/ParserSystemQuery.cpp 中解析(Type::SYNC_DATABASE_REPLICA),并由 src/Interpreters/InterpreterSystemQuery.cpp 执行。在创建副本库后、或需要确保各副本表结构一致时,可主动调用它等待元数据同步完成。
4. Prometheus 输出格式
新增Prometheus输出格式(输出侧),可将查询结果渲染为 Prometheus 文本暴露格式,便于直接接入 Prometheus 抓取端点,作为自定义指标源。该格式通过 src/Formats/registerFormats.cpp 中的registerOutputFormatPrometheus注册(FORMAT Prometheus即可使用)。
5. JSONLines / NDJSON 别名
为JSONEachRow增加JSONLines与NDJSON两个别名,满足常见的数据交换工具习惯。这意味着在INSERT ... FORMAT NDJSON、SELECT ... FORMAT JSONLines中均可直接使用,无需再记忆JSONEachRow这一名称。
6. 查询级 parts_to_delay_insert / parts_to_throw_insert
parts_to_delay_insert与parts_to_throw_insert(控制 MergeTree 分区数过多时的插入延迟/拒绝阈值)此前是表级设置,22.5 起提升为查询级设置,可在查询中覆盖表级配置:
INSERT INTO tbl SELECT ... SETTINGS parts_to_throw_insert = 500;7. 临时表统计信息
临时表(Temporary Table)现在可以在系统表中展示总行数(total rows)与总字节数(total bytes),便于排查会话级临时数据的内存占用。
8. 新哈希函数 wyHash64
新增wyHash64哈希函数,返回 UInt64。其实现位于 src/Functions/FunctionsHashing.h(ImplWyHash64,第 1971 行附近注册为wyHash64),文档信息见 src/Functions/FunctionsHashingMisc.cpp:
SELECT wyHash64('ClickHouse') AS Hash; -- 12336419557878201794值得关注的是,源码注释中对各哈希函数的 AVX-512 适用性做了详细评估:wyHash64在 8 字节及以下参数上性能约为 xxHash64 的 0.85 倍、其余场景持平,因此 AVX-512 对其没有收益(hash_avx512_usage<ImplWyHash64> = HashAVX512Usage::Never),而xxHash64、xxh3、murmurHash2_64、cityHash64等则能从 AVX-512 中获益。选择哈希函数时,如需 SIMD 加速与高速吞吐,xxHash64/xxh3仍是更优选择。
9. 窗口函数 nth_value
新增窗口函数nth_value,允许在窗口分区内取第 N 个值,补齐了分析函数矩阵(first_value/last_value/nth_value)的一环:
SELECT department, employee, nth_value(salary, 3) OVER (PARTITION BY department ORDER BY salary DESC) AS third_highest FROM employees;10. MySQLDump 输入格式
新增MySQLDump输入格式(输入侧),可直接读取mysqldump导出的文件:
- 它会读取 dump 中属于一个表的所有
INSERT语句数据; - 若 dump 包含多个表,默认读取第一个表的数据。
该格式在 src/Formats/registerFormats.cpp 中通过registerInputFormatMySQLDump注册。配合表函数file或url即可将 MySQL 备份直接灌入 ClickHouse,简化 MySQL 迁移链路:
SELECT * FROM file('dump.sql', 'MySQLDump') -- 或按目标结构 INSERT INTO my_table SELECT * FROM file('dump.sql', 'MySQLDump');11. 单二进制诊断工具 clickhouse-diagnostics
新增基于单一二进制的诊断工具(clickhouse-diagnostics),用于快速收集服务器状态信息,其使用说明见 utils/clickhouse-diagnostics/README.md。该工具适合在排查生产环境问题时一键导出诊断数据。
12. 远程文件访问监控系统表
新增用于统计远程文件访问请求的系统表,目标是帮助用户在存算分离场景下分析性能波动原因。查询读取远端文件的某个 segment 时产生一条记录,读取类型包括:
| 读取类型 | 含义 |
|---|---|
READ_FROM_FS_AND_DOWNLOADED_TO_CACHE | 从远端文件系统读取并下载到本地缓存 |
READ_FROM_CACHE | 直接命中本地缓存 |
READ_FROM_FS_BYPASSING_CACHE | 绕过缓存直接读取远端文件 |
通过该表可量化缓存命中率,定位"读远端"与"读缓存"的比例,从而诊断存算分离架构下的性能抖动来源。
13. H3 地理网格函数扩展
新增h3Line(两点间网格线)、h3Distance(两点网格距离)、h3HexRing(六边形环)三个 H3 索引函数,实现均位于 src/Functions/ 下(如 h3Line.cpp、h3Distance.cpp、h3HexRing.cpp),与既有的geoToH3、h3kRing等共同构成完整的地理空间分析工具集。同时为h3kRing第二参数增加了隐式类型转换,提升了易用性。
14. system.certificates 系统表
新增system.certificates系统表,展示服务器信任的证书信息。对应实现为 src/Storages/System/StorageSystemCertificates.h,可用于审计 TLS 证书链配置。
三、Performance Improvement:性能优化详解
1. JIT 编译排序比较器
ORDER BY、MergeJoin 以及 MergeTree 插入流程中,排序列的比较器支持 JIT(即时编译)编译,显著减少比较函数调用开销。这也是 ClickHouse 通过 LLVM 对热点算子做运行时代码生成的代表性实践。
2. OR LIKE 链改写为 multiMatchAny
优化器将LIKE串联的OR条件改写为multiMatchAny(基于 RE2 的多模式匹配),大幅提升多模式文本过滤性能。
3. countDistinct 查询重写
SELECT countDistinct(a) FROM t会被重写为:
SELECT count(1) FROM (SELECT a FROM t GROUP BY a)利用聚合下推消除多余的 distinct 中间层,减少数据传输。
4. system.asynchronous_metric_log 瘦身约 10 倍
重构了system.asynchronous_metric_log的表结构,占用空间减少约 10 倍;同时移除了无用的event_time_microseconds字段。这是对系统监控日志常驻磁盘空间的直接削减。
5. HashJoin 右表并行填充
默认HashJoin插入右表行时不是线程安全的,此前只能在单线程中执行,右表较大时 CPU 利用率低、Join 过慢。22.5 修复了该瓶颈,使右表构建可并行化,显著改善大右表 Join 的吞吐。
6. File 存储与 glob 读取优化
当路径包含 glob 且匹配目录内含大量文件时,File存储和file表函数的读取性能得到提升。同时改进了 glob 场景下的 schema 推断:只在合理情况下尝试下一个匹配文件(此前任何错误都会尝试下一个文件),并修复了相关推断缺陷(src/Interpreters/TreeOptimizer.cpp 等相关优化器逻辑)。
7. HiveText 输入格式并行解析
为HiveText输入格式实现并行解析,读取本地文件时解析速度提升可达 2 倍。对 Hive 数仓文本数据的导入场景收益明显。
8. 文件描述符缓存互斥锁细化
通过收窄文件描述符缓存中 mutex 的作用域,减少锁竞争,提升高并发小文件访问的性能。
9. WindowView WATCH 查询优化
改进 WindowView 的WATCH查询:通过fire_condition信号缩短结果提供延迟,并通过更频繁检查isCancelled()加速 ctrl-c 取消操作。
10. 无 GROUP BY 的 avg/sum 优化
不带GROUP BY表达式时(即全表聚合),avg、sum聚合函数性能得到提升,使用更高效的向量化聚合路径。
11. 一元算术函数动态分发
bitCount、bitNot、abs、intExp2、intExp10、negate、roundAge、roundDuration、roundToExp2、sign等一元函数通过动态分发(dynamic dispatch)优化,为不同数据类型选择最优执行路径。
四、Improvement:易用性与稳定性增强
1. clickhouse-client / clickhouse-local 改进
- 使用
clickhouse-client --file而未前置--external时给出明确提示; clickhouse-client/clickhouse-local中INSERT查询可被正确取消;clickhouse-local中INSERT SELECT及文件处理的进度提示更准确;clickhouse-benchmark支持从环境变量读取认证信息。
2. 内存超卖(Memory Overcommit)默认开启
内存超卖(overcommit)默认启用:在选定查询被停止之前,若所需内存已释放,所有等待查询继续执行;若在查询收到取消通知前内存已释放,则不再停止任何查询。这显著缓解了内存不足时的"误杀"。
其核心实现围绕 src/Common/MemoryTracker.h 中的OvercommitTracker/OvercommitRatio展开,配套测试见 src/Common/tests/gtest_overcommit_tracker.cpp。本版本还修复了OvercommitRatio比较时的潜在溢出、以及日志期间 OvercommitTracker 的潜在死锁问题。
3. 后台任务线程数运行时调整
在顶层配置中指定的后台操作线程数(merges、mutations、moves、fetches)现在可以在运行时增加。此前background_fetches_pool_size等设置被废弃后若出现在顶层配置会抛出A setting 'background_fetches_pool_size' appeared at top level in config异常,此问题也在本版本修复。
4. 文件系统缓存管理
SYSTEM DROP FILESYSTEM CACHE查询得到增强:支持<path>选项按路径删除,以及FORCE选项强制删除。缓存读取逻辑与current_size统计、system.filesystem_cache_log日志列等也有多处修正与完善。
5. 系统表与监控增强
system.processes新增is_all_data_sent列,用于判断结果数据是否全部发送完毕(实现见 src/Storages/System/StorageSystemProcesses.cpp),内部测试的 hardening 检查也基于它;system.session_log补齐缺失的枚举值;- 修复
system.opentelemetry_span_log的attribute.values别名错误; - 修复 S3 读取耗时指标计算错误;
- 新增
S3Requests指标与更多 fs cache 相关 CurrentMetrics/异步指标。
6. 安全与访问控制
- 新增行级安全策略(row policy)新模式:可在主配置中启用,允许没有 permissive 行策略的用户读取行(默认为拒绝),方便在多租户场景下放开只读用户;
- 新增
user_defined_path配置项,用于指定用户自定义对象(如 UDF)的路径。
7. 数据摄取与格式
- Protobuf 支持通过 Google wrappers 检测 Nullable;
file、s3、url表函数解析出错时显示具体出错文件名;- 修复
file表函数在clickhouse-local中允许使用文件描述符; s3Cluster表函数支持集群宏(cluster macro);Object类型支持Object(Nullable(...))转换,JSON 复杂嵌套数组插入Object列的多个问题被修复;- 元组元素允许以数字开头命名。
8. 兼容性
- 新增
compatibility_ignore_auto_increment_in_create_table选项:创建表时忽略列声明中的AUTO_INCREMENT关键字,简化 MySQL 迁移; - 新增 Keeper 集群配置的
keeper_server.host_checks_enabled开关,用于启用/禁用主机名健全性检查; - Keeper 支持强制恢复(force recovery),允许在无 quorum 的情况下重新配置集群。
9. 其他改进
- 1970-01-01 之前、带整点/半点时区的日期时间转换函数在溢出时饱和到零而非报错;
- MySQLHandler 中取消查询时保留合理的 query id;
- 向其他服务器发送异常时附带额外诊断信息(如适用);
- 哈希函数支持
Array(Tuple(..))参数; - 若以 log level "test" 运行 clickhouse-server 会发出警告(该级别仅用于测试,会产生不可避免的性能退化);
- Play UI:单行多列结果垂直展示、Nullable 数字右对齐、超长查询输入框可扩展不遮挡数据区;
- 默认关闭
log_query_threads设置——它记录参与查询执行的每个线程统计;引入异步读取后线程 id 数量过大,写入query_thread_log过于沉重,故改为默认关闭。
五、Bug Fix:官方稳定版用户可见问题修复
1. 第二类修复(用户可见错误行为)
- 修复
ilike()在 FixedString 列上可能返回错误结果(匹配过少)的问题; - 修复
optimize_skip_unused_shards_rewrite_in的隐式类型转换; - 为子查询启用
enable_global_with_statement; - 修复 WindowView
WATCH EVENTS因非空 Chunk 被终止、多列 WindowView schema 转换、hop window 触发、删除未触发数据后max_fired_watermark更新、删除源表卡死等问题; - 修复分布式查询
LIMIT BY的 "Cannot create column of type Set" 错误; - 修复
OvercommitRatio比较溢出与日志死锁; - Kafka 生产端不再需要
group.id(此前控制台会出现Configuration property group.id is a consumer property and will be ignored by this producer instance警告); - 修复 MySQL 数据库引擎对
binary(0)数据类型的兼容; - 修复含
Object列表的 mutation 执行(UPDATE/DELETE的 WHERE 暂不允许使用 Object 子列); - 修复
Nullable(String)到Nullable(Bool/IPv4/IPv6)的转换; - 修复
system.opentelemetry_span_log属性别名错误。
2. 第一类修复(官方 stable 版本中的用户可见问题)
- 修复
substring函数在 offset/length 为负常量时的范围错误; - 修复 Arrow 输出未编译 ZSTD 支持的问题;
- 修复 compact parts 中嵌套列的
ALTER DROP COLUMN; - 修复特殊算子内使用别名时的解析错误(如
SELECT substring('test' AS t, 1, 1)); - 修复 JOIN 断言与 nullptr 解引用、JOIN WHERE 字面量错误;
- 修复
ClickHouseDictionarySource含标量子查询时的字典重载、外部字典主机名无法解析导致启动失败; - 修复
s3Clusterschema 推断导致部分数据未读取; - 修复
clickhouse-benchmarkJSON 报告结果; - 修复客户端收到未知服务器包、可执行 UDF 在 GROUP BY 中的使用;
- 修复 Keeper 集群 hostname 检查与压缩日志损坏问题;
- 修复
flatten_nested = 0建表重启后被拍平、INTERPOLATE与 MergeTree 的 Missing column、宽 parts 的垂直合并与Object类型合并; - 移除有 bug 的
groupArraySorted函数; - 修复 Hedged 请求超时(发送远程查询后连接挂起导致无限等待)、
max_parallel_replicas != 1时外部表数据发送; - 修复
quantileTDigest中 inf 值问题; - 修复 LowCardinality→ArrowDictionary 索引类型非 UInt8 时的非法输出;
- 修复
optimize_aggregation_in_order=1与*Array聚合函数组合、INSERT SELECT隐式聚合性能退化; - 修复缓存
current_size计数、远程 fs 缓存读取中的错误类型转换与低基数异步读取问题。
六、Build / Testing / Packaging:构建与发布改进
- clickhouse-keeper 静态链接:
x86_64架构的clickhouse-keeper现使用 musl 静态链接,不依赖任何系统库,部署时无需处理动态库依赖; - PowerPC64LE 支持:ClickHouse 为
PowerPC64LE架构提供构建产物,可通过通用安装脚本与直链下载;同时将 PowerPC 代码生成限制在 Power8 以获得更好兼容性; - CMake 健壮性:更稳健地处理未知架构、简化 cmake 构建脚本;
- CI 流程:性能对比在报告出错时直接判失败、大部分构建任务使用 depth=1 检出、统一
force tests标签、minizip-ng 升级至可修复 dangling remote ref 问题的版本; - 测试修复:修复 rabbitmq liveness 检查的错误 import、简化性能测试以使其更易使用。
七、升级建议与总结
综合 22.5 的变更,升级前建议关注以下几点:
- 监控指标变化:
SelectedRows/SelectedBytes不再包含后台任务量,若告警依赖这两个指标需重新校准; - FIPS 环境:如果运行在 FIPS 模式下,22.5 已内置合规 BoringSSL;
log_query_threads默认关闭:需要线程级统计的用户需显式开启;- 利用新能力:GROUPING SETS、
SYSTEM SYNC DATABASE REPLICA、Prometheus 输出、MySQLDump 输入、wyHash64 与 nth_value 等新特性可直接提升查询表达力与迁移效率; - 内存策略:内存 overcommit 默认开启,对内存受限环境是利好的"软着陆"策略,但建议结合 src/Common/MemoryTracker.h 相关参数评估。
22.5 延续了 ClickHouse "高性能 + 高可用 + 易迁移" 的演进主线:一方面通过 JIT、并行 Join、聚合与哈希函数优化持续压榨性能,另一方面通过 GROUPING SETS、MySQLDump、MeiliSearch 等能力降低了从 MySQL/Hive/全文检索系统迁入的门槛,是 2022 年值得关注的一个功能密集型稳定版本。
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考