Data Cache
了解 Data Cache 的核心原理以及如何通过 Data Cache 加速数据查询。
Data Cache 用于缓存内表和外部表的数据。该功能从 v3.3.0 开始默认启用。从 v4.0 开始,内存缓存和磁盘缓存已统一集成到 Data Cache 系统中,以便于管理。
Data Cache 由两个组件组成:Page Cache(内存缓存)和 Block Cache(磁盘缓存)。
Page Cache 原理
作为内存缓存,Page Cache 负责存储解压后的内表和外部表的数据页。这些页的大小不固定。目前,Page Cache 支持缓存以下类型的数据:
- 内表的数据页和索引页
- 外部表数据文件的页脚信息
- 外部表的部分解压数据页
Page Cache 目前使用 LRU(最近最少使用)策略进行数据淘汰。
Block Cache 原理
Block Cache 是基于磁盘的缓存,其主要功能是将数据文件(来自外部表,以及存算分离集群中的存算分离表)缓存到本地磁盘。这减少了远程数据访问延迟并提高查询效率。每个数据块的大小是固定的。
背景和价值
在数据湖分析和存算分离表场景中,StarRocks 作为一个 OLAP 查询引擎,需要扫描存储在 HDFS 或对象存储中的数据文件(以下简称“远端存储系统”)。此过程面临两个主要性能瓶颈:
- 查询需要读取的文件越多,远程 I/O 开销越大。
- 在即席查询场景中,频繁访问相同数据导致冗余的远程 I/O 消耗。
为了解决这些问题,Block Cache 功能在 v2.5 中引入。它根据特定策略将远端存储系统中的原始数据拆分为多个块,并将这些块缓存到 BE 或 CN 节点的本地磁盘中。通过避免重复检索远程数据,显著提高了对热点数据的查询性能。
场景
- 使用 External Catalog(除 JDBC Catalog 外)查询远端存储系统中的数据。
- 在存算分离集群中查询存算分离表。
核心机制
数据拆分和缓存单元
当系统缓存远程文件时,它根据配置的策略将原始文件拆分为大小相等的块。一个块是最小的缓存单元,其大小是可定制的。
示例:
如果块大小配置为 1 MB,当在 Amazon S3 上查询一个 128 MB 的 Parquet 文件时,该文件将被拆分为 128 个连续的块(即 [0, 1 MB),[1 MB, 2 MB),...,[127 MB, 128 MB))。
每个块被分配一个全局唯一的缓存标识符(缓存键),由以下三部分组成:
hash(filename) + fileModificationTime + blockId
| 组件 | 描述 |
|---|---|
| filename | 数据文件的名称。 |
| fileModificationTime | 数据文件的最后修改时间。 |
| blockId | 数据文件拆分时分配给每个块的 ID。此 ID 在单个文件内是唯一的,但不是全局唯一的。 |
缓存命中和读取过程
假设查询命中了范围 [1 MB, 2 MB) 内的块,Block Cache 的处理流程如下:
- 系统首先检查本地 BE 节点的 Block Cache 中是否存在该块(通过匹配缓存键)。
- 如果找到(缓存命中),则直接从本地磁盘读取该块。
- 如果未找到(缓存未命中),则从远程存储中获取该块,并同步到本地 BE 节点的 Block Cache 以供后续查询重用。
缓存介质
Block Cache 使用 BE 或 CN 节点的本地磁盘作为其存储介质,缓存加速效果与磁盘性能直接相关:
- 建议使用高性能本地磁盘(例如 NVMe 磁盘)以最小化缓存读写延迟。
- 如果磁盘性能不佳,可以增加磁盘数量以实现负载均衡并减少单个磁盘的 I/O 压力。
缓存替换策略
Block Cache 支持两种数据缓存和淘汰策略:LRU 和 SLRU(分段 LRU)。
LRU
LRU 策略基于“最近最少使用”原则——淘汰最长时间未被访问的块。实现简单,适用于访问模式稳定的场景。
SLRU
SLRU 策略将缓存空间分为淘汰段和保护段,均遵循 LRU 规则:
- 数据首次访问时进入淘汰段。
- 淘汰段中的数据再次访问时提升到保护段。
- 从保护段淘汰的数据回退到淘汰段,而从淘汰段淘汰的数据直接从缓存中移除。
SLRU 策略可以有效抵御突发的稀疏流量,防止“仅访问一次的临时数据”直接淘汰保护段中的热点数据。它比 LRU 提供更好的稳定性。
启用和配置 Data Cache
Data Cache 默认启用,由 BE 配置项 datacache_enable 控制(默认值:true)。Page Cache 和 Block Cache 作为两个独立的组件,也默认启用。将 datacache_enable 设置为 false 将禁用 Data Cache,即同时禁用 Page Cache 和 Block Cache。
您还可以使 用不同的 BE 配置项分别激活或停用 Page Cache 和 Block Cache。
- Page Cache(默认启用)由
disable_storage_page_cache控制(默认值:false)。 - Block Cache(默认启用)由
block_cache_enable控制(默认值:true)。
您还可以使用以下 BE 配置来设置 Data Cache 的最大内存和磁盘使用限制,以防止资源占用过多:
datacache_mem_size:设置 Data Cache 的最大内存使用限制(用于存储 Page Cache 中的数据)。datacache_disk_size:设置 Data Cache 的最大磁盘使用限制(用于存储 Block Cache 中的数据)。
填充 Block Cache
填充规则
从 v3.3.2 开始,为了提高 Block Cache 的缓存命中率,系统根据以下规则填充 Block Cache:
- 对于非
SELECT的语句,例如ANALYZE TABLE和INSERT INTO SELECT,不会填充缓存。 - 查询扫描表的所有分区时不会填充缓存。然而,如果表只有一个分区,则默认执行填充。
- 查询扫描表的所有列时不会填充缓存。然而,如果表只有一列,则默认执行填充。
- 对于非 Hive、Paimon、Delta Lake、Hudi 或 Iceberg 的表,不会填充缓存。