跳到主要内容

缓存加速

IEDB 内置多层缓存机制,优化重复查询性能,尤其对仪表盘和监控场景效果显著。

缓存层级

IEDB 使用三层互补缓存协同工作:

缓存TTL用途性能提升
SQL 转换缓存60s缓存 SQL → read_parquet() 转换49-104x 加速
分区路径缓存60s缓存分区裁剪结果50-100ms/查询
Glob 缓存30s缓存文件系统 glob 结果5-10ms/查询

SQL 转换缓存

当执行查询时:

SELECT * FROM mydb.cpu WHERE time > now() - INTERVAL '1 hour'

IEDB 将表引用 mydb.cpu 转换为 DuckDB read_parquet() 调用:

SELECT * FROM read_parquet('s3://bucket/mydb/cpu/**/*.parquet')
WHERE time > now() - INTERVAL '1 hour'

这个字符串转换使用正则匹配,每次查询都会触发。SQL 转换缓存存储结果,使重复查询跳过此处理。

性能影响

场景耗时加速比
无缓存(首次查询)13-37μs-
有缓存(重复查询)~300ns49-104x

适用场景

  • 仪表盘刷新:每 30s-5min 执行相同查询
  • 监控告警:重复阈值检查
  • API 集成:客户端轮询相同指标
  • 多用户仪表盘:跨用户共享查询

缓存行为

  • Key:原始 SQL 字符串的 SHA256 哈希
  • TTL:60 秒
  • 最大条目:10,000 条查询
  • 淘汰策略:优先淘汰过期条目,其次淘汰最旧条目

分区路径缓存

SQL 转换后,IEDB 通过基于时间的分区裁剪优化存储路径。此缓存存储优化后的路径。

示例

带时间过滤的查询:

SELECT * FROM mydb.cpu WHERE time > 1704067200000000
  • 无缓存:扫描分区元数据以找到相关目录
  • 有缓存:返回预先计算的路径 s3://bucket/mydb/cpu/2024/01/**/*.parquet

性能影响

在拥有大量分区的大型数据集上,每次查询节省 50-100ms。


Glob 缓存

确定分区路径后,IEDB 使用文件系统 glob 查找匹配的 Parquet 文件。Glob 缓存存储这些文件列表。

性能影响

通过避免重复文件系统操作,每次查询节省 5-10ms。


S3 文件缓存

对于 S3/MinIO/Azure 存储后端,IEDB 支持 DuckDB 的 cache_httpfs 扩展,在本地缓存远程 Parquet 文件:

[storage]
backend = "s3"
s3_bucket = "iedb-production"
s3_region = "cn-hangzhou"

# 开启 S3 文件缓存
cache_httpfs_enabled = true
cache_httpfs_dir = "./data/cache"
cache_httpfs_max_size = "10GB"

首次查询从 S3 拉取文件并缓存到本地,后续查询直接读取本地缓存,大幅降低延迟和带宽成本。


最佳实践

1. 保持查询文本一致

缓存 Key 基于精确的 SQL 文本。以下被视为不同的缓存条目:

-- 不同的缓存条目
SELECT * FROM mydb.cpu WHERE time > 1704067200000000
SELECT * FROM mydb.cpu WHERE time > 1704067200000000 -- 多一个空格
select * from mydb.cpu where time > 1704067200000000 -- 小写

统一查询格式以提高缓存命中率。

2. 使用相对时间范围

仪表盘查询使用相对时间:

-- 推荐:每次刷新使用相同查询文本
SELECT * FROM mydb.cpu WHERE time > now() - INTERVAL '1 hour'

-- 不推荐:每次使用不同时间戳
SELECT * FROM mydb.cpu WHERE time > 1704067200000000

3. 监控命中率

健康仪表盘应达到 60-80%+ 缓存命中率。低命中率可能表明:

  • 查询种类过多
  • 查询文本不一致
  • TTL 相对刷新间隔过短

缓存失效

缓存基于 TTL 自动过期。以下情况触发手动失效:

  • 新数据摄入:影响相关 measurement 的分区/Glob 缓存
  • 压缩运行:文件路径变化时清除分区/Glob 缓存
  • 集群文件清单更新:节点间同步后清除本地缓存

SQL 转换缓存不受数据变化影响,因为转换逻辑不依赖数据内容。


内存占用

缓存单项大小最大条目最大内存
SQL 转换~500 字节10,000~5MB
分区路径~200 字节1,000~200KB
Glob~1KB1,000~1MB

总缓存开销:典型 ~6MB,最大 ~10MB。