缓存加速
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 | - |
| 有缓存(重复查询) | ~300ns | 49-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 | ~1KB | 1,000 | ~1MB |
总缓存开销:典型 ~6MB,最大 ~10MB。