【译】ClickHouse 22.3 LTS 发布

作者:Alexey Milovidov

原文链接:https://clickhouse.com/blog/clickhouse-22-3-lts-released/

新的 ClickHouse 版本 22.3 已准备就绪!这是一个长期支持版本 (LTS) — 在2023 年 3 月之前我们将对其进行安全更新和重要错误修复。 该版本包括来自 86 个贡献者的 1308 个新提交,其中包括 25个新贡献者:

1lann, Anish Bhanwala, Eugene Galkin, HaiBo Li, Hongbin, Jianmei Zhang, LAL2211, Lars Eidnes, Miel Donkers, NikitaEvs, Nir Peled, Robert Schulze, SiderZhang, Varinara, Zhang Xudong, Yong Wang, cwkyaoyao, heleihelei, kashwy, lincion, metahys, rfraposa, shuchaome, tangjiangling, zhangyifan27.

22.3 中的改动主要集中在功能成熟度、安全性和可靠性上。一些实验性功能已准备好用于生产:

ClickHouse Keeper

ClickHouse Keeper 是ZooKeeper 的替代品。它实现了 ZooKeeper 的协议和数据模型;并无缝替代 ZooKeeper(最高版本 3.5)供ClickHouse和其他应用使用。它可作为独立组件运行,也可以嵌入到 clickhouse-server 中。

我们为它通过持续集成的 Jepsen 测试而感到自豪。这包括对ZooKeeper 的测试和为了提高覆盖率的附加测试。此外,它还通过了 ClickHouse功能和集成测试、压力测试和模糊测试。

从 22.3 版本开始,我们保证它在读写方面都比 ZooKeeper 更快,同时消耗更少的内存,日志和快照的磁盘占用也更低。此外还对对磁盘和网络中的数据进行checksum校验,用避免硬件故障的影响。请求延迟大部分情况下都很低。这得益于Zhang Li StarAlexander Sapin的贡献 。

从 22.3 版开始,ClickHouse Keeper 已经是production ready状态!事实上,它已经在生产环境中使用了半年多,所以你不会是第一个吃螃蟹的人。

ARM 架构支持

64 位 ARM CPU 架构 (AArch64) 在云服务器、笔记本电脑和工作站上变得越来越流行。有想过在网络设备和移动设备上使用 ClickHouse 吗?你是否知道ClickHouse能够在所有这些设备中运行并榨干他们的性能?

我们从 2016 年 2 月开始将 ClickHouse 移植到 AArch64,从那时起我们检查了 13 种不同的 CPU 型号: APM X-Gene; Cavium ThunderX 1, 2; Raspberry Pi; Pinebook; Google Pixel; Apple M1, M1 Max; Huawei Taishan; AWS Graviton 1, 2, 3; Ampere Altra。不同ARM CPU制造商之间的产品存在巨大差异,我们很乐意不断支持它。我们还维护了不同硬件的比较基准的集合

22.3 版对 AArch64 的支持有两个里程碑:

  1. 100% 通过持续集成中的功能测试。
  2. 完全支持何种发布版本:deb、rpm、apk、tgz、single-binary 和 Docker。

Mikhail Shiryaev 的工作使这些成为可能 。从22.3 ClickHouse 版本开始AArch64架构已经是production ready状态!

ClickHouse 针对x86_64指令集架构有很多细致的优化,但对 AArch64架构仅有少数几个优化。尽管如此,ClickHouse + AArch64 在主要云厂商中拥有更好的性价比。

AArch64 上禁用了某些 x86 架构中的特定功能:对Hyperscan的支持,对来自 PMU的硬件指标的支持。编译时也不会包含一些特性,例如 对GRPC API 的支持。我们不建议运行混合架构的ClickHouse集群,尽管目前尚未发现有相关问题。

接下来该期待什么?我们正在支持PowerPC 64 little-endian 和 RISC-V 64 。如果您对其他 CPU 架构感兴趣,请告诉我们。

S3 上的VFS

对 S3 上的 VFS 的实验性支持存在了大约两年:

  • 用于数据导入和导出的 s3 函数。 By Vladimir Chebotarev
  • 磁盘、卷和存储策略。By Igor MineevAlexander Sapin
  • 自动和用户触发的磁盘间data parts的移动。By Vladimir Chebotarev
  • 虚拟文件系统接口 。By Alexander Burmak
  • 在 s3 上实现 VFS 。By Pavel KovalenkoGrigory PervakovAnton Ivashkin
  • 异步读取 。By Alexey MilovidovKseniia SumarokovaAlexander Sapin
  • 功能测试的覆盖率、正确性和可靠性。By Alexander Sapin

从 22.3 开始,我们保证在 s3 之上的最大查询性能和每次提交的持续测试。对 s3 上的 MergeTree 和 ReplicatedMergeTree Engine的支持已准备好投入生产。

尽管一些新功能还不是production ready的:“零副本复制”(如果一个区域中设置了多个副本,则确保实际只有一个数据副本)和本地缓存。我们已针对 AWS S3 和 Minio 进行了测试。已知问题可通过GCP查看。

安全功能

Eungenue 提供了 X.509 客户端证书的身份验证 。由Heena Bansal贡献的两个功能 :

  • 禁用用户明文密码或无密码的开关;
  • 过滤 MySQL、PostgreSQL联邦查询中的传出连接。

更多模糊测试

我们相信 模糊 测试是构建可靠软件的绝对需要。而fuzzing的主要原则是:应该有更多的fuzzing。因此,我们在 ClickHouse CI 中有许多模糊测试方法:LLVM 的 libFuzzer、基于 AST 的查询模糊测试、Ad-hoc SQL 函数模糊测试、线程调度顺序随机化、时区随机化、SQLancer(逻辑模糊测试)、压力测试和 Jepsen 测试。

但这还不够。

从 22.3 版本开始,我们 在功能测试中添加了查询开关的随机化。因此,我们可以在不同开关的各种组合下运行测试。

我们还添加了向后兼容性的自动化测试。它会尝试创建所有可能的数据库、表和字典,然后安装以前的 ClickHouse 版本并检查能否成功启动。这使我们能够了解新功能是否向后兼容。

我们非常热衷于测试,因此我们决定为测试添加自动化测试。每当有人提交bugfix时,我们会自动检查它是否包含测试,并确认这些测试是否会在之前的版本中失败。

半结构化数据

好的,我花了您 15 分钟的时间来讲述安全性、可靠性、合规性、透明度……但 乐趣在哪里?

在 22.3 版本中,我们有一个新的实验特性——支持动态子列和半结构化数据!

假设您有一堆 JSON 并且想要分析它 - 没有指定表中的数据类型。并且您希望您的表自动适应架构更改,自动添加新列。以及所有具有层次对象和深度嵌套的数组!现在它是可能的,它就像魔术一样工作。

让我通过一个使用 GitHub API 的示例来演示它。

我从 GH Explorer获得了按星数排序的 GitHub 存储库列表。然后我开始使用以下脚本从 GitHub API 查询最受欢迎的存储库的元数据:

cut -f1 repos.tsv | while read repo; do 
    [ -f "${repo/\//@}.json" ] && continue; 
    echo $repo; 
    while true; 
        do curl -sS -u 'alexey-milovidov:***' "https://api.github.com/repos/${repo}" > ${repo/\//@}.json; 
        grep -F 'API rate limit exceeded for user' ${repo/\//@}.json && sleep 60 || break; 
    done;
done

数据包含repo的语言、star数量、fork数量和subscriber数量等信息。 返回的JSON对象中存在大量冗余信息。而现在我可以将它们全部加载到 ClickHouse 中,而无需关心数据类型和嵌套级别:

SET allow_experimental_object_type = 1;
CREATE TABLE repositories (data JSON) ENGINE = MergeTree;
INSERT INTO repositories FROM INFILE '*.json' FORMAT JSONAsObject;

然后计算一些有趣的东西:

SELECT
    1 + rowNumberInAllBlocks() AS n,
    *
FROM
(
    SELECT DISTINCT
        data.full_name,
        data.stargazers_count,
        data.license.name
    FROM repositories
    WHERE data.language = 'C++'
    ORDER BY data.stargazers_count DESC
)
LIMIT 20

Query id: 175ccd7e-d689-493b-b0bc-57a584f09590

┌──n─┬─data.full_name────────────────────────┬─data.stargazers_count─┬─data.license.name───────────────────────┐
│  1 │ tensorflow/tensorflow                 │                164038 │ Apache License 2.0                      │
│  2 │ electron/electron                     │                101133 │ MIT License                             │
│  3 │ microsoft/terminal                    │                 82110 │ MIT License                             │
│  4 │ opencv/opencv                         │                 60681 │ Other                                   │
│  5 │ apple/swift                           │                 59164 │ Apache License 2.0                      │
│  6 │ pytorch/pytorch                       │                 55051 │ Other                                   │
│  7 │ protocolbuffers/protobuf              │                 53704 │ Other                                   │
│  8 │ x64dbg/x64dbg                         │                 38319 │ GNU General Public License v3.0         │
│  9 │ BVLC/caffe                            │                 32370 │ Other                                   │
│ 10 │ nlohmann/json                         │                 29284 │ MIT License                             │
│ 11 │ google/leveldb                        │                 28826 │ BSD 3-Clause "New" or "Revised" License │
│ 12 │ topjohnwu/Magisk                      │                 24989 │ GNU General Public License v3.0         │
│ 13 │ microsoft/calculator                  │                 24045 │ MIT License                             │
│ 14 │ CMU-Perceptual-Computing-Lab/openpose │                 23777 │ Other                                   │
│ 15 │ huihut/interview                      │                 23490 │ Other                                   │
│ 16 │ cmderdev/cmder                        │                 23453 │ MIT License                             │
│ 17 │ ClickHouse/ClickHouse                 │                 22957 │ Apache License 2.0                      │
│ 18 │ facebook/rocksdb                      │                 22198 │ Other                                   │
│ 19 │ mongodb/mongo                         │                 21409 │ Other                                   │
│ 20 │ apache/incubator-mxnet                │                 19938 │ Apache License 2.0                      │
└────┴───────────────────────────────────────┴───────────────────────┴─────────────────────────────────────────┘

因此,ClickHouse 是 GitHub 上第 17 个最受欢迎的 C++ repo,还不赖!

让我解释一下动态子列的工作原理:

我们新增了一种叫做 JSON 数据类型。您也可以将其写为 Object('JSON'). 该数据类型可以解析任意 JSON,其中包含动态子列。您可以在同一个表中同时拥有常规类型和JSON类型。动态子列在插入时创建,并像常规列一样以列存方式储存,因此查询这些子列与常规列一样有效。数据类型是自动推断的,并且可以在后台合并期间进行转换,因此您可以在不同的 INSERT 中拥有不同的schema。查询使用更自然的语法,例如 data.license.name[1] ,而不用 JSONExtractString(data, 'license', 'name', 1) or JSON_QUERY(data, '$.license.name[1]')

此功能由 Anton Popov实现。它在 22.3 版中可供预览。我们将很高兴听到您的反馈。

性能改进

ClickHouse 中有很多性能优化,每个新版本的 ClickHouse 都变得更快更强.

Maksim Kita 通过排序优化将插入 MergeTree 表的性能提高了两倍(如果排序键由多个数字列组成)。

如果您在 WHERE IN 中有包含大量列表的 SELECT 查询,这些查询在 ClickHouse 22.3 中的运行速度将提高 3 倍:

SELECT * FROM table
WHERE key IN (111, 222, ... a megabyte of something)

远程文件系统的本地缓存

当 ClickHouse 从本地文件系统读取数据时,数据被 OS 缓存在page cache中。在具有多通道内存的服务器上从多个线程读取page cache的典型性能约为 50 GB/秒,因此热查询会非常快。

但是,如果 ClickHouse 正在从远程文件系统读取,则操作系统不会感知到这些读取,且无法使用page cache。因此,我们需要在 ClickHouse 中拥有自己的page cahce。从 22.3 版本开始,ClickHouse 具有远程文件系统的缓存,由 Ksenia Sumarokova实现。它 极大地提高了性能。缓存同时使用本地磁盘和 RAM。

还有什么?

阅读 22.3 版本的 完整变更日志 并浏览 路线图