- Published on
InfluxDB 3 Core 的「72 小时限制」其实是 432 个文件的限制 — Parquet 重写留下的账单
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 「72 小时」这个数字究竟是什么
- 432 是从哪儿来的
- 从硬限制到软限制
- 72 小时是最理想的情况
- 触发限制之后会发生什么
- 那调高上限不就行了吗 — 对象存储的账单
- 答案是 compactor,而 compactor 是收费的
- 2026 年真正的新闻 — Parquet 之上的新引擎
- 预览版值多少 — 老实说
- 那么,什么时候用、什么时候不该用
- 结语
- 参考资料
引言 — 「72 小时」这个数字究竟是什么
凡是评估过 InfluxDB 3 的人,大概都在某处见过这句话 — 「开源版 Core 只能查询最近 72 小时」。社区论坛上、对比文章里都反复出现。
可翻遍源码,却找不到任何计数 72 小时的代码。检查时间范围的逻辑本身根本不存在。真正存在的只有一件事 — 单次查询能触碰的 Parquet 文件数上限。默认值是 432。
这个区分不是文字游戏。限制的单位是文件而不是时间,这一事实解释了这个限制的性质、它何时会更早触发,以及它当初为什么会存在。而这个答案直接指向一个架构决策 — 把存储层押在了 Parquet 上。
本文要读的就是这张账单。整个时序数据库阵营的全景图,我已经在时序数据库深度对比一文中梳理过,这里只深入挖 InfluxDB 3 这一个点。
432 是从哪儿来的
InfluxDB 3 Core 以 MIT 或 Apache-2.0 协议开源在 influxdata/influxdb 仓库里。所以这不是一个需要猜的问题,直接去读就行。
先看标志位定义。influxdb3/src/commands/serve.rs 里的注释这样写:
/// Set the limit for number of parquet files allowed in a query. Defaults
/// to 432 which is about 3 days worth of files using default settings.
/// This number can be increased to allow more files to be queried, but
/// query performance will likely suffer, RAM usage will spike, and the
/// process might be OOM killed as a result. It would be better to specify
/// smaller time ranges if possible in a query.
#[clap(long = "query-file-limit", env = "INFLUXDB3_QUERY_FILE_LIMIT", action)]
pub query_file_limit: Option<usize>,
这个标志位是 Option 类型,不传值的话,默认值就写死在 influxdb3_write/src/write_buffer/mod.rs 里。以发布标签 v3.10.0 为准,是第 437 行。
query_file_limit: query_file_limit.unwrap_or(432),
那 432 为什么是 432 呢?InfluxDB 3 按时间戳把进来的数据装进固定长度的时间块,并把每块落盘为一个 Parquet 文件。这个块叫 gen1,长度由 --gen1-duration 决定。
/// Duration that the Parquet files get arranged into. The data timestamps will land each
/// row into a file of this duration. 1m, 5m, and 10m are supported. These are known as
/// "generation 1" files. The compactor in Pro can compact these into larger and longer
/// generations.
#[clap(long = "gen1-duration", env = "INFLUXDB3_GEN1_DURATION", default_value = "10m", action)]
pub gen1_duration: Gen1Duration,
默认值是 10 分钟,允许的取值只有 1 分钟、5 分钟、10 分钟这三档。代码里也是如此,Duration::from_secs(600) 是默认值,解析器只接受 60、300、600 秒。
于是数学就对上了。
gen1 时间块 = 10 分钟
每小时文件数 = 60 / 10 = 6 个
每天文件数 = 6 x 24 = 144 个
432 / 144 = 3 天 = 72 小时
也就是说,72 小时不是输入值,而是派生值。它只是把 432 这个文件数上限乘以 10 分钟这个块长度后得到的结果。官方文档说的也是同一件事 — 用默认值 432 和默认的 gen1-duration 10 分钟,一次查询最多能触及 72 小时的数据。
那把 --gen1-duration 调低到 1 分钟会怎样?432 个文件就变成了 432 分钟,约 7.2 小时。同样是 432,可查询范围却缩小到十分之一。这就是「这是文件限制而不是时间限制」这句话的实际含义。
从硬限制到软限制
最初这确实是个真正的时间限制。早期的 InfluxDB 3 Core 在查询和写入两侧都硬性限制在 72 小时,取消这个限制的是 PR #25890。按 GitHub API 拉到的元数据,它在 2025 年 1 月 21 日开出,1 月 23 日合并。
这个 PR 的说明几乎就是本文的摘要。
- 移除 Core 的 72 小时查询/写入限制
- 改为按默认的 Parquet 文件数量限制查询。之所以选 432,是因为在 gen1 时间块的默认设置下,它大致对应 72 小时
- 这个文件上限可以调高,但帮助文本和错误信息会警告查询性能将会下降
- 遇到这个报错时,尽量使用更窄的时间范围
而最后一句才是关键 — 移除硬限制,换成一个用户可以自行选择、以性能为代价的软限制;如果承受不了这个代价,就被引导去用内置 compactor 的 Enterprise 版。
这段话写于 2025 年 1 月,到 2026 年 7 月依然原样有效。
72 小时是最理想的情况
从这里开始,实务中的人往往会感到意外。文档说 432 乘以 10 分钟得出 72 小时,但紧接着又附上一条限定条件 — 这取决于给定的 10 分钟块里的数据是否都在同一时间被摄入,实际数字可能比这更短。
原因看一眼生成文件路径的代码就清楚了,位于 influxdb3_write/src/paths.rs。
{host_prefix}/dbs/{db_id}/{table_id}/{YYYY-MM-DD}/{HH-MM}/{wal_seq}.parquet
到目录这一层为止都是 gen1 时间块(日期 + 时·分),而文件名是 WAL 序列号。这意味着同一个 10 分钟块内,可能并存多个由不同 WAL 序列生成的文件。如果同一个 10 分钟内发生了两次快照,就会产生两个文件,这个块就要吃掉 432 个文件预算里的 2 个。
在默认设置下,这种情况被调校得不太容易发生。--wal-flush-interval 默认是 1 秒,--wal-snapshot-size 默认是 600,按标志位说明,这两者相乘决定了快照的节奏。600 秒正好是 10 分钟,所以快照节奏恰好与 gen1 块长度对齐,结果是每块一个文件。
问题在于数据不会总是这么规矩地到达。回填到过去的时间点,或者迟到的数据落进了一个已经被快照过的块,都会给那个块多加一个文件。这样一来,432 这个预算就会比 72 小时更快耗尽。回填越频繁的工作负载,「72 小时」这个数字就越来越像谎言。
归纳一下:72 小时不是保证,而是一个上限 — 而且这个上限也只在数据严格按实时到达时才成立。
触发限制之后会发生什么
强制执行点在 write_buffer/mod.rs 里统计文件列表的地方。逻辑本身三行就能概括 — 收集该表中通过过滤条件的 Parquet 文件,如果数量超过上限,就抛出一个 DataFusion 错误并终止。
这里有三点值得指出。
第一,这个限制是按表计算的。 因为获取文件列表时会按数据库 ID 和表 ID 过滤,所以 432 不是「整次查询」的预算,而是「查询触碰的这一张表」的预算。
第二,这是计划阶段的拒绝,而不是扫描之后的失败。 它不会先打开文件再变慢,而是先数文件数量,然后直接拒绝执行。也没有部分结果。
第三,错误信息里有一个小 bug。 传给消息占位符的格式化参数,实际上并不是查询本来打算扫描的文件数,而是上限值本身。
format!(
"Query would scan {} Parquet files, exceeding the file limit. \
InfluxDB 3 Core caps file access to prevent performance degradation \
and memory issues. Use a narrower time range, or increase the limit \
with --query-file-limit ...",
self.query_file_limit
)
只有一个参数,而它的值就是上限。所以即便一次会扫描 5,000 个文件的查询,消息也永远是「Query would scan 432 Parquet files」。这条报错根本不会告诉你到底超了多少。对于想估算该把时间范围缩小多少的人来说,这个行为相当不友好。
消息正文并不建议调高上限,而是引导你使用更窄的时间范围,或者转向带有 compactor 的 Enterprise。错误信息里甚至还写着非商业/家庭使用免费,商业评估有免费试用期这样的话。
那调高上限不就行了吗 — 对象存储的账单
把 --query-file-limit 调到 4320,查询 30 天的数据不行吗?可以。但文档列出了副作用。
- 读取更多 Parquet 文件的查询性能会下降
- 内存占用增加
influxdb3进程可能因 OOM 被杀- 如果用的是对象存储,访问数据需要大量 GET 请求 — 用文档自己的说法是每个文件最多 2 次
最后一条是那个安静的杀手。哪怕只用默认的 432,一次查询也最多要发 864 次 GET。把上限调到 4320,仪表盘每自动刷新一次,一次查询最多就要发 8,640 次 GET。S3 的 GET 定价是按每 1,000 次请求计费的,所以这在成为性能问题之前,先是个账单问题。
而这正是 Parquet 设计的直接后果。读一个 Parquet 文件,得先读页脚(footer)的元数据,再读需要的 row group。文件越小、数量越多,元数据往返相对于真实数据的比例就越差。每 10 分钟落一个文件的结构,正好就是那种最糟糕的形态。
文档给出的建议很坦率 — 维持默认设置,查询更短的时间范围。如果涉及超过一小时的查询需要更长的范围或更快的性能,就用 Enterprise。
答案是 compactor,而 compactor 是收费的
小而不可变的文件不断堆积,这个问题的正解是压实(compaction) — 把小文件重写成覆盖更长时间范围的大文件,减少文件数量,按 series 排序,并附加索引。
InfluxDB 3 有这个 compactor。但只在 Enterprise 里有。
这一点在文档结构本身就能看出来。启动专用 compactor 节点的 --mode=compact 配置示例,在文档源码里就位于 Enterprise 专属的区块中,mode 这个选项本身也被归类为 Enterprise 专属项。Core 里压根就没有 compactor 节点这个概念。
Core 文档开篇第一句话,就是在委婉地说明这一点 — InfluxDB 3 Core 是一款为实时和近期数据设计并优化的开源时序数据库。这与其说是营销措辞,不如说是架构描述。没有 compactor,就只能看到近期数据,所以才被定位为面向近期数据。
同样的结构在别处也重复出现。Core 的 README 引以为傲的性能数字 — last-value 查询低于 10 毫秒、distinct 元数据低于 30 毫秒 — 并不是通用查询性能,而是 last-value 缓存和 distinct value 缓存这两个缓存的性能。这两个缓存是架在内存上的独立结构。之所以要单独造,正是因为在 Parquet 布局之上,「这个 series 的最后一个值」这类点查询快不起来;需要缓存这件事本身,就是存储层在这类问题上力不从心的证据。
2026 年,删除也成了 compactor 的活儿
2026 年 6 月 17 日发布的 v3.10.0,给 Enterprise 带来了行级删除。但它的实现方式,把本文的主题原样又重复了一遍。
据文档所说,删除是异步的。执行 influxdb3 delete rows 会记录一条删除请求并存进对象存储,等 compactor 下一次重写那部分数据时,请求才会被应用。 默认情况下,删除请求发出后最多可能要等 24 小时才生效,这个延迟可以用 --pt-row-delete-min-age 标志调整。文档说得很明白 — 因为删除是在压实过程中应用的,所以在 compactor 处理这条请求之前,这些行仍然可以被查询到,不要以为命令一返回,行就立刻消失了。
谓词只支持标签的等值比较,无法按字段值删除。
而 v3.10.0 文档的已知问题列表里有这么一条 — 行删除被报告为「完成」之后,尚未压实的摄入尾部里的行仍可能存活,并持续出现在查询结果中。变通方法是,等那部分数据被压实之后,重新发出一次删除请求并核对行数。
这不是一个偶然的 bug,而是设计的逻辑推论。如果删除是靠重写文件来实现的,那么在还没被重写的区域里,删除就根本不存在。因为 Parquet 文件是不可变的。
Core 那边呢?在官方文档仓库里,Core 的管理文档列表里根本没有 delete-data.md,它只属于 Enterprise。没有 compactor,也就没有删除行的办法。如果你在开源 Core 里存放的是那种会收到 GDPR 删除请求的数据,现在就值得核实一下这件事。
2026 年真正的新闻 — Parquet 之上的新引擎
以上是背景,接下来才是今年的消息。
在 2026 年 4 月 2 日发布的 v3.9.0 中,InfluxData 开放了一个性能升级预览版(beta)。用 --use-pacha-tree 标志打开,按发布说明自己的措辞,它包含一种新的列式文件格式(.pt 文件)、带混合查询模式的自动 Parquet 迁移、面向宽表 I/O 的列族(column family),以及有边界的压实。
概括起来,InfluxDB 正在部分地走出 Parquet。InfluxDB 3 的首个正式发布版 v3.0.0 是在 2025 年 4 月 16 日,所以这大约是 GA 一年之后的事。
原因不需要猜测,厂商自己写得明明白白。预览版文档「Why these upgrades」一节开篇就是 — 现有的 InfluxDB 3 存储层使用 Apache Parquet,为分析型工作负载做了优化。 而那些跑高基数、宽 schema、查询密集型工作负载的客户,需要更好的单 series 查询性能、更可预测的资源占用,以及让 InfluxDB v1 和 v2 大受欢迎的那种 schema 灵活性。
最后这句话值得再读一遍。这是一句关于夺回「曾让 v1 和 v2 受欢迎的东西」的话。v1、v2 的存储引擎正是专为时序打造的 TSM,而 3.0 抛弃掉的,恰恰就是那个 TSM。
看 .pt 格式的说明,这种回归就更明显了。据文档所述,文件内的数据按列族键、series 键、时间戳的顺序排序,并根据数据特性采用按类型区分的压缩算法 — 时间戳用 delta-delta RLE,浮点数用 Gorilla 编码,低基数字符串用字典编码,等等。
这里 Gorilla 特别显眼。直接查一下 Parquet 格式规范的编码列表,会发现全部内容就是 PLAIN、字典(PLAIN_DICTIONARY / RLE_DICTIONARY)、RLE、BIT_PACKED(已弃用)、DELTA_BINARY_PACKED、DELTA_LENGTH_BYTE_ARRAY、DELTA_BYTE_ARRAY、BYTE_STREAM_SPLIT。浮点数的 XOR 系列编码,也就是 Gorilla,并不在这份规范里。要用时序 float 压缩的标准手法,就只能走出 Parquet 之外。
关于压缩率,文档写的是通常能达到 5 到 20 倍。但这是厂商自己的说法,文档没说这是基于哪个数据集、哪种 schema、和什么基准比较的。甚至连比较对象是 Parquet 还是原始 line protocol 都没写明,所以不该拿这个数字来做容量规划。同样,「高选择性时序查询响应为个位数毫秒」这句话,也没有公开测量条件。把它当作目标值来读会更安全。
列族是通过在 line protocol 字段名里使用 :: 分隔符来指定的。第一个 :: 之前的部分是族名,未指定的字段会按每 100 个一组,被自动归入生成的族。这种结构意味着,在宽表里只查询特定字段时,其余族的数据块可以完全不用读。
压实方式也变了。据文档所述,压实后的数据按 24 小时的 UTC 窗口组织,Gen0 文件从 L1 逐级推进到 L4,并在一个按字节计的内存预算(默认是系统 RAM 的一半)之内持续在后台运行。
预览版值多少 — 老实说
在为此兴奋之前,我先原样把文档自己附上的警告搬过来。
它是 beta,禁止用于生产。 文档的警告框明确写着,这个预览版是以 beta 形式提供给 Enterprise 试用及付费客户的,随时可能变更,而且不得用于生产工作负载。 文档钉死了这一点 — 只能用在预发布(staging)和测试环境。
v3.10.0 的已知问题里包含数据丢失。 在开启 --use-pacha-tree 的情况下运行 2 个或更多分片(--pt-shard-count),可能触发数据丢失和启动死锁。变通办法是把分片数保持为 1。也就是说,目前这个预览版实际上只能以单分片方式使用。
降级不等于撤销。 influxdb3 downgrade-to-parquet 会更新目录(catalog),并把对象存储里所有的 .pt 文件删掉。按文档的说法,这甚至会删掉升级之后写入的数据,只有升级之前就已存在的原始 Parquet 文件会被保留。 打开预览版、攒了一个月的数据之后又改变主意,那一个月的数据就没了。
3.10 的升级本身是单向的。 第一次启动 3.10 时,磁盘上的目录会自动从 v2 迁移到 v3,此后 3.9.x 及更早版本的二进制文件将无法针对同一份集群数据启动。发布说明建议事先备份目录目录和目录检查点(catalog checkpoint)对象,并说恢复那个对象是回滚到 3.9.x 的唯一办法。如果开启过 --use-pacha-tree,用 .pt 格式写入的数据同样是 3.9.x 读不了的。
而所有这一切都是 Enterprise 专属。 Core 拿不到 .pt、列族,也拿不到有边界的压实,Core 继续活在那 432 个文件的预算之内。
把发布说明连起来读,Core 和 Enterprise 之间的温差就赤裸裸地显现出来。2026 年 6 月 25 日的 v3.9.6,以及 6 月 30 日的 v3.10.2 和 v3.9.7 — 这三个版本的 Core 条目全部是同一句话:一个维护性发布,只包含构建和依赖更新,用户感知不到任何变化。同一天的 Enterprise 条目里,则有压实去重的修复、以及处理引擎(processing engine)触发器取消的修复。
那么,什么时候用、什么时候不该用
Core 够用的情况。 Core 不是个坏产品,它做到了自己承诺要做的事。
- 查询范围是最近几小时到几天的实时仪表盘和告警
- 边缘/IoT 采集点上做缓冲、再向上游转发的用途
- 以最新值查询为核心的工作负载 — last-value 缓存正是为此而存在的
- 数据只以实时方式到达、没有回填的管道
Core 不够用的情况。 只要符合下面任意一条,开源版 Core 就不是答案。这不是靠调参就能跨过去的那种墙。
- 需要定期查询超过几天的历史区间 — 调高文件上限,GET 请求数和内存占用会一起涨上去
- 回填或迟到数据频繁发生 — 文件会在同一个 gen1 块里重叠堆积,72 小时会崩得更快
- 需要删除行 — Core 没有办法做到
- 有理由要把
--gen1-duration缩到 1 分钟 — 可查询范围会降到 7.2 小时左右
值得一试 Enterprise 预览版的情况。 文档推荐给高基数、宽表;跨时间范围的频繁回填;需要低延迟的查询密集型访问;列会动态出现的稀疏 schema;以及内存/CPU 用量上限很关键的环境。但请先在预发布环境、以单分片、用可以丢弃的数据开始。
该去看别的方案的情况。 如果长期保留、删除、历史查询这几件事都要在开源里全部做到,那从一开始 InfluxDB 3 Core 可能就不是正确选项。无论是转向 Postgres 扩展还是列式存储,比较的起点我都整理在时序数据库深度对比一文里了。
结语
归纳一下。「InfluxDB 3 Core 有 72 小时限制」这句话是个不准确的概括。更准确的说法是:单次查询在单张表上能扫描的 Parquet 文件默认被限制为 432 个,乘以默认的 gen1 块长度 10 分钟得出 72 小时,而这 72 小时本身也只是数据严格按实时到达时的最理想数值。
这个限制不是随意的功能限制。在 Parquet 之上搭建时序数据库,必然会产生大量小而不可变的文件,而清理它们的唯一办法就是压实(compaction),InfluxData 把那个 compactor 划成了商业边界。开源版 Core 原样继承了这个决策的所有后果 — 文件上限、每文件最多 2 次 GET,以及删除功能的缺失。
而到了 2026 年,这套架构的账单也送到了厂商自己手上。Parquet 是为分析型工作负载优化的,因此在单 series 查询和宽 schema 上力有不逮 — 这不是我说的,这写在 InfluxData 自己的预览版文档里。结果就是 .pt,其中带着 Parquet 规范里没有的 Gorilla 编码 — 正是 v1 和 v2 的 TSM 曾经拥有的那种手法。
如果说这里有什么教训,大概是关于选择通用格式这件事本身的性质。选了 Arrow、Parquet 和 DataFusion,InfluxDB 3 几乎白得了 SQL、Flight SQL 和整个生态工具链,这是实打实的收获。但通用格式是为通用情形优化的,你的工作负载离那个平均值越远,早晚要在某处把差价补上。对 InfluxDB 3 来说,这笔差价的账单,一部分开给了一个叫 compactor 的付费组件,另一部分开给了 GA 一年之后重新造出一套自有文件格式这件事。
在评估技术选型时,我建议把这个问题放在发布说明的功能列表之前先看一眼 — 这套系统根本性的约束是什么,而解开这个约束的组件,站在哪一边的许可证之后。
参考资料
- influxdata/influxdb — InfluxDB 3 Core 源码(MIT / Apache-2.0)
- PR #25890 — feat: loosen 72 hour query/write restriction(2025-01-23 合并)
- InfluxDB 3 配置选项文档 — query-file-limit / gen1-duration
- InfluxDB 3 Core / Enterprise 发布说明 — v3.9.0(2026-04-02)、v3.10.0(2026-06-17)、v3.10.3(2026-07-07)
- InfluxDB 3 Enterprise — Performance upgrade preview(PachaTree / .pt)
- InfluxDB 3 Enterprise — Delete data(行级删除与 compactor)
- Apache Parquet 格式规范 — 编码列表
- 时序数据库深度对比 — 各阵营全景图(相关文章)