
本文字数:18333;估计阅读时间:46分钟
作者: Tom Schreiber
本文在公众号【ClickHouseInc】首发

引言
大约一年前,我们参与了 Gunnar Morling 发起的 “十亿行挑战 (One Billion Row Challenge)”,测试了 10 亿行文本文件的聚合性能。
现在,我们发起了一个新的挑战:“十亿文档 JSON 挑战 (One Billion Documents JSON Challenge)”,旨在评估数据库在存储和聚合大规模半结构化 JSON 文档数据集时的表现。
为了解决这一问题,我们需要一个高效的 JSON 方案。最近,我们详细介绍了如何从零开始为 ClickHouse 构建一个全新的强大 JSON 数据类型,并展示了它为何成为列式存储的最佳 JSON 方案。
在本文中,我们将 ClickHouse 的 JSON 实现与其他支持 JSON 的数据存储方案进行对比,测试结果可能会让你大吃一惊。
为了完成这项测试,我们开发了 JSONBench——一个完全可复现的基准测试工具,它能够将相同的 JSON 数据集加载到五个主流的、具备原生 JSON 支持的数据存储系统中:
-
ClickHouse
-
MongoDB
-
Elasticsearch
-
DuckDB
-
PostgreSQL
JSONBench 评估了 JSON 数据集的存储占用情况,以及五种常见分析查询的执行性能。
以下是 10 亿 JSON 文档存储与查询的基准测试结果预览。
-
ClickHouse 的存储效率比 MongoDB 高 40%,聚合查询速度快 2500 倍。

-
ClickHouse 仅需 Elasticsearch 一半的存储空间,聚合查询速度快 10 倍。

-
ClickHouse 的磁盘占用仅为 DuckDB 的五分之一,在分析查询上的速度快 9000 倍。

-
ClickHouse 仅使用 PostgreSQL 六分之一的磁盘空间,在分析查询上的速度同样快 9000 倍。

-
最后值得一提的是,即使采用相同的压缩算法,ClickHouse 存储 JSON 文档的空间利用率仍比将其作为压缩文件存储提高 20%。

接下来的内容将首先介绍我们的测试 JSON 数据集,并简要概述每个基准测试对象的 JSON 处理能力(如果你对技术细节不感兴趣,可以跳过这部分)。接着,我们将介绍基准测试的环境配置、查询以及测试方法。最后,我们将展示并深入分析测试结果。
JSON 数据集 —— 10 亿条 Bluesky 事件
我们的测试 JSON 数据集来自对 Bluesky 社交媒体平台的事件流抓取。在另一篇文章中,我们详细介绍了如何使用 Bluesky API 获取这些数据。这些数据天然以 JSON 文档格式存储,每个文档代表一个特定的 Bluesky 事件(例如帖子、点赞、转发等)。
基准测试会将以下 8 个 Bluesky 事件数据集(下图中的 ① 到 ⑧)加载到每个基准测试候选系统中:

评测系统
本节概述了基准测试系统的 JSON 处理能力、数据压缩技术以及查询加速特性(例如索引和缓存)。理解这些技术细节有助于澄清各系统的配置方式,以确保基准测试的公平性和准确性。
如果你对这些技术细节不感兴趣,可以跳过本节。
ClickHouse
ClickHouse 是一款列式分析数据库。在本文中,我们将对其进行基准测试,与其他候选系统对比,以突出其在处理 JSON 数据方面的卓越能力。
JSON 支持
我们最近为 ClickHouse 构建了一个强大的新 JSON 数据类型,具备真正的列式存储,支持在不统一类型的情况下动态变化数据结构,并能以极快的速度查询特定的 JSON 路径。
JSON 存储
ClickHouse 将每个唯一 JSON 路径的值存储为原生列,从而实现高效的数据压缩,并且——正如本文所展示的——在查询性能方面保持与经典数据类型相同的高水平:

上图概述了每个唯一 JSON 路径的值如何存储在磁盘上的独立(高度压缩的)列文件中(位于数据分片中)。这些列可以独立访问,最小化查询时对无关 JSON 路径的 I/O 操作。
数据排序与压缩
ClickHouse 的 JSON 类型允许将 JSON 路径用作主键列。这确保了写入的 JSON 文档在存储时,在每个数据分片内部按照这些路径的值排序。此外,ClickHouse 生成稀疏主索引,以自动加速基于这些主键列的查询:

将 JSON 子列作为主键列可以更好地将相似数据组织到同一列文件中,从而提高数据压缩率,前提是主键列按照基数递增的顺序排列。磁盘上的数据排序还可以避免查询时的重新排序,并在查询的搜索排序与物理数据排序匹配时实现短路优化。
灵活的压缩选项
在默认情况下,ClickHouse 在自托管版本中对每个数据列文件分别应用 lz4 压缩,而在 ClickHouse Cloud 中使用 zstd 压缩。
此外,还可以在 CREATE TABLE 语句中为单独的列定义压缩编解码器。ClickHouse 支持通用、高级和加密编解码器,并允许进行级联压缩。
对于 JSON 类型,ClickHouse 目前支持对整个 JSON 字段定义编解码器(例如,在此将默认的 lz4 编解码器更改为 zstd)。未来,我们计划支持针对单个 JSON 路径指定编解码器。
灵活的 JSON 格式选项
ClickHouse 支持 20 多种不同的 JSON 格式用于数据导入和查询结果的输出。
查询处理
由于 ClickHouse 在基准测试中的卓越性能,我们在此简要介绍其 JSON 数据查询的处理方式。
正如前文所述,ClickHouse 以类似传统数据类型(例如整数)的方式存储每个唯一 JSON 路径的值,使其能够对 JSON 数据进行高效聚合。
ClickHouse 专为互联网规模的分析而构建,能够利用所有可用资源,通过完全并行化的 90 多种内置聚合函数高效筛选和聚合数据。这一方法可以通过 avg(平均值)聚合函数来说明:

上图展示了 ClickHouse ① 处理引用 JSON 路径 c.a 和 c.b 的 avg 聚合查询的方式。ClickHouse 仅使用对应的数据列 a.bin 和 b.bin,在单台服务器上的 N 个 CPU 核心上并行处理 N 个不重叠的数据范围。这些数据范围独立于分组键,并动态平衡以优化工作负载分布。这种并行化处理得益于部分聚合状态的使用。
在 ClickHouse 的基准测试中,我们还跟踪物理执行计划,以深入分析这一并行化方法。例如,在这里,你可以看到 ClickHouse 在测试机器(32 核 CPU)上如何使用 32 条并行执行通道处理基准查询 ① 的全数据集聚合。
多节点并行化
虽然本次基准测试仅关注单节点性能,但需要补充说明的是,如果聚合查询的 JSON 源数据分布在多个节点上(以表分片的形式),ClickHouse 能够无缝地在所有节点的所有 CPU 核心上并行执行聚合函数:

缓存
在查询执行过程中,ClickHouse 依赖多个内置缓存,以及操作系统的页面缓存。例如,尽管默认情况下禁用,但 ClickHouse 还提供查询结果缓存。
MongoDB
MongoDB 是最知名的 JSON 数据库之一。
JSON 支持
MongoDB 以 BSON 文档集合的形式原生存储所有数据,其中 BSON 是 JSON 文档的二进制表示形式。
JSON 存储
MongoDB 的默认存储引擎 WiredTiger 在磁盘上以 B-

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



