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

简而言之
我们构建了一个面向云对象存储的分布式缓存 —— 一个共享的低延迟缓存层,能够为所有计算节点提供对热点数据的快速访问。
本文将深入讲解其内部原理:过去的热数据是如何缓存的,为何对象存储让事情变得更复杂,以及我们全新架构是如何彻底解决这一难题的。我们还将展示基准测试结果。
→ 分布式缓存目前已开放私密预览注册,点击此处申请试用【https://clickhouse.com/cloud/distributed-cache-waitlist】。
如果热数据始终是热的,会怎样?
想象一下这样一种数据库架构:你可以随意通过更换更强的计算节点来纵向扩展,或者通过增加节点数量来横向扩展,无需担心缓存的热数据会丢失。更进一步,每个节点还能立刻受益于其他节点已经完成的计算任务 —— 不再有冷启动,也无需反复读取存储,更不会有无谓的资源浪费。
听起来像幻想?在如今解耦的云数据库架构中,持续保持热数据的可用性确实是一项挑战。
我们现在为 ClickHouse Cloud 推出分布式缓存,这是一个共享的缓存层,专为解决这一长期难题而设计 —— 即便计算节点在扩容、缩容或迁移时,也能始终将热点数据保留在靠近计算的位置。
接下来我们将回顾 ClickHouse 中缓存机制的演变历程,介绍分布式缓存的工作原理,以及它在性能和弹性方面带来的突破。
最后,我们还会展示它与以往方案的基准对比,包括基于 SSD 的自托管服务器。(提前透露一下:哪怕在冷启动下,我们的表现依然更胜一筹。)
在理解我们为何构建这个分布式缓存之前,我们需要先看清 —— 到底缓存了什么。
什么是热表数据?为什么它很重要?
ClickHouse 内置了几乎所有方面的缓存机制:从 DNS 解析记录、输入文件结构、表的元数据、稀疏主键索引和标记文件,到未压缩的表数据、编译后的表达式、满足查询条件的表数据,甚至完整的查询结果。每一类缓存都在加速查询执行中发挥着重要作用,后续我们也会在其他文章中深入探讨。
本文聚焦于其中影响最深远的一项技术:将热表数据缓存在内存中。
这一机制与 ClickHouse 的分层 I/O 优化紧密结合,后者的核心目标是尽可能减少读取的数据量。一旦这些优化生效,查询引擎只会加载真正需要的数据 —— 也就是热表数据 —— 到内存中进行处理。为了让数据加载速度更快,尤其是在重复查询时,ClickHouse 会在执行前将热表数据缓存到本地内存中,尽可能靠近查询引擎的位置。
为什么这很重要?
因为从内存读取数据的速度远远快于从磁盘读取 —— 差距可能高达百万倍。前者是纳秒级,后者则是毫秒级;前者的吞吐量可以高达 100 GB/s,而后者往往只有几 GB/s。
这些数字我们稍后会具体展开,但首先,先来看看“热表数据”在实际中的含义。
下图展示了一个简化查询在表上的执行过程:

① 查询
一个 SELECT 查询选取列 c1,并通过 WHERE 子句筛选特定的行。
② 所需 granule
ClickHouse 会将表划分为 granule(最小的查询处理单元),默认每个 granule 含有 8,192 行。在本示例中简化为每个 granule 仅包含 4 行。通过索引分析,Granule 3 被识别为可能包含匹配行。
③ ④ 所需列文件与数据块
磁盘中每一列单独存储为一个文件(位于某个数据分片目录中),文件由多个压缩数据块组成,每个块覆盖多个 granule。在本例中,每个块包含 2 个 granule。查询引擎判断需要读取列文件 c1.bin,并定位到其中的第 2 个数据块包含了 Granule 3。因此,该块即为本次查询的热表数据。
那么什么是热表数据?
从技术角度来看,热表数据是指列文件中与本次查询命中 granule 对应的压缩数据块。这些块会从磁盘中读取,并缓存至内存,以加速未来的查询。
ClickHouse 热数据缓存机制的演进
在 ClickHouse 的发展过程中,热表数据的缓存方式经历了三个重要阶段:
-
最初,它使用的是本地磁盘上的操作系统页面缓存。这种方式既简单又高效,但高度依赖于具体机器。
-
在进入云时代后,我们引入了本地文件系统缓存,用以填补对象存储与内存计算之间的性能差距。
-
现在,我们迈出了下一步:将文件系统缓存演变为一个共享的网络服务。全新的分布式缓存保留了原有的缓存逻辑,同时能够为所有计算节点提供服务,实现了热数据访问的一致性、弹性扩展能力以及秒级响应。
下面,我们逐个回顾这三个阶段,看看它们如何一步步引领我们走向分布式缓存架构。
阶段一:本地操作系统页面缓存
在传统的 shared-nothing 架构中,ClickHouse 采用分片方式进行横向扩展,每个服务器仅在本地磁盘中保存并访问属于自己的数据。在这种架构下,ClickHouse 借助操作系统自带的页面缓存机制,自动缓存查询过程中加载的列数据段。
下图动画展示了整个处理流程(点击可全屏查看):

① 查询到达
一个查询抵达 ClickHouse 服务器。服务器会首先分析索引文件,以确定需要读取哪些压缩列块来满足查询条件。
② 数据加载
若所需的数据块尚未被缓存,则会从本地 SSD(例如 NVMe Gen3)读取,并自动缓存在操作系统页面缓存中。
③ 内存处理
缓存中的压缩块以流式方式传输至查询引擎

最低0.47元/天 解锁文章
1013

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



