跳到主要内容
版本:Latest-3.2

Data Cache

本文介绍 Data Cache 的原理,以及如何开启 Data Cache 加速外部数据查询。

在数据湖分析场景中,StarRocks 作为 OLAP 查询引擎需要扫描 HDFS 或对象存储(下文简称为“外部存储系统”)上的数据文件。查询实际读取的文件数量越多,I/O 开销也就越大。此外,在即席查询 (ad-hoc) 场景中,如果频繁访问相同数据,还会带来重复的 I/O 开销。

为了进一步提升该场景下的查询性能,StarRocks 2.5 版本开始提供 Data Cache 功能。通过将外部存储系统的原始数据按照一定策略切分成多个 block 后,缓存至 StarRocks 的本地 BE 节点,从而避免重复的远端数据拉取开销,实现热点数据查询分析性能的进一步提升。Data Cache 仅在使用外部表(不含 JDBC 外部表)和使用 External Catalog 查询外部存储系统中的数据时生效,在查询 StarRocks 原生表时不生效。

原理

StarRocks 将远端存储文件缓存至本地 BE 节点时,会将原始文件按照一定策略切分为相等大小的 block。block 是数据缓存的最小单元,大小可配置。当配置 block 大小为 1 MB 时,如果查询 Amazon S3 上一个 128 MB 的 Parquet 文件,StarRocks 会按照 1 MB 的步长,将该文件拆分成相等的 128 个 block,即 [0, 1 MB)、[1 MB, 2 MB)、[2 MB, 3 MB) ... [127 MB, 128 MB),并为每个 block 分配一个全局唯一 ID,即 cache key。Cache key 由三部分组成。

hash(filename) + fileModificationTime + blockId

说明如下。

组成项说明
filename数据文件名称。
fileModificationTime数据文件最近一次修改时间。
blockIdStarRocks 在拆分数据文件时为每个 block 分配的 ID。该 ID 在一个文件下是唯一的,非全局唯一。

假如该查询命中了 [1 MB, 2 MB) 这个 block,那么:

  1. StarRocks 检查缓存中是否存在该 block。
  2. 如存在,则从缓存中读取该 block;如不存在,则从 Amazon S3 远端读取该 block 并将其缓存在 BE 上。

开启 Data Cache 后,StarRocks 会缓存从外部存储系统读取的数据文件。如不希望缓存某些数据,可进行如下设置。

SET enable_populate_datacache = false;

关于 enable_populate_datacache 的更多信息,参见 系统变量

缓存介质

StarRocks 以 BE 节点的内存和磁盘作为缓存的存储介质,支持全内存缓存或者内存+磁盘的两级缓存。 注意,当使用磁盘作为缓存介质时,缓存加速效果和磁盘本身性能直接相关,建议使用高性能本地磁盘(如本地 NVMe 盘)进行数据缓存。如果磁盘本身性能一般,也可通过增加多块盘来减少单盘 I/O 压力。

缓存淘汰机制

在 Data Cache 中,StarRocks 采用 LRU (least recently used) 策略来缓存和淘汰数据,大致如下:

  • 优先从内存读取数据,如果在内存中没有找到再从磁盘上读取。从磁盘上读取的数据,会尝试加载到内存中。
  • 从内存中淘汰的数据,会尝试写入磁盘;从磁盘上淘汰的数据,会被废弃。

开启 Data Cache

Data Cache 默认关闭。如要启用,则需要在 FE 和 BE 中同时进行如下配置。

FE 配置

支持使用以下方式在 FE 中开启 Data Cache:

  • 按需在单个会话中开启 Data Cache。

    SET enable_scan_datacache = true;
  • 为当前所有会话开启全局 Data Cache。

    SET GLOBAL enable_scan_datacache = true;

BE 配置

在每个 BE 的 conf/be.conf 文件中增加如下参数。添加后,需重启每个 BE 让配置生效。

参数说明默认值
datacache_enable是否启用 Data Cache。
  • true:启用。
  • false:不启用。
false
datacache_disk_path磁盘路径。支持添加多个路径,多个路径之间使用分号(;) 隔开。建议 BE 机器有几个磁盘即添加几个路径。BE 进程启动时会自动创建配置的磁盘缓存目录(当父目录不存在时创建失败)。${STARROCKS_HOME}/datacache
datacache_meta_pathBlock 的元数据存储目录,一般无需配置。${STARROCKS_HOME}/datacache
datacache_mem_size内存缓存数据量的上限,可设为比例上限(如 "10%")或物理上限(如 "10G", "21474836480"等)。推荐将该参数值设置不低于 10 GB。10%
datacache_disk_size单个磁盘缓存数据量的上限,可设为比例上限(如 "80%")或物理上限(如 "2T, "500G"等)。举例:在 datacache_disk_path 中配置了 2 个磁盘,并设置 datacache_disk_size 参数值为 21474836480,即 20 GB,那么最多可缓存 40 GB 的磁盘数据。0 表示仅使用内存作为缓存介质,不使用磁盘。

示例如下:

# 开启 Data Cache。
datacache_enable = true

# 设置磁盘路径,假设 BE 机器有两块磁盘。
datacache_disk_path = /home/disk1/sr/dla_cache_data/;/home/disk2/sr/dla_cache_data/

# 设置内存缓存数据量的上限为 2 GB。
datacache_mem_size = 2147483648

# 设置单个磁盘缓存数据量的上限为 1.2 TB。
datacache_disk_size = 1288490188800

查看 Data Cache 命中情况

您可以在 query profile 里观测当前 query 的 cache 命中情况。观测下述三个指标查看 Data Cache 的命中情况:

  • DataCacheReadBytes:从内存和磁盘中读取的数据量。
  • DataCacheWriteBytes:从外部存储系统加载到内存和磁盘的数据量。
  • BytesRead:总共读取的数据量,包括从内存、磁盘以及外部存储读取的数据量。

示例一:StarRocks 从外部存储系统中读取了大量的数据 (7.65 GB),从内存和磁盘中读取的数据量 (518.73 MB) 较少,即代表 Data Cache 命中较少。

 - Table: lineorder
- DataCacheReadBytes: 518.73 MB
- __MAX_OF_DataCacheReadBytes: 4.73 MB
- __MIN_OF_DataCacheReadBytes: 16.00 KB
- DataCacheReadCounter: 684
- __MAX_OF_DataCacheReadCounter: 4
- __MIN_OF_DataCacheReadCounter: 0
- DataCacheReadTimer: 737.357us
- DataCacheWriteBytes: 7.65 GB
- __MAX_OF_DataCacheWriteBytes: 64.39 MB
- __MIN_OF_DataCacheWriteBytes: 0.00
- DataCacheWriteCounter: 7.887K (7887)
- __MAX_OF_DataCacheWriteCounter: 65
- __MIN_OF_DataCacheWriteCounter: 0
- DataCacheWriteTimer: 23.467ms
- __MAX_OF_DataCacheWriteTimer: 62.280ms
- __MIN_OF_DataCacheWriteTimer: 0ns
- BufferUnplugCount: 15
- __MAX_OF_BufferUnplugCount: 2
- __MIN_OF_BufferUnplugCount: 0
- BytesRead: 7.65 GB
- __MAX_OF_BytesRead: 64.39 MB
- __MIN_OF_BytesRead: 0.00

示例二:StarRocks 从 data cache 读取了 46.08 GB 数据,从外部存储系统直接读取的数据量为 0,即代表 data cache 完全命中。

 Table: lineitem
- DataCacheReadBytes: 46.08 GB
- __MAX_OF_DataCacheReadBytes: 194.99 MB
- __MIN_OF_DataCacheReadBytes: 81.25 MB
- DataCacheReadCounter: 72.237K (72237)
- __MAX_OF_DataCacheReadCounter: 299
- __MIN_OF_DataCacheReadCounter: 118
- DataCacheReadTimer: 856.481ms
- __MAX_OF_DataCacheReadTimer: 1s547ms
- __MIN_OF_DataCacheReadTimer: 261.824ms
- DataCacheWriteBytes: 0.00
- DataCacheWriteCounter: 0
- DataCacheWriteTimer: 0ns
- BufferUnplugCount: 1.231K (1231)
- __MAX_OF_BufferUnplugCount: 81
- __MIN_OF_BufferUnplugCount: 35
- BytesRead: 46.08 GB
- __MAX_OF_BytesRead: 194.99 MB
- __MIN_OF_BytesRead: 81.25 MB