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 | 数据文件最近一次修改时间。 |
blockId | StarRocks 在拆分数据文件时为每个 block 分配的 ID。该 ID 在一个文件下是唯一的,非全局唯一。 |
假如该查询命中了 [1 MB, 2 MB) 这个 block,那么:
- StarRocks 检查缓存中是否存在该 block。
- 如存在,则从缓存中读取该 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。
| false |
datacache_disk_path | 磁盘路径。支持添加多个路径,多个路径之间使用分号(;) 隔开。建议 BE 机器有几个磁盘即添加几个路径。BE 进程启动时会自动创建配置的磁盘缓存目录(当父目录不存在时创建失败)。 | ${STARROCKS_HOME}/datacache |
datacache_meta_path | Block 的元数据存储目录,一般无需配置。 | ${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