3. InfluxDB 架构解析:存储引擎 TSM、WAL、Cache、Compactor 工作流程
InfluxDB 的存储引擎是其高性能写入与查询能力的核心。它并非直接使用传统的 B+ 树或 LSM-Tree,而是基于 LSM-Tree 思想进行了深度定制,形成了以 TSM (Time-Structured Merge Tree) 为核心的存储架构。该架构主要由四个核心组件构成:Cache、WAL (Write-Ahead Log)、TSM 文件 和 Compactor。理解它们之间的协作流程,是进行数据保留策略配置与查询优化的前提。
3.1 核心组件概述
下表总结了四个核心组件的角色、存储位置与生命周期,帮助建立整体认知。
| 组件 | 角色 | 存储位置 | 生命周期 |
|---|---|---|---|
| Cache | 写入缓冲层,将新写入的数据点按时间与序列组织成内存中的 map | 内存 (RAM) | 从数据写入开始,直到被快照并写入 TSM 文件后释放 |
| WAL | 持久化日志,确保写入数据不丢失,是 Cache 的故障恢复来源 | 磁盘 (WAL 目录) | 持续追加写入,直到对应的 Cache 被成功刷入 TSM 文件后,旧的 WAL 段文件被删除 |
| TSM 文件 | 只读的列式存储文件,是数据最终的持久化格式 | 磁盘 (数据目录) | 由 Compactor 生成,根据保留策略自动删除过期文件 |
| Compactor | 后台合并与压缩引擎,负责将多个小 TSM 文件合并成大文件,并清理过期/删除的数据 | 后台进程 | 周期性运行,持续优化磁盘存储结构 |
设计哲学: InfluxDB 采用“先写内存,后落盘”的策略。Cache 提供高速写入,WAL 保证数据安全,TSM 文件提供高效的只读查询,Compactor 则负责后台的“整理”工作。这种设计使得写入吞吐量极高,同时查询性能在时间范围过滤下表现优异。
3.2 数据写入与持久化工作流程
一条数据点从写入到最终存储在 TSM 文件中,经历了以下标准流程:
- 写入请求到达: 客户端通过 HTTP/HTTPS 或 UDP 协议发送写入请求(Line Protocol 格式)。
- 写入 WAL: 数据首先被序列化并追加写入到当前活跃的 WAL 文件中。这一步是顺序 I/O,速度极快,确保数据在系统崩溃后可以恢复。
- 更新 Cache: 数据同时被写入内存中的 Cache 结构。Cache 按照
measurement + tags + time作为 key 进行组织,便于后续快速合并相同序列的数据。 - 返回成功: 一旦 WAL 写入成功,InfluxDB 立即向客户端返回 204 状态码,表示写入成功。此时数据已安全持久化,但尚未进入查询优化的存储格式。
- Cache 快照: 当 Cache 的大小达到阈值(默认 25MB)或超过一定时间(默认 10 分钟),当前 Cache 会被“冻结”并创建一个快照。同时,一个新的空 Cache 和新的 WAL 段文件开始服务新的写入。
- 写入 TSM 文件: 后台进程将 Cache 快照中的数据排序、去重、压缩,并写入一个新的只读 TSM 文件。写入完成后,对应的 WAL 段文件可以被安全删除。
关键指标: 监控
wal_write_points_ok 和 cache_write_points_ok 可以评估写入健康度。如果 cache_write_points_dropped 持续增长,说明写入速度超过了 Cache 和 TSM 文件的处理能力,需要调整 cache-snapshot-write-cold-duration 或 cache-snapshot-memory-size 参数。
3.3 TSM 文件结构
TSM 文件是 InfluxDB 存储引擎的基石,它是一种列式、只读、压缩的文件格式。一个 TSM 文件内部由四个主要区域组成:
- Header (头部): 文件标识和版本信息。
- Data Blocks (数据块): 存储实际的时间序列数据。每个块包含一个特定序列和时间范围内的数据,并按列(时间戳、field 值)进行压缩存储。常见的压缩算法包括
simple8b(用于整数)、gorilla(用于浮点数)和snappy。 - Index (索引区): 位于数据块之后,用于快速定位某个序列的数据块在文件中的偏移量。索引条目包含
measurement + tags + field key的哈希值、时间范围以及数据块的起始位置和大小。 - Footer (尾部): 指向 Index 区起始位置的指针,用于快速加载索引。
查询优化启示: TSM 文件的列式存储和索引结构,使得 InfluxDB 在查询时能够快速跳过不相关的数据块。查询优化应尽量利用时间范围过滤,因为索引是按时间排序的。避免查询跨度极大的时间范围,这会导致需要扫描大量 TSM 文件的索引和数据块。
3.4 Compactor 工作流程
Compactor 是 InfluxDB 的后台“清道夫”和“整理师”。它持续运行,负责将多个小的 TSM 文件合并成更大的文件,并在此过程中执行数据清理和压缩优化。其工作流程分为两个阶段:
3.4.1 一级合并 (Level 1 Compaction)
- 触发条件: 当 Cache 快照生成的 TSM 文件数量超过阈值(默认 2 个)时触发。
- 操作: 将多个小的、未压缩的 TSM 文件合并成一个稍大的、经过全量压缩的 TSM 文件。此阶段会应用
simple8b、gorilla等压缩算法,显著减少磁盘空间占用。 - 输出: 生成一个或多个 Level 1 的 TSM 文件。
3.4.2 二级合并 (Level 2 Compaction)
- 触发条件: 当 Level 1 的 TSM 文件数量达到阈值(默认 4 个)时触发。
- 操作: 将多个 Level 1 的 TSM 文件合并成一个更大的 Level 2 文件。此阶段还会执行 去重 和 删除标记清理。如果某个数据点被覆盖或删除(通过删除序列或保留策略),其标记会在合并时被物理移除。
- 输出: 生成一个 Level 2 的 TSM 文件。
3.4.3 全量合并 (Full Compaction)
- 触发条件: 当 Level 2 的 TSM 文件数量达到阈值(默认 1 个,且文件大小超过一定值)时触发。
- 操作: 将多个 Level 2 的大文件合并成一个最终的、高度优化的 TSM 文件。这是最高级别的合并,会进行最彻底的压缩和数据清理。
- 输出: 生成一个最终的、只读的 TSM 文件,直到其被保留策略删除。
性能影响: Compaction 是 I/O 和 CPU 密集型操作。在写入负载极高时,如果 Compactor 处理速度跟不上 TSM 文件的生成速度,会导致大量小文件堆积,进而影响查询性能。监控
compactions_failed 和 tsm1_files 指标,可以判断是否需要调整 Compaction 并发度或增加磁盘 I/O 能力。
3.5 数据保留策略与 Compactor 的协作
数据保留策略(Retention Policy, RP)是 InfluxDB 管理数据生命周期的核心机制。它定义了数据在数据库中保留的时长,以及副本数量。RP 与 Compactor 的协作关系如下:
- 自动删除: Compactor 在运行过程中,会检查 TSM 文件中数据的时间戳。如果某个 TSM 文件中的所有数据点的时间戳都早于 RP 定义的
DURATION,该文件会被标记为“可删除”。 - 物理删除时机: 文件的实际物理删除并非立即发生,而是在下一次 Compactor 的“全量合并”或专门的“删除清理”周期中执行。这避免了频繁的磁盘 I/O 操作。
- Shard 生命周期: InfluxDB 将数据按时间划分为 Shard。每个 Shard 对应一个时间范围(如 1 天或 7 天)。当 Shard 的时间范围完全超出 RP 后,整个 Shard 目录及其包含的所有 TSM 文件会被一次性删除,这是最高效的清理方式。
配置建议: 合理设置 Shard 的持续时间 (
SHARD DURATION) 非常重要。如果 Shard 持续时间过长,会导致单个 Shard 内文件过多,增加 Compactor 的合并压力。如果过短,则会产生大量小 Shard,增加元数据管理的开销。一般建议 Shard 持续时间与 RP 时长匹配,例如 RP 为 7 天,Shard 持续时间可设为 1 天。
3.6 查询优化与存储引擎的关联
理解存储引擎的工作流程,可以直接指导查询优化实践:
| 优化方向 | 存储引擎原理关联 | 实践建议 |
|---|---|---|
| 时间范围过滤 | TSM 文件的索引按时间排序,查询时能快速跳过不包含目标时间的数据块。 | 始终在 WHERE 子句中指定精确的 time 范围,避免全表扫描。 |
| 减少序列基数 | 高基数(大量唯一的 tag 组合)会导致 Cache 中 map 膨胀,增加内存压力,并导致 TSM 文件中产生大量小数据块。 | 合理设计 tag 的粒度,避免将高基数数据(如 UUID、时间戳)作为 tag。 |
| 避免频繁删除 | 删除操作不会立即释放磁盘空间,而是通过 Compactor 在合并时进行物理清理。频繁删除会导致 Compactor 负担加重。 | 优先使用 RP 进行自动数据过期管理,而非手动执行 DELETE 语句。 |
| 批量写入 | 批量写入可以减少 WAL 的写入次数和 Cache 的更新频率,提高吞吐量。 | 建议每次写入请求包含数千到数万个数据点,而非逐点写入。 |
总结: InfluxDB 的 TSM 存储引擎是为时序数据量身定做的。它通过 Cache 和 WAL 实现了极高的写入性能,通过 TSM 文件的列式存储和索引实现了高效的只读查询,并通过 Compactor 的后台合并与清理机制,保证了数据的长期存储效率和健康度。掌握这些核心组件的协作原理,是后续章节中配置数据保留策略和进行查询优化的理论基础。