规模、资源与性能基线
首版以真实百万级 VRP 输入、多来源更新和普通服务器/开发机为目标。本文固定测量对象、预算制定方式和超限行为;已有实现和显式测量运行器;当前默认值的适用范围由下列实际测量限定,不能仅凭配置数值宣称容量、RSS 或吞吐保证。实施与测量证据跟踪见 Issue #4。执行流程见 CI/CD,资源字段见配置。
首版交付容量边界
单来源固定真实输入为 1,016,911 VRP、3,355 ASPA、11,006 provider edges;两数据库在 2 CPU/4 GiB 的受限环境完成解析、索引、提交、重开及恢复,进程峰值分别约 1.48/1.60 GiB。单独查询专项覆盖 100 万 VRP 与 116,385 ASPA 支持。三来源各百万条的初次加载和落盘也已完成,但旧快照、并发更新/查询/导出的组合不能由此推断通过。详细数据、源码版本与共用主机等限制保留在后文。
首版保留现有来源 1200 秒、flush 600 秒、HTTP 服务/SDK/保留期 120/180/600 秒默认值。它们已具备有界失败和取消清理证据,并在相应单项负载下实际执行;三来源百万综合负载已出现超时,因而不承诺该负载在默认配置下完成。资源容量上限、最大配置来源数与采样 RSS 不是同一指标,不自动提高默认内存和截止来掩盖未通过场景。
性能收尾只执行两数据库各一次最大规模单轮任务,报告实际结果并据此限定容量;不重复已通过的梯度、互操作或持续运行。最后两例的提交、配置、结果和未执行范围由 Issue #4 关联,故意扩大实验预算的结果不改变上述默认配置结论。
数据和其他实现的依据
| 依据 | 可使用的事实 | 不能据此推断 |
|---|---|---|
| 本机 2026-10-01 rpki-client 完整导出,来源与 SHA-256 见资料索引 | 105,953,312 bytes;1,016,911 条 ROA,其中 IPv4 781,066、IPv6 235,845;3,355 条 ASPA、11,006 个 provider 项,单条 provider 中位数 2、95 分位数 9、最大 228 | 文件的字节数不是 Python 堆内存;历史输入不作为当前在线可信状态;条数不是去重后的生效索引大小 |
| Routinator 0.15.2 安装说明,2026-10-02 核对 | 上游给出的资源建议为 1 GB 可用内存、4 GB 磁盘;它还承担仓库与证书验证 | Rust RP 的资源建议不能成为本 Python 库的内存上界、实测速度或最低硬件承诺 |
| Routinator 安全公告中的解压内存耗尽案例 | 压缩字节限制不足以约束解析成本;必须限制解压输入并记录共同峰值 | 不把某个历史修复方式原样当成本库格式或协议要求 |
| 实现参考与互操作资料中的 RTRlib、rtrtr、Routinator、rpki-client | 对照增量更新、来源隔离、customer 索引和失效行为;基准比较固定版本、同一数据与功能范围 | 不搬用 C/Rust 吞吐数字;不同草案、信任处理或解释详细度的结果不可直接比较 |
上述真实样本分布在 2026-10-02 从本机原始 JSON 重算,95 分位取排序后索引 floor(0.95×(n−1));摘要保存于忽略的 .local-data/scale-audit/2026-10-02/summary.json。大型数据不进入 wheel 或常规 CI。CI 使用可分发固定向量及有种子、可重建的合成分布;扩展到更大规模的数据明确标为合成,不修改历史样本的时间冒充新数据。
工作负载档位
| 档位 | 输入与用途 |
|---|---|
| 日常正确性 | 小型独立向量覆盖完整协议、合并、期限、热配置和错误分支;不用于容量结论 |
| 单来源现实规模 | 上述约 102 万 ROA、3,355 ASPA 的固定输入;测读取、解析、构建、全量替换、期限更新和两数据库恢复 |
| 常见冗余部署 | 3 个来源,各约 100 万 VRP;分别构造 90% 和 100% 重合,以及优先/备用组;原始支持约 300 万,即使生效集合只有约 100 万也完整计费 |
| 增长与边界 | 逐步增加至每来源 500 万、总支持 1,000 万的现有防护上限;ASPA 单独采用 1 万和 10 万 customer 的合成增长场景,保留 provider 长尾并另外测试协议极限 |
| 更新压力 | 0、1、100、10,000 条增删;多个来源同时全量同步;大量不同过期点;增加/移除/替换来源同时保留 4 个旧版本并落盘 |
| 查询压力 | ROV 覆盖/无覆盖/AS0,ASPA 不同路径长度与 provider 长尾;简要和详细模式、批次、遍历、diff、HTTP 并发及慢订阅者 |
计数分开记录原始载荷、支持记录、去重索引项和 ASPA provider 边,不能只报 customer 数掩盖一个大 provider 集合。路径长度包含常见短路径以及配置边界,不把全网路由表导入本库形成额外 RIB。
预算初值和准入
测量优先使用两个工程档位:2 核/4 GiB 的受限环境、4 核/8 GiB 的参考环境,存储原规划为本机 SSD。它们是基于上述百万级输入和常见冗余部署选取的测量条件,不是来自上游的硬件结论,也不是用户必须购买的配置。每种 OS/架构记录实际 CPU、可用内存和文件系统;无法获得完全相同硬件时不直接比较绝对耗时。
2026-10-02 的 Linux 规模实验在共享 Intel Xeon E5-2680 v4 主机上以 CPU affinity、真实 cgroup 内存上限及禁用组内 swap 执行。文件系统为 ext4,控制器暴露 MR9361-8i RAID 逻辑盘;没有取得底层物理介质的证明,不能把这些结果标为 SSD 测量,也不能据此推断物理盘为机械硬盘。报告保存实际条件;既有热缓存和跟踪系统调用的实验分别说明,不能与冷磁盘或独占机器混为一谈。
以单来源在受限环境、三来源在参考环境为首轮优化目标,同时测内存模式、SQLite、DuckDB。记录进程启动基线和增量 RSS/PSS(平台提供时)、旧状态、输入缓冲、解析对象、候选索引、持久化 pending 及驱动缓存的峰值。给宿主及系统保留至少约一半环境内存作为初始规划余量;超出时报告目标未满足,优化或调整公开容量,不通过交换分区、缩小数据或漏掉旧快照掩盖峰值。这个规划余量不是运行时可强制保证的 Python 堆限额。
首版默认同时最多 2 个重型构建,全部来源暂存 wire/input 合计最多 512 MiB;超过并发额度前排队,不先把整份 JSON 读入无预算内存。等待者有界且使用调用/协议已有截止时间。来源管理默认最多 16 个配置来源,配置候选最多 1 个,退休中工作继续占用构建与暂存额度。设置更多来源须显式提高限制并验证预算。这些默认值保留了已验证的有界接纳、取消与释放行为;单来源百万及三来源初次加载已有规模证据,但不保证 16 个大型来源同时工作或三来源综合并发的容量。
已准入的来源发布按组协调完整索引构建:同组一次执行一个来源的完整构建,取得组名额后重新读取当前状态,避免两个来源先同时构建再因版本冲突丢弃重做。相同原始输入的索引复用和不同组的来源不受此组等待限制;到期、健康重选、撤销与配置变更继续走原有维护准入,不取得组名额。组等待者仍占全局构建及暂存预算:HTTP 组等待计入原 request_timeout,RTR End of Data 发布和文件来源的组等待没有硬性截止;组登记只保留持有者和等待者。来源迁组先释放旧组再重新检查,不同时持有两个组;取消、退休或关闭不提前释放仍在运行的受管理线程。紧急维护仍按原准入顺序选择可中断候选,可能等待其线程结束。不可重连 RTR 流仍遵守一次性交付边界。
JSON 解压输入与 RTR 暂存按字节计数,解析对象、索引和数据库驱动还会放大内存;max_total_records 等上限不等于 RSS 上限。所有构建共用准入器,包括首次加载、到期重算、恢复和配置变更;查询、服务导出另有有界并发。公平调度不能让大来源永久占住额度;容量不足时不接纳部分状态,保留旧有效视图至原期限,并记录拒绝/排队原因。容量等待不能阻止移除来源、处理到期或必要清理,必要时取消未提交候选释放预算。
来源候选按 FIFO 排队,维护构建在有界队列中优先;队列已满时可拒绝一个尚未准入的来源候选,给维护腾出队列位置。纯期限推进、自然 failback 与普通连接健康重选使用不抢占的维护票,避免密集到期或健康波动反复取消大输入;健康变化仍立即更新状态并要求重选,候选提交按最新健康状态决定组。撤销、配置和时钟信任变化可抢占尚未提交的来源事务,已入队的紧急维护优先于软维护;队列被软票占满时,紧急请求在等待票位前仍触发抢占,不逐出软票或超过队列上限。中断后仍等线程及清理结束才归还真实工作和暂存额度。候选跨过时间或健康发布版本时复用原始输入不变的组,依据最新已发布快照重新选择组及计算完整端点差分;原始锚点和期限不变。JSON 后续轮询与可重连 RTR 会话按原调度继续;不可重连的既有流遵守一次性交付边界。取消不构成绕过内存预算或强制终止用户阻塞代码的手段。
RTR 查询结束后的状态报告不继续占用来源候选票;必要撤销重新取得不可被候选抢占回调取消的维护票。撤销仍计入构建并发数,不绕过全局准入,也不提前释放尚在运行的线程。
同一来源已被完整撤销后,重连和重复错误携带的不可用能力只作为连接状态观察,不重新申请抢占性撤销额度或产生重复撤销快照。真正的协议降级仍删除适用的载荷;新的有效 EOD 接纳后,后续再次失去信任仍须完整撤销。错误来源不能仅凭重复报告中断其他来源的正常候选。
全部构建槽被占用时(包括已准入的同组等待者),查询触发的时效推进可能等待当前来源工作结束;已有固定快照仍逐次拒绝过期数据,不能用旧授权回答。HTTP 沿用原 request_timeout;RTR 查询的准入与接收保持原 query_timeout,但 End of Data 后的发布(包括组等待)没有硬性截止。本地文件或宿主自定义阻塞 reader 同样没有新增硬性执行期限,调用方可取消等待,但不可中断的受管理线程及资源仍须真正退出。SQLite 共享读取者的数据库头构建与本地时效校准分别串行,并共同受其 max_concurrent_builds 限制:默认两个槽允许两者并行,显式一个槽安全排队。
SQLite 同时测数据库、WAL 和临时文件,DuckDB 同时测数据库、临时空间和驱动缓存;全量事务替换只有在上述场景的写入量与延迟可接受时才作为发布实现。磁盘预算以实测完整状态、事务峰值、WAL/checkpoint 和安全余量推导,不从 JSON 文件大小直接乘一个未验证常数。自定义后端的隐藏内存和磁盘占用必须由适配器说明。
性能验收与优化空间
每轮报告全量/增量耗时,ROV/ASPA 简要及详细查询的 p50/p95/p99,事件循环延迟,事件传播与积压,配置提交及新来源就绪时间,持久化/恢复,取消请求到停止接纳、线程退出和资源释放的各段时间,以及共同峰值内存和写入量。原始记录、种子、依赖及提交版本可复现;仅测纯函数不能证明异步服务响应性。
首版必须有前缀覆盖和 customer 索引,不允许每条普通查询扫描全表。索引布局、结构共享、批量变更和到期队列可按基准选择;不预先绑定 C/Rust、特定 trie 或更多运行依赖。小增量、仅续期和来源高度重合场景必须揭示全表复制、重复摘要、重复落盘的成本。资源上限附近明确拒绝是可验收行为,达到上限仍维持某个 QPS 尚无承诺。
完整索引构建可在同一来源内复用相邻记录共有的不可变来源支持值。只在实际支持起止时间和上游标签均相同时复用,来源 ID 与生成时间由该次来源输入固定;每个来源只暂存最近一个值,不建立随记录数增长的额外驻留表。原始行、来源期限和旧快照保持不变,内容相等不代表可以刷新授权寿命。此优化减少重复对象,不能单独作为完整规模或内存容量的验收证据。
期限推进需要修改前缀索引时,浅拷贝快照拥有的字典,再替换受影响的不可变记录元组;已发布快照的索引不被修改。浅拷贝减少逐键查找的开销,但仍按索引大小分配字典,不能据此宣称到期处理具有常数成本。
取得稳定基线后,在对应 Issue 和基准配置中固定回退阈值、超时及发布默认值,并同步本文。未获得数据前不填写虚构的 QPS、毫秒延迟或“百万级只需若干 MB”。性能门槛不能通过降低协议、时效、来源隔离或固定快照一致性达成。
持久化测量运行器
scripts/benchmark_persistence.py 为原生 Linux /proc 环境提供可复现的单来源同步后端测量。每次运行使用新的输出目录和子进程;CPU affinity、RSS 采样终止阈值与墙钟超时通过参数显式设置。RSS watchdog 不等于 cgroup 的瞬时内存硬上限,也不表示整机只有该容量。其他目标平台仍按兼容矩阵另行验证。
uv run --locked --isolated --no-default-groups --extra sqlite --extra duckdb --python 3.11 \
python scripts/benchmark_persistence.py --backend sqlite --rows 10000 --seed 20261002 \
--cpus 2 --max-rss-mib 4096 --timeout 1800 \
--output .local-data/performance/sqlite-10000
uv run --locked --isolated --no-default-groups --extra sqlite --extra duckdb --python 3.11 \
python scripts/benchmark_persistence.py --backend duckdb \
--input .local-data/rpki-client/2026-10-01T151848Z/vrps.json \
--cpus 2 --max-rss-mib 4096 --timeout 1800 \
--output .local-data/performance/duckdb-production
合成数据使用固定种子、唯一规范前缀、约 77% IPv4、少量 AS0 及可重建的 ASPA provider 分布。真实输入默认必须匹配资料索引中的完整文件 SHA-256,并核对原始载荷和 provider 边数;数据按原生成时刻作显式离线评价。运行器分别记录读取与解析或生成、索引、流式规范摘要、提交、保留原快照的读取、关闭后重开读取及恢复索引。报告同时区分原始支持和生效索引数量,完整比对恢复记录、回执与摘要,并检查采样查询结果。
输出目录中的 report.json 保存最终结果、逐阶段时间与进程 RSS 高水位、采样 RSS/PSS/Swap 峰值、数据库/WAL/临时文件观测峰值、依赖和源码摘要。worker.json 持续保存阶段进度;超时、超限或失败保持明确失败状态。当前运行器先归档 code/ 与 worktree.patch,核对摘要后执行该冻结副本,frozen.json 记录执行方式;源码副本没有自己的 Git 工作区时,提交、差异摘要为空,并以完整文件摘要识别输入,不借用外层仓库 HEAD。早期仅保存哈希或只归档源码的报告须按实际字段解释,不能追溯宣称隔离执行。stdout.log、stderr.log 和数据库文件保留在同目录,已存在的输出目录拒绝覆盖。
每阶段另保存 Linux /proc/self/io 的前后原始计数与差值,区分逻辑读写字节、系统调用次数、内核存储读写计数和 cancelled_write_bytes。最后一项指截断脏页的写入抵消,与任务取消无关;单独报告,不静默从写入量扣除。采样包含进程的驱动线程及已等待子进程,采样读取自身也有少量开销,且各字段不是原子快照;它不是最终设备流量或按数据库文件归属的统计。平台不可用或读取失败明确记录,不能补零。独立的 commit、close/checkpoint、reopen/read 区间揭示延迟写入;区间外异步工作仍需另外解释。文件大小只用于空间占用,不能作为累计写入量或写放大比。计数含义依据 Linux proc_pid_io(5)。
这里的恢复测量是在同一工作进程中释放原对象并重新打开连接;操作系统缓存保持原状。摘要计算有独立时间项,提交和读取内部仍包含各自必需的完整性验证,不能从总耗时中扣除。常规 CI 的小型 smoke 只验证合成输入和持久化正确性;容量、吞吐及回退门槛由显式规模报告给出。单来源同步报告的范围不包括在线事件循环延迟、多来源更新、热配置和取消清理。
2026-10-02 的固定真实输入测量已完整读取、提交、关闭重开并重建恢复快照,保留原生成时间和完整性校验。两次实验使用冻结 cc07ddf、2 核 affinity、4 GiB cgroup、swap=0;原始报告、逐阶段进程计数和受控系统调用归属见 .local-data/performance/io-growth-v1/reviewed-io-summary.json。下表时间包含 strace 开销,恢复读取是在释放原对象后从热缓存读取,不能当作未跟踪或冷盘延迟。
| 后端 | commit | 关闭/checkpoint | 重开后读取 | 恢复索引构建 | 峰值 RSS | 数据库相关文件同时峰值 |
|---|---|---|---|---|---|---|
| SQLite | 68.06 秒 | 0.020 秒 | 65.79 秒 | 25.88 秒 | 1,663,795,200 bytes | 164,142,872 bytes |
| DuckDB | 77.05 秒 | 0.128 秒 | 66.52 秒 | 25.50 秒 | 1,795,571,712 bytes | 25,440,256 bytes |
按成功 write/pwrite 返回值累计,SQLite 主数据库写入 81,833,984 bytes、WAL 写入 82,722,320 bytes;DuckDB 主数据库写入 25,444,352 bytes、WAL 写入 644,561 bytes。SQLite 另有 journal 写入和 SHM 可写共享映射,SHM mmap 的写入量没有被该方法量化,因此不声称取得所有文件的完整写入总量。关闭后的主文件分别为 81,756,160 / 25,440,256 bytes;空间占用、系统调用接纳字节和物理设备流量是三种不同指标。这两次成功不替代在线多来源并发、长期 WAL 增长和慢 reader 的验收。
在线测量运行器
scripts/benchmark_online.py 使用公共 Client API、真实环回 HTTP 字节流和受管理的文件读取线程。supervisor 先把被测 Python 源码与运行器复制到输出目录的 code/,验证摘要后通过固定 PYTHONPATH 运行该副本;后续工作区修改不影响本次测量。它沿用原生 Linux CPU affinity 与 RSS/墙钟 watchdog,记录源码、输入、依赖、每阶段时间、10 ms heartbeat 的事件循环延迟分位数、RSS/PSS/Swap、文件峰值与进程 I/O 计数。
事件测量用运行器内的实例包装记录实际事件发布的入口和返回:此时 Client 已交换完整状态,事件入队在返回前完成,持久化 offer 在其后。用完整 EventId 关联公共 watch 首次 yield 后的接收时间;发布返回至接收的间隔才是报告中的传播延迟,不从生产者换文件或轮询开始计时。发布匹配缓存最多 1,000 项小型身份与时间信息,状态/快照各保留最近 500 项,不持有快照对象;每个消费者的收件样本也分别保留两类最早 500 项,消费者最多 8 个。频繁状态变化不能挤占后续快照的匹配或采样预算。滚动淘汰、未匹配收件、超出采样额度及 resync 分别计数;已经淘汰的发布无法追溯赋予延迟。状态事件与快照事件分开解释。旧报告按其实际观测方式解释:只有接收时间的报告不能算发布延迟,只缓存最早 1,000 项的报告也不能算覆盖后续所有换代。
uv run --locked --isolated --no-default-groups --extra http --extra trio --extra sqlite --extra duckdb --python 3.11 \
python scripts/benchmark_online.py --scenario load --backend trio --sources 3 \
--rows 100000 --overlap 90 --cpus 4 --max-rss-mib 8192 --request-timeout 300 \
--output .local-data/performance/online-three-synthetic
uv run --locked --isolated --no-default-groups --extra http --extra trio --python 3.11 \
python scripts/benchmark_online.py --scenario load \
--input .local-data/rpki-client/2026-10-01T151848Z/vrps.json \
--request-timeout 300 --cpus 2 --max-rss-mib 4096 \
--output .local-data/performance/online-production
load 测所有配置来源完成原始状态发布,不能用第一个来源 ready 代替全部完成。churn 重新生成含 0、1、100 和最多 10,000 条授权变化的完整生产者文件,分别记录生成与在线发布成本;0 条授权变化仍有新的原始生成/到期时间,用于测只续期。更新期间保留四个调用方持有的旧快照,再测轮询参数热改、删除全部来源和重新添加至全部就绪。--persistence sqlite|duckdb 增加真实落盘和 flush 时间。
churn 还把一个来源切换到同一原始文件的另一 URL,分别记录身份替换提交、重新就绪及落盘;核对来源身份变化而原始生成/失效时间与完整载荷计数保持不变。调用方始终只刻意保留四个旧版本,不额外持有被替换前的第五个旧视图。retire 单独使用一个完整规模的文件 reader:在线程内停在适配器障碍处,提交删除后以同一 ID 新增另一份新生成的输入,在旧线程仍受管理且占用额度时完成新来源发布,再释放旧线程并核对迟到结果没有改变新快照。报告分开记录删除、重新添加、并行接纳、释放至实际清理、最终落盘、关闭及重新打开数据库读取,记录公共资源 gauge;该场景要求至少两个构建槽。受控障碍不是生产者耗时指标,失败时也释放障碍并等待拥有者清理。
--request-timeout 和 --flush-timeout 仅在显式提供时覆盖来源请求和持久化等待期限;省略时分别使用 HttpJsonSourceConfig 和 PersistenceConfig 的公共默认值。flush 调用省略 timeout,以验证配置的真实生效值。报告记录实际期限、显式覆盖标记及独立的总实验预算;--timeout 只约束实验与外部等待,不扩大这两个产品期限。旧运行器将 flush 显式设为总实验预算,旧报告仍按其冻结源码解释,不能作为默认值验收。
2026-10-02 的请求与落盘期限校准采用固定提交 3986a54 的源码、4 CPU affinity、8 GiB cgroup、swap=0;三个独立 HTTP 来源各含 1,000,000 条合成 VRP,90% 重合,完整加载后为 3,000,000 条原始支持、1,200,000 条生效 VRP,另有 9,999 条 ASPA 支持、39,618 条 provider 边。保留默认两个构建槽,显式设置来源总截止 1200 秒及 flush 等待 600 秒;总实验预算 2400 秒独立计时。报告位于 .local-data/performance/online-budget-scale-v3/,输入摘要、冻结文件摘要、原始期限、累计进程 I/O 和事件延迟一同保留。
| 实际后端组合 | 全部来源加载(秒) | 初始 flush 等待(秒) | 进程峰值 RSS(bytes) | 关闭后数据库(bytes) | WAL 文件峰值(bytes) |
|---|---|---|---|---|---|
| Trio / SQLite | 748.30 | 358.93 | 3,476,578,304 | 189,923,328 | 191,023,832 |
| asyncio / DuckDB | 820.40 | 399.05 | 3,834,355,712 | 73,936,896 | 678,384 |
两项均完成全部来源发布和目标版本落盘。加载区间已有后台持久化,flush 列是后续等待时间,不是独占事务成本;文件大小不是累计写入量。加载时 10 ms heartbeat 的调度延迟 p99 分别为 0.386/0.432 秒,最大 6.95/8.48 秒,不能据此承诺低延迟服务。RSS 在本次单一当前视图工作负载中低于 8 GiB 的一半;保留旧快照、并发查询或其它机器仍需按各自报告判断。来源整体 max_age 为 86400 秒,合成记录自带的到期时间为原始生成时间后 12 小时;两类期限均不因加载或落盘而刷新。
原 30 秒来源期限在百万级输入未完成时退出且没有部分发布;30 秒 flush 也不足以完成对应全量等待。较早的三来源实验中,来源 600 秒或 flush 300 秒仍分别出现超时。上述完整校准是公共默认值采用来源 1200 秒、flush 600 秒的测量依据,原失败报告保留。该显式参数实验本身不证明后续版本省略参数的行为,也不承诺任意硬件或负载均能在默认期限内完成。部署可显式缩短失败等待;原始数据寿命、就绪等待、备用组启动窗口和必要清理规则不随这些预算延长。
随后四个独立进程实际省略了来源和 flush 覆盖参数,报告中的两项显式标记均为 false,公共 flush 调用也未传入 timeout。运行库全部 Python 文件与提交 140972f 逐字节相同;冻结运行器为 source-flush-v1,本次只执行 load。原始报告、输入与源码摘要、实际期限和逐阶段观测见 .local-data/performance/online-public-defaults-v4/reviewed-summary.json。全部完成了配置来源的加载、目标版本落盘和关闭。
| 载荷规模与实际组合 | CPU / cgroup 内存上限 | 全部来源加载(秒) | 初始 flush 等待(秒) | 进程峰值 RSS(bytes) |
|---|---|---|---|---|
| 单来源 100 万 VRP,asyncio / SQLite | 2 / 4 GiB | 69.57 | 131.80 | 1,257,349,120 |
| 单来源 100 万 VRP,Trio / DuckDB | 2 / 4 GiB | 68.67 | 145.55 | 1,320,787,968 |
| 三来源各 100 万 VRP,Trio / SQLite | 4 / 8 GiB | 667.63 | 350.17 | 3,438,346,240 |
| 三来源各 100 万 VRP,asyncio / DuckDB | 4 / 8 GiB | 716.14 | 395.25 | 3,448,528,896 |
三来源仍是上述 90% 重合分布,保留完整的 300 万原始 VRP 支持;单来源另含 3,333 条 ASPA 支持和 13,206 条 provider 边。环境为相同的共享原生 Linux x64 主机、热文件系统、环回 origin,组内 swap=0。四项均达到各自 RSS watchdog 一半的规划目标,但这仅覆盖当前视图的加载/落盘;不能推导四个旧版本、来源退休或 HTTP 并发的容量。既有显式参数实验和失败报告继续保留,后来的成功不覆盖它们。
expiry 使用真实时间、可配置数量的分散秒级到期点,等待生效集合降至已同步为空。cancel 在自定义 reader 的受控线程障碍处请求关闭,先确认关闭仍在等待,再释放线程,确认线程退出和候选未发布;它不把取消请求等同于已完成清理。--aspa-customers 可单独增加 ASPA customer,合成 provider 分布同时包含短列表与 228 项尾部;它是标注为合成的增长分布,不冒充真实样本分布或协议极限向量。
真实历史输入仅支持 load,校验固定 SHA-256、保持所有原始字节与时间,并按实际当前时间和显式 max_age 接纳。文件已过期时必须报告无法在线接纳,不能刷新历史时间以完成基准。--expect-timeout 或 --expected-error resource_limit 用于明确的负向实验,只有观察到指定错误且没有发布部分支持才通过;报告的 outcome 区分此类拒绝与成功完整加载。
环回 origin 在同一工作进程中逐块读取文件,它的开销计入 RSS 和 CPU;这不代表公网、TLS、远程缓存或冷磁盘条件。半内存余量字段只比较观测峰值与所选 watchdog 容量的一半,不是运行时堆内存保证。普通 CI 只运行可移植的小型 workload smoke;完整规模与增长实验必须显式执行并保留报告。
在已委托 memory 控制器的 systemd 用户会话中,可将同一命令放入 systemd-run --user --scope -p MemoryMax=4G -p MemorySwapMax=0 taskset -c 0-1 ...(参考档位改为 8G 和四个可用 CPU)。报告记录实际 cgroup 路径、memory.max/peak/events、swap 和可用的 CPU 控制器字段;未提供的控制器不伪装为已启用。这仍是共享宿主上的受限进程组,不等同于一台独占的 4 GiB 机器。
百万级 retire 场景另使用与提交 0e7d127 逐文件摘要匹配的冻结工作树,运行库也与 140972f 相同,在 2 CPU、4 GiB cgroup、swap=0 下完成两种数据库检查。旧 reader 停在受控障碍时仍占一个构建槽及 256 MiB 暂存额度;删除后以相同来源 ID 接纳另一份新生成的输入,原 worker 尚未退出时新快照已经就绪。释放原 worker 后核对迟到结果隔离,落盘并关闭,随后重新打开数据库读取,恢复的新快照、配置版本、来源身份、原始期限和百万条支持保持一致。
| 实际组合 | 新来源就绪,旧 worker 仍被持有 | 释放旧 worker 至实际清理 | flush 新状态 | 重开读取 | 进程峰值 RSS |
|---|---|---|---|---|---|
| Trio / SQLite | 56.52 秒 | 71.47 秒 | 74.23 秒 | 66.15 秒 | 1,695,563,776 bytes |
| asyncio / DuckDB | 54.03 秒 | 69.82 秒 | 88.90 秒 | 63.19 秒 | 1,995,161,600 bytes |
该释放后耗时包括 reader 返回后仍需完成的受管理工作,不能当作普通网络取消延迟。报告在 .local-data/performance/hot-config-scale-v1/reviewed-retirement-summary.json。两项行为检查通过,但 DuckDB 的半内存规划字段仍为 false:字段比较的是 3.5 GiB RSS watchdog 的一半;实际 4 GiB cgroup 的记账峰值为 2,177,417,216 bytes,计入的范围比 RSS 更广。记录三种不同指标,不调整阈值或把逻辑删除视为资源已释放。这两项不覆盖三来源并持有四个旧版本的数据库更新负载。
同一冻结工作树的三来源 SQLite churn 在 4 CPU、8 GiB cgroup、swap=0 下未完成。该工作树在提交前冻结,清单保留当时的 678a807 HEAD 和未提交修改;全部 359 个冻结文件事后与 0e7d127 的 Git 树匹配,实际执行的 65 个运行库及脚本文件也逐一匹配。副本没有独立 Git 工作区,报告不借用外层 HEAD;具体身份以源码摘要为准。原始失败报告保存在 .local-data/performance/hot-config-scale-v1/churn-3x1m-trio-sqlite-8g/report.json。
终止前已完成以下四轮内容核对和 flush;每轮保留完整的 300 万 VRP 原始支持、9,999 条 ASPA 支持及 39,618 条 provider 边。来源和 flush 均未覆盖公共默认值 1200/600 秒;下列阶段时间包含运行器断言及重叠工作,不能当作独占 SQL 时间或库自身的延迟。
| 改动 VRP 数 | 发布观察阶段(秒) | 后续 flush 等待(秒) | 截至该轮的进程 RSS 高水位(bytes) |
|---|---|---|---|
| 0,仅续期 | 116.39 | 422.04 | 3,465,814,016 |
| 1 | 127.58 | 440.81 | 4,438,474,752 |
| 100 | 137.02 | 477.09 | 5,484,941,312 |
| 10,000 | 132.44 | 499.25 | 6,492,233,728 |
四轮 flush 区间的进程级 wchar 均为 382,342,496 bytes,仅续期也观察到同量级写入。该计数覆盖整个进程,不是数据库文件归属或最终物理设备流量。随后在持有四个不同代旧视图、删除并重新添加全部来源的就绪等待阶段,采样 RSS 达到 8,060,252,160 bytes,超过 7,680 MiB watchdog,外部看门狗以 SIGKILL 终止工作进程。cgroup 峰值达到实际 8 GiB 上限,max 事件为 919,oom / oom_kill 均为 0。来源重载、身份替换和正常关闭未执行完成;这既不是完整 churn 通过,也不是库返回 ResourceLimitError 或安全清理的证据。当前视图加载的成功不能用于推导此负载的容量,8 GiB 档位预留一半内存的规划目标同样未满足。
随后保持同一冻结源码、完整负载和断言,在原生 Linux x64、CPython 3.11.15、4 CPU affinity 下将 cgroup 上限设为 16 GiB、RSS watchdog 设为 15,872 MiB,仍禁用 swap。来源请求和 flush 继续省略覆盖参数,实际使用公共默认值 1200/600 秒;独立总实验预算为 10800 秒。此次完整 churn 在 6018.48 秒后正常退出,原始报告与逐文件复核保存在 .local-data/performance/hot-config-scale-v1/churn-3x1m-trio-sqlite-16g/ 和 reviewed-sqlite-churn-16g.json。
| 16 GiB 下的阶段 | 实测时间(秒) |
|---|---|
| 全部来源加载 / 随后的初始 flush | 745.01 / 465.71 |
| 0、1、100、10,000 条变化的发布观察 | 120.87 / 141.21 / 147.20 / 136.56 |
| 对应四轮后续 flush | 458.38 / 515.68 / 518.50 / 529.54 |
| 修改轮询参数 / 删除全部来源 / 重新添加配置提交 | 0.13 / 0.07 / 0.47 |
| 重新添加至全部来源就绪 | 1091.90 |
| URL 身份替换提交 / 替换来源就绪 / 最终 flush | 166.19 / 424.44 / 349.32 |
| flush 完成后的关闭 / Client 对象返回后的 GC | 0.25 / 15.48 |
四个不同代旧视图在重载和身份替换期间仍被持有。最终回执为配置 revision 5、快照 generation 16;来源身份改变,替换前后的原始生成和失效时间相同,完整数量为 300 万 VRP 支持、9,999 条 ASPA 支持、39,618 条 provider 边和 1,209,000 条生效 VRP。关闭后 WAL/SHM 文件不再存在,主数据库为 189,923,328 bytes;包含生产者输入及临时文件的同时磁盘占用采样峰值为 709,201,681 bytes。四轮 flush 的进程级 wchar 仍各为 382,342,496 bytes,最终 flush 区间为 764,684,992 bytes;这些仍是包含重叠工作的进程计数。
采样峰值 RSS 为 9,708,163,072 bytes,阶段记录的进程 RSS 高水位为 9,748,443,136 bytes,cgroup 记账峰值为 10,460,422,144 bytes;本次 max / oom / oom_kill 均为零。即使完整负载在 16 GiB 中完成,预留一半内存的规划目标仍未满足,较大的内存档位也不改变先前 8 GiB 失败的结论。Client 对象返回并执行 GC 后 RSS 仍为 6,568,517,632 bytes,不能将正常关闭解释为内存回到启动基线或长期增长已收敛。重载和替换就绪阶段的 heartbeat 最大间隔分别为 27.46/28.21 秒,包含运行器同步核对;它们不是库自身独占延迟,但也不能据此声称低延迟。这一结果只覆盖该共享宿主上的 SQLite/Trio 工作负载,不能替代 DuckDB、并发 HTTP、其他平台或最终候选制品的验收。
相同 0e7d127 字节等价冻结工作树的 DuckDB/asyncio 三来源 churn 也在 4 CPU、8 GiB cgroup、swap=0 下失败。公共来源/flush 期限仍为省略覆盖后的 1200/600 秒,两个构建槽和完整数量断言保持不变。全部来源加载耗时 842.89 秒,随后的初始 flush 为 539.74 秒;终止前完成以下四轮更新,每轮仍包含 300 万 VRP 支持、9,999 条 ASPA 支持和 39,618 条 provider 边。
| 改动 VRP 数 | 发布观察阶段(秒) | 后续 flush 等待(秒) | 截至该轮的进程 RSS 高水位(bytes) |
|---|---|---|---|
| 0,仅续期 | 117.41 | 543.26 | 3,878,821,888 |
| 1 | 130.84 | 553.31 | 4,817,346,560 |
| 100 | 138.71 | 574.57 | 6,028,845,056 |
| 10,000 | 132.75 | 589.87 | 6,933,921,792 |
持有四个旧视图并删除、重新添加全部来源后,在等待全部来源重新就绪时,采样 RSS 达到 8,053,870,592 bytes,超过 7,680 MiB watchdog,外部看门狗以 SIGKILL 终止工作进程。总运行时间为 4525.89 秒;cgroup 峰值为 8,584,327,168 bytes,max / oom / oom_kill 均为零,因此不能记作内核 OOM。完整重载、URL 身份替换和正常关闭没有完成;已有落盘文件也不构成恢复成功的证明。半内存规划目标未达到,原报告的完成后规划字段为 null,保留原值。
四轮 flush 的进程级 wchar 分别为 62,656,512、62,918,656、62,918,656 和 63,180,800 bytes,仍不是数据库专属或物理设备写入量。终止后的主数据库为 234,631,168 bytes;含生产者输入和临时文件的同时磁盘占用采样峰值为 529,364,037 bytes。原始报告及独立复核位于 .local-data/performance/hot-config-scale-v1/churn-3x1m-asyncio-duckdb-8g/ 和 reviewed-duckdb-8g-failure.json。全部 359 个冻结文件与 0e7d127 匹配,65 个实际执行文件与原清单匹配;其中 _json_source.py 早于 63738bc 的重复 JSON 候选释放修复,这一实验不能标为该修复或最终候选制品的实测结果。
同一冻结工作树随后在 4 CPU、16 GiB cgroup、swap=0 下完成 DuckDB/asyncio 的完整三来源 churn,总耗时 6447.29 秒。两项公共期限仍为省略覆盖后的 1200/600 秒,构建槽和完整数量断言不变。加载为 851.38 秒,随后初始 flush 为 549.15 秒;四轮更新都保留 300 万 VRP 支持、9,999 条 ASPA 支持和 39,618 条 provider 边。
| 改动 VRP 数 | 发布观察阶段(秒) | 后续 flush 等待(秒) | 截至该轮的进程 RSS 高水位(bytes) |
|---|---|---|---|
| 0,仅续期 | 111.37 | 518.77 | 3,933,904,896 |
| 1 | 124.86 | 554.11 | 4,850,446,336 |
| 100 | 136.02 | 579.31 | 6,067,290,112 |
| 10,000 | 130.20 | 591.25 | 6,940,545,024 |
持有四个不同代的旧视图时,全部来源移除后重新就绪耗时 1066.63 秒。随后来源 URL 身份替换的配置提交为 162.50 秒、新来源就绪为 399.38 秒,原始生成时间和有效期保持不变;最终 flush 为 470.77 秒,取得配置修订 5、快照版本 16 的回执。正常关闭为 0.15 秒,Client 对象返回后的 GC 阶段为 15.76 秒;这里的关闭发生在最终 flush 之后,不能代替活动解析或数据库写入期间的取消测量。
采样峰值 RSS 为 10,227,412,992 bytes,阶段记录的进程 RSS 高水位为 10,225,057,792 bytes,cgroup 记账峰值为 10,750,369,792 bytes;max / oom / oom_kill 均为零。预留一半内存的规划目标在 16 GiB 下仍未满足,先前 8 GiB 失败保持原结论。Client 对象返回并执行 GC 后 RSS 仍为 6,139,568,128 bytes,不能据此宣称内存回到启动基线或长期增长已经收敛。重载和替换就绪阶段的 heartbeat 最大间隔分别为 26.35/26.89 秒,包含运行器同步核对,不是库自身独占延迟。
四轮 flush 的进程级 wchar 分别为 62,656,512、62,918,656、63,180,800 和 63,442,944 bytes,最终替换 flush 为 126,623,744 bytes;仅续期也需要同量级写入。这些重叠工作的进程计数不能作为数据库专属或物理设备流量。关闭后的主数据库为 300,691,456 bytes,WAL 已消失;包括输入和临时文件的同时磁盘占用采样峰值为 546,611,951 bytes,单独 WAL 峰值为 678,393 bytes。原始报告和独立复核位于 .local-data/performance/hot-config-scale-v1/churn-3x1m-asyncio-duckdb-16g/ 和 reviewed-duckdb-churn-16g.json。原来的 359 文件工作树身份及 65 个执行文件摘要保持不变,仍早于 63738bc;本结果只证明所述原生 Linux x64、CPython 3.11.15、共享宿主和热文件系统上的完整负载,不替代并发 HTTP、其他平台或最终候选制品的验收。
--max-builds 只覆盖本次显式基准的重型构建准入,用于对照默认值。--trace-builds 为冻结副本内存在的 build_view、prepare_view、PreparedView.advance 与 make_snapshot_event 增加保留参数/结果/异常的薄计时包装,分别记录墙钟、线程 CPU 时间、输入支持数量、调用总数及前 1,000 次详情。时间校准还记录 reused、脏 VRP/customer 数和 full 标记;当前实现的时间索引初始化计入完整 prepare_view,unseeded_groups 用于核对 advance 输入已具备时间索引。组等待单列为 group_build_waits,使用来源发布编号关联 source_publications 与完整 prepare_view 次数;完整并发基准逐轮核对每个来源的新输入仅完成一次非复用完整构建。包装保留原调用结果和异常,最多记录各类前 1,000 次详情及总数,不改变原截止。启用包装的报告列出实际 instrumented_functions,不能把它和未包装的结果无条件视为相同测量条件。
服务与远程 SDK 测量运行器
scripts/benchmark_service.py 复用冻结源码、Linux watchdog 和 cgroup 观测,在真实 Uvicorn 环回监听器上调用公共 RemoteClient。每次独立进程只测 pages、export 或 batch 一项;先完整加载,再固定新的 token,避免前一个操作消耗后一个操作的保留时间。ASGI 服务使用 asyncio;SDK 在受管理线程的独立 asyncio 或 Trio 循环中执行。RSS 包含服务、SDK、解析线程及驱动,不能冒充仅服务器或仅 SDK 的独立峰值。
uv run --locked --isolated --no-default-groups --extra service --extra http --extra trio --python 3.11 \
python scripts/benchmark_service.py --operation pages --sdk-backend trio --page-size 1000 \
--input .local-data/rpki-client/2026-10-01T151848Z/vrps.json \
--cpus 2 --max-rss-mib 4096 --timeout 900 \
--output .local-data/performance/service-production-pages
服务请求截止、SDK 请求截止与 token 保留分别由 --service-timeout、--sdk-timeout、--retention-seconds 指定,默认保留产品的 120、180、600 秒。操作前先固定 SDK token,并通过受管理线程桥在服务拥有者循环中取得同 ID 的公共 Client 快照;合法换代只允许在共享的建档总截止内重新固定 token,操作开始后不再更换。建档失败有独立阶段和结果。
这些服务默认值来自 2026-10-02 的百万条合成 VRP 校准:冻结 cc07ddf、单来源、2 核 affinity、4 GiB cgroup、swap=0,服务/SDK/保留期显式取 120/180/600 秒。四次独立进程均完整通过,服务所有者均关闭;原始报告与源码摘要保存在 .local-data/performance/service-calibration-v3/,结论关联 Issue #4。下表的 SDK 时间包含解码、完整性或逐行领域核对;分页时间跨多个请求,不是单次请求截止。
| SDK 后端与操作 | 完成量 | SDK 总时间 | 进程采样峰值 RSS |
|---|---|---|---|
| asyncio 导出 | 138,179,124 bytes | 62.57 秒 | 2,216,214,528 bytes |
| Trio 导出 | 138,179,124 bytes | 57.79 秒 | 2,233,102,336 bytes |
| asyncio 分页,每页 1,000 | 1,000,000 条 | 308.09 秒 | 1,192,558,592 bytes |
| Trio 分页,每页 10,000 | 1,000,000 条 | 256.68 秒 | 1,170,972,672 bytes |
两次导出的实际 ASGI 请求耗时分别为 41.69/38.01 秒;SDK 还需要接收和验证完整响应,因此为它保留更长的独立截止。旧 30 秒请求、60 秒 token 的规模失败保留为反证。600 秒只是可定位版本的保留上限,最多 4 个版本、容量淘汰及原始数据期限仍生效。导出未达到保留一半内存的规划目标;测量包含同进程服务和 SDK,不代表独立服务器 RSS。该单来源校准不证明三来源更新、数据库与多个 SDK 并发时也满足相同时间或内存预算;这类负载按下面的并发实验单独报告。
分页流式消费,每行与同代公共 query.iter_vrps 的下一行比较完整领域对象,同时计算包含来源支持和时间界限的有序摘要;双方必须同时耗尽才算完整。没有预先全表扫描或第二份百万条结果列表,测量时间包含比较和摘要成本。公共本地 iterator 仍执行在线时效检查;若它先到期,明确记录 local_oracle_expired 和已消费数量,不能当作 SDK 成功或 SDK 自身故障。批量的本地预期计算另计,其时间仍消耗已固定 token 的真实期限;SDK 结果逐条核对。导出由 SDK 校验交换格式、身份与完整 payload 摘要。导出超过截止、分页 token 淘汰、来源到期和超限均保留具体失败,不缩短遍历造成功。
报告记录实际 ASGI 响应字节与请求耗时、SDK 整体时间、服务循环延迟和所有者 drain/close。ASGI 计数包装仅观察已发送的消息,不修改请求、响应或领域结果。绑定预先打开 socket、lifespan 和退出行为按锁定 Uvicorn 0.54.0 的 Server 源码 核对;测量依赖版本仍以每份报告为准。普通 CI 仅用小型真实 socket smoke 覆盖两个 SDK 异步后端;大规模测试另行显式执行。
一次独立的小规模导出剖析使用三个来源各 10,000 条 VRP、CPython 3.11.15、原生 Linux x64 和 CPU 24–27,固定输入并以离线上下文评价。基线 369162c 为摘要和外层文档两次编码完整 payload;复用第一次的规范字节后,三次未启用 profiler 的总导出时间中位数从 0.989 秒降至 0.655 秒,输出均为 4,118,869 bytes。每次完整输出与独立标准库规范 JSON 编码逐字节相同,摘要也重新核对;完整封装仍受同一字节预算约束。原始输入、执行文件摘要、独立进程报告和额外 cProfile 记录在 .local-data/performance/export-cost-369162c/ 的 baseline 与 reuse-payload 子目录。优化后报告保留实际工作树文件摘要,不冒充旧提交;这个共享宿主上的 30,000 条支持微基准只说明重复编码成本,不能推导百万级并发的延迟、峰值内存或默认期限通过。
后续以 4aab800 的逻辑映射为基线,在同一档位交错执行各三次公共导出,复用已验证网络对象排序后的工作树中位时间为 0.581 秒,基线为 0.690 秒,约减少 15.8%。每次仍有 30,000 条原始支持、4,118,869 bytes 完整输出;与独立标准库编码及 payload 摘要逐字节核对。原始输入、基线及实际执行源码、未剖析计时和另外的 cProfile 结果保存在 .local-data/performance/export-native-sort-4aab800/production/。同进程比较不证明峰值内存改善,CPU 24–27 同时承载小型回归;该结果不代替百万级并发测量,也不能与前一次不同进程的时间直接合并计算总体收益。
同步查询测量运行器
scripts/benchmark_queries.py 复用冻结源码、Linux watchdog 和 cgroup 观测,测固定离线快照的同步公共查询。表按种子合成;唯一的 IPv4 /24 与 IPv6 /64 支持独立确定的 ROV valid、wrong ASN、AS0 与 notfound 预期。ASPA customer 分布、228 项 provider 尾部及独立连续授权链使用不重叠的 ASN 区间,覆盖 valid、invalid、unknown 和 2 至 16,384 个 ASN 的路径。它不修改生产数据,也不能替代固定规范与独立互操作向量。
uv run --locked --isolated --no-default-groups --python 3.11 \
python scripts/benchmark_queries.py --rows 100000 --aspa-customers 10000 \
--path-length 16384 --samples 1000 --batch-size 10000 \
--cpus 2 --max-rss-mib 4096 --timeout 900 \
--output .local-data/performance/queries-100k
简要与详细查询分别计时;批量明确批次大小,长路径减少采样数量并报告实际数量。每个计时结果都核对状态、快照身份和解释开关;计时之后才执行断言,不把漏做工作当成加速。报告保存未经扣减的原始 perf_counter_ns 调用耗时、p50/p95/p99、最大值、预热次数、时钟精度及含验证循环的 CPU 时间。遍历报告一次完整扫描,不用一个样本声称稳定尾延迟。这里是同步函数和热缓存测量,宿主事件循环响应性由在线与服务运行器另测。
来源差异保留默认条数/字节预算。完整结果包括双方共同的原始支持;表超过默认预算时,运行器核对明确的 resource_limit 拒绝并记录拒绝成本,不扩大预算构造百万条诊断对象,也不把它称为全量差异完成。相同规模条件下比较 ROV 表增长与 ASPA customer 增长;记录连续授权链额外的 customer/provider 项,不能只报命令中的 --aspa-customers 掩盖实际索引数量。
2026-10-03,冻结提交 cae9cb2 在原生 Linux x64、CPython 3.11.15 上完成下列四档查询测量。每档使用 2 CPU affinity(8–9)、4 GiB cgroup、禁用 swap 和 3840 MiB RSS watchdog;主机同时在其他 CPU 运行并发规模及生命周期实验。数据和 CPU 缓存保持热态,下面是实际观测,不是独占机器的延迟或吞吐保证。
| VRP 支持 | 基础 customer / 实际 ASPA 支持 | provider 边 | 采样峰值 RSS(bytes) | ROV valid 简要 p50(µs) | ASPA 5-ASN valid 简要 p50(µs) |
|---|---|---|---|---|---|
| 10,000 | 10,000 / 26,385 | 56,668 | 144,629,760 | 14.758 | 11.404 |
| 100,000 | 10,000 / 26,385 | 56,668 | 235,991,040 | 15.921 | 12.079 |
| 100,000 | 100,000 / 116,385 | 417,427 | 653,426,688 | 15.841 | 11.121 |
| 1,000,000 | 100,000 / 116,385 | 417,427 | 1,543,933,952 | 17.401 | 11.810 |
每档完成 34 个查询场景、23,037 次记录调用,另有明确的预热。简要和详细结果均核对状态、快照身份、AFI 及解释开关;覆盖最长 16,384 个 ASN 的路径、10,000 项批次、228 项 provider 尾部和完整遍历。来源 diff 均按原默认预算明确拒绝。四档的实际 cgroup 峰值分别为 184,602,624、274,198,528、693,321,728、1,585,766,400 bytes,均满足该档位的一半规划余量;这个结论仅限上述同步、单份离线快照负载。
原始调用样本、p50/p95/p99、完整阶段及冻结源码保存在 .local-data/performance/queries-cae9cb2/,reviewed-summary.json 记录逐文件身份、输入形状和分位数复算。VRP 或基础 customer 增长十倍的对照中,表中短查询的 p50 没有随表大小近似增长十倍;这项观测不代替索引实现审查,也不是任意输入的复杂度证明。先前 queries-v2/ 的结果保留原源码身份,不能与本轮合并为同一次执行。
原始支持与索引增长运行器
scripts/benchmark_growth.py 单独测量程序化 VRP 模型与公共 MemoryStore 的增长,避免 JSON 字节上限先于记录上限拒绝输入而掩盖模型容量。每个来源分配独立的记录与载荷对象;90% 或 100% 重合只描述载荷值,不通过重复引用同一个对象降低原始输入内存。数据仅含 VRP,因而每源 500 万、两个来源合计 1,000 万精确对应支持预算,没有附加 ASPA provider 项。
systemd-run --user --scope -p MemoryMax=8G -p MemorySwapMax=0 \
taskset -c 0-3 uv run --locked --isolated --no-default-groups --python 3.11 \
python scripts/benchmark_growth.py --rows 5000000 --sources 2 --overlap 90 \
--cpus 4 --max-rss-mib 7680 --timeout 1800 \
--output .local-data/performance/growth-5m-two-sources-90
先用较小的 --rows 验证趋势,再分别测量单来源边界和两个来源的 90%/100% 重合;所有重型实验串行运行。上述 Linux 命令需要已委托的 memory 控制器和四个可用 CPU;7.5 GiB RSS watchdog 留在实际 8 GiB cgroup 上限以内,两者仍不能保证采样间隔内不会触及内核限制。报告记录实际 cgroup、swap 和终止原因,不能把资源失败改称完整接纳。
数据在固定合成生成时刻显式离线评价,调用公共 replace_source、iter_vrps 和 covering_vrps,逐源核对完整生效条数、来源支持总数及采样载荷的来源集合。报告区分计划条数、每 10 万条更新的生成进度、实际已提交支持和已完成查询验证的数量,并记录生成、构建、遍历和释放阶段;中途终止仍保留最后已知进度。默认仅保留 store 必需的当前视图,这个实验不覆盖 JSON 解析、在线时效索引、数据库、四个旧版本或事件循环响应性,不能替代相应工作负载的验收。普通测试仅执行小型独立正确性 smoke。
2026-10-02 已执行的 VRP 模型边界如下。单来源来自 .local-data/performance/growth-v2/;两个来源的加大内存复测来自 .local-data/performance/io-growth-v1/reviewed-growth-summary.json,冻结源码为 cc07ddf。全部为独立来源对象、完整原始支持核对和公开遍历;这是离线当前视图测量。
| 原始支持与重合 | 实际内存上限 | 结果 | 采样峰值 RSS |
|---|---|---|---|
| 单来源 500 万 | 8 GiB | 完整完成 | 5,177,323,520 bytes |
| 两来源各 500 万,100% | 8 GiB | 第二来源提交前被外部 RSS watchdog 终止 | 约 7.5 GiB |
| 两来源各 500 万,90% | 8 GiB | 第二来源提交前被外部 RSS watchdog 终止 | 约 7.5 GiB |
| 两来源各 500 万,100% | 16 GiB | 完整完成,500 万生效 VRP,454.81 秒 | 9,255,940,096 bytes |
| 两来源各 500 万,90% | 16 GiB | 完整完成,550 万生效 VRP,448.85 秒 | 9,356,419,072 bytes |
所有实验禁用组内 swap。8 GiB 失败不能重写为通过,也不是库优雅返回 ResourceLimitError 的证据;16 GiB 成功仍未达到预留一半内存的规划余量。记录上限只限制模型条数,不能承诺同等 RSS,也不能据这张表推断 JSON、在线时效、数据库或四个旧视图的容量。三来源各百万、90% 重合并持有四个旧视图的独立在线 churn 测量(冻结 85ade29 及对应运行器)在 asyncio/Trio 均完成,但峰值分别为 7,679,299,584 / 7,720,288,256 bytes,未达到 8 GiB 档位的一半余量;详见 .local-data/performance/remaining-v3/reviewed-summary.json。这些版本限定的观测不能无条件归给后继候选制品。
连续到期与长稳运行器
scripts/benchmark_expiry.py 在公共 Client 上测连续到期期间的实际可查询性。默认百万 VRP 具有 120 个连续秒级到期点,首个期限固定在原始合成生成时刻之后 180 秒;加载、扫描或更新都不重设期限。运行必须在首个期限前完成初始全量核对,并在到期区间的前、中、后三段分别取得仍含有效数据的视图,最后观察到 ready_empty。允许多个边界合并为一代,不新增每秒发布的吞吐承诺;只在末尾清空不能通过。
systemd-run --user --scope -p MemoryMax=4G -p MemorySwapMax=0 \
taskset -c 0-1 uv run --locked --isolated --no-default-groups --extra http --extra trio --python 3.11 \
python scripts/benchmark_expiry.py --backend trio --rows 1000000 \
--cpus 2 --max-rss-mib 3840 --timeout 600 \
--output .local-data/performance/expiry-trio
每次观察记录 get_snapshot 耗时、身份、原始 usable_until 和立即执行的公共覆盖查询。取到固定快照后恰好到期属于合法竞争,单独记录失败探针并重新获取;它不能成为三段有效查询的见证。报告同时保留构建次数、期限校准、事件循环延迟和最终取消清理。超时、初次加载跨过首个期限或缺少任何一段见证均保留失败。
scripts/soak.py 为小型合成数据提供有预算的生命周期长稳检查,覆盖真实环回 RTR 断线重连、Serial/Cache Reset、运行中来源增删、订阅取消和显式遗漏通知,以及 SQLite/DuckDB 的提交前异常和提交后回执丢失。后端故障由公共适配器注入,不能称为物理磁盘故障。四组合分别使用 --backend asyncio|trio --database sqlite|duckdb,例如:
uv run --locked --isolated --no-default-groups --extra trio --extra sqlite --extra duckdb --python 3.11 \
python scripts/soak.py --backend trio --database duckdb --duration 600 --warmup 30 \
--max-rss-mib 512 --output .local-data/soak/trio-duckdb
每轮记录任务、线程、连接、句柄、RSS/PSS 与故障恢复计数;结束时真实等待拥有的工作线程和运行时闲置线程退出,再关闭重开数据库核对恢复。平台不提供的资源指标为 null。预设 32 MiB 的稳态 RSS 四分位中位数增长预算用于发现趋势,有限时长通过不能证明长期内存不增长;报告仍须展示实际斜率与各阶段内存。源码先冻结并逐文件校验,没有独立 Git 工作区的副本不借用外层 HEAD 作为提交身份。
在来源撤销、构建调度和持久化摘要改动后,冻结提交 cae9cb2 于 2026-10-03 在原生 Linux x64、CPython 3.11.15 上重新实际执行四组合。每组合使用一个独立 CPU(24–27)、512 MiB cgroup、禁用 swap 和 480 MiB RSS watchdog;预热 30 秒后观察不少于 600 秒。四组合同时运行,主机还运行使用其他 CPU 的规模实验;这些是小型合成数据的生命周期结果,不作为独占机器的延迟基准或百万级容量证据。
| 异步 / 数据库 | 完整循环数 | 采样峰值 RSS(bytes) | 稳态前后四分位 RSS 中位数增长(bytes) |
|---|---|---|---|
| asyncio / SQLite | 590 | 48,316,416 | 413,696 |
| Trio / SQLite | 589 | 49,631,232 | 589,824 |
| asyncio / DuckDB | 534 | 134,832,128 | 12,128,256 |
| Trio / DuckDB | 533 | 135,327,744 | 10,989,568 |
四组合均完成真实环回 RTR 的全量、Serial 和 Cache Reset 路径,以及每轮配置更新、订阅取消/遗漏通知、提交前故障恢复和回执丢失恢复。关闭后拥有的任务与后端线程退出,连接和订阅计数为零,FD 与 OS 线程回到各自基线;重新打开数据库保持原 serial 和有效期限。Trio 另等待运行时闲置线程约 10 秒实际退出,该时间单独记录。DuckDB 在窗口内仍有正向内存增长,结果仅说明满足原有 32 MiB 有限窗口预算,不表示内存已停止增长。
原始命令、环境、逐轮采样、实际 cgroup 采样及每个进程执行的 66 个源码/脚本摘要保存在 .local-data/soak-network-cae9cb2/;reviewed-summary.json 关联原始报告摘要和经核对的 386 个 Git 文件。表中 RSS 为监督器采样峰值;工作器自己的逐轮样本及趋势另行保存。cgroup 的末次存活采样不是退出后的最终采样,不补造未观测区间。该报告只覆盖上述解释器、平台和环回 RTR 生命周期,不扩大到 HTTP、其他平台或最终候选制品。先前 socket 就绪等待者修复后的 93b7c8b 四组合报告仍保留在 .local-data/soak-network-93b7c8b/。
scripts/benchmark_groups.py 单独测三个独立 HTTP 来源组成的主组与备用组,载荷值 100% 重合。主组先完成全量验证,随后收到畸形新文档;在两备用来源加载期间,持续用公共查询核对所选组及支持集合,不能把主组和备用组混合。备用完整就绪后,主来源重新提供完全相同的原始字节,观察健康恢复及 failback,并核对原生成时间、有效期和仍持有的旧视图不变。
systemd-run --user --scope -p MemoryMax=8G -p MemorySwapMax=0 \
taskset -c 0-3 uv run --locked --isolated --no-default-groups --extra http --extra trio --python 3.11 \
python scripts/benchmark_groups.py --backend trio --rows 1000000 \
--cpus 4 --max-rss-mib 7680 --timeout 900 \
--output .local-data/performance/groups-trio
这里的故障为真实 HTTP 内容解析失败,原完整数据仍在原期限内;它不冒称 TCP/TLS 断线或数据已过期。两个异步后端分别运行,报告加载、备用激活/全量就绪、恢复回切、完整遍历、取消清理和共同内存。连续时间到期另由上述 expiry 运行器测量。
同步、批量、导出及落盘的并发测量
首版收尾复用已经通过且实现未受影响的真实输入、查询、过期、取消、热配置、互操作和持续运行证据,不重复执行增长梯度。两种数据库各一次最大规模任务后即按实测结果确定公开容量;超时或超限保留为失败及容量限制,不反复提高预算重试。数据错误、未清理资源或破坏契约的问题仍须修复并针对性复测。实验显式预算与产品默认值分别记录,失败或未执行不写成通过。
scripts/benchmark_concurrent.py 运行两个先后执行的阶段。首版收尾按用户确认采用 --update-profile maximum(默认):直接使用三来源各 100 万条、90% 重合的数据,每个数据库只执行一次综合任务。第一阶段在选定的 asyncio/Trio 循环上管理真实 HTTP 来源与 SQLite/DuckDB,只执行一轮每来源改动 10,000 条的更新,同时批量验证和导出旧固定快照。--batch-calls-per-round 默认为每轮最多 64 次批量(每次最多 10,000 项),允许显式选择 2–64 次;完整导出仍每轮最多 4 次。报告同时记录请求预算、实际完成次数及真实重叠区间,不把较小预算称为默认压力。该最大规模档保留一个旧快照,等待新代真实落盘,不声明覆盖同时保留四个不同旧版本的资源峰值。--update-profile growth 可选执行只续期、改动 1、100、10,000 条的四轮诊断并保留四个旧快照;它不是首版收尾必需重跑项。SQLite 另由公共 SharedSnapshotClient 观察数据库传播并验证同一上游代,DuckDB 明确不执行共享文件读取。
便携正确性 smoke 显式选择每轮 4 次批量,保持 120 行,分别覆盖 maximum 的一轮/一个旧视图与 growth 的四轮/四个旧视图,保留完整数据与清理断言及原有 20/25 秒期限;实际规模命令默认仍为 64 次,不检测或禁用覆盖率采集。延后首次 HTTP poll 的回归单独选择每秒一次来源轮询,以构造有限的真实来源与落盘突发;它不证明延迟消费者能承受任意时长的默认 50 毫秒持续轮询。实际 socket 测量的快观察者立即消费、慢观察者仍须明确重同步,两者的预算和来源轮询间隔均记录在报告中。
--stage all|core|socket 默认执行 all。单阶段选项仅用于独立校准,报告显式列出已选择、已完成及未执行的阶段,并标记 selected_stage_only;它不能替代完整并发验收。socket 初始输入包含所选 profile 的核心阶段本应完成的变化序列,继续核对原来的旧代批量、导出和后续真实来源更新,不能用空白初始表绕过一致性断言。单阶段结果不能声称完整负载通过;首版最大规模任务使用 all。只有实际完成的阶段才可报告通过,未完成阶段保留为未验证。
--service-timeout、--sdk-timeout、--retention-seconds 可显式覆盖 HTTP 请求截止、SDK 请求截止和 token 保留,值必须有限且大于零;省略时使用公共配置与构造器的当前默认值。报告保存三者的实际生效值和显式覆盖项。服务长轮询仍短于总截止,显式总截止较小时相应缩短长轮询;来源请求及 flush 的实验总预算不随这三个参数改变。使用覆盖参数得到的校准结果不能声称验证了产品默认值。
第二阶段启动独立 asyncio Uvicorn 服务拥有者,选定后端的 SDK 在受管理线程中通过实际 socket 并发执行一次批量(最多 10,000 项)与一次完整导出;核心阶段的每轮 64 次预算不适用于此阶段。服务、SDK、独立核对器和 origin 共用一个进程、CPU 预算及 GIL,进程 RSS、CPU 与 I/O 均为共同成本,不能当作独立服务端成本。maximum 档的第二阶段同样每来源改动 10,000 条;growth 诊断档沿用一次单条更新。来源更新、落盘和慢 HTTP watch 同时运行。HTTP 观察使用产品默认的 64 项订阅队列,让来源同步、50 毫秒轮询及持久化产生的正常状态突发有独立缓冲;这不同于核心阶段为慢消费显式设置的两项队列。完成自然同步和 flush、且快速 SDK 已实际收到至少一个可匹配事件后,再执行实际队列容量加一(当前 65)次公共配置提交,使不消费的慢订阅溢出,SDK 必须收到明确的 resync_required。报告保存实际容量、计划/完成次数和单独的 socket_deliberate_watch_overflow 阶段及起止时刻。外层 socket_concurrent_update_sdk_flush 是包含这次故意突发的总阶段;来源更新耗时使用 publish_started 至 all_sources_observed,flush 使用独立调用区间。嵌套或重叠阶段不可相加或相减后声称是独占 CPU 时间。不能用直接修改队列模拟丢失。服务内部 loss 字段只用于只读等待障碍,最终判断仍来自公共 SDK 错误。 运行器固定记录 SDK 注册的订阅集合;若等待期间订阅已被移除(例如默认 60 秒空闲回收),立即将本次溢出测量标为缺口并失败,不能把订阅消失当作队列溢出通过。等待 loss 的障碍也有独立上限,为订阅空闲期限和整次实验预算的较小值。该保护不延长产品订阅寿命;失败后仍实际关闭 SDK、服务和 origin。
systemd-run --user --scope -p MemoryMax=8G -p MemorySwapMax=0 \
taskset -c 0-3 uv run --locked --isolated --all-extras --python 3.11 \
python scripts/benchmark_concurrent.py --backend trio --persistence sqlite \
--rows 1000000 --sources 3 --cpus 4 --max-rss-mib 7680 --timeout 21600 \
--output .local-data/performance/concurrent-trio-sqlite
--timeout 只控制整次运行的监督期限及运行器观察等待,不再覆盖来源请求或公共 flush。省略 --request-timeout / --flush-timeout 时,两个阶段均实际使用当前产品默认的 1200 / 600 秒;只有显式传入相应选项才改变该项。HTTP 服务、SDK 和 token 默认值同样只在显式覆盖时改变。每个阶段的 timeout_configuration 保存整次预算、显式来源/flush 覆盖项及真实配置对象中的操作期限;HTTP 专属参数另外记录。内部公共 flush 调用沿用拥有者的持久化配置,不以剩余实验时长延长期限。增加总观察时长不能证明旧总预算通过,也不能消除来源、flush、HTTP 或 SDK 的实际超时失败。
上述六小时是包含输入准备、所选更新档位、两个拥有者的先后运行和独立核对的总观察上限,不是吞吐或容量保证;8 GiB 档位仍可能因资源上限失败。未完成、超时与资源拒绝均保存原始失败。解析和后端 commit 的薄计时包装保留实际参数、返回值和异常,在所有拥有者关闭后恢复;commit 区间包含该公开调用实际执行的验证和 SQL 操作,不声称只测到 SQL 执行。工作器在调用前完成的完整摘要不在这个细分区间内,仍计入整个阶段;内置后端可在相同状态和预算下复用该摘要,故不能把 commit 区间直接当作全部落盘 CPU 成本。每阶段的 commit_interval_scope 明确保存这一测量边界。
报告逐轮区分来源更新、实际 JSON 解析、flush 等待和实际后端 commit 与批量/导出的重叠次数;零值表示该项未取得并发证据。两个阶段不互相重叠,创建了任务也不等于实际发生重叠。保留原始区间、循环延迟、RSS、落盘文件大小及取消清理结果;关闭服务和 SDK 线程后统计仍存活的连接,origin 的额外强制清理计数必须为零才支持客户端无泄漏结论。小型 CI smoke 只验证运行器与结果,不是百万规模或吞吐证明。
socket 报告另保存 server_export 的实际线程起止与线程 CPU 时间,以及 /v1/export 的 ASGI 入口、响应头/末尾 body 发送完成、字节数、状态、断连与返回时间。包装不保留响应内容、不修改结果或取消语义;ASGI send 返回只表示 Uvicorn 接纳消息,不能证明 SDK 收到它。operation_overlap_pairs 对 SDK 批量、SDK 导出和服务端导出分别计算与实际解析、commit、flush 等待区间的相交对数;一个导出可能覆盖多个解析调用,零值保持为零。update_overlap_calls 仍只说明与整个更新窗口相交,不能替代这些细分证据。
成功与失败路径均在 SDK 线程真正返回时记录 watches_after_sdk_close,并在服务关闭前记录 watch 和活动请求数;服务退出后的 remaining_watches 为另一观测点,不能用它证明 SDK 的 DELETE 请求成功。SDK 客户端关闭、Client 关闭、Uvicorn 退出分别保存区间,已超时但未返回的导出线程仍计入等待。旧冻结报告没有这些字段时保持原样,不能补写为事后测量结果。
本地 watch 与独立的快速 HTTP watch 使用上述实际发布观测;故意积压的慢 watch 继续验证明确丢失。HTTP 观测在初次加载、flush 和生产者准备之后开始,紧邻 SDK 注册;只有实际匹配并保存了传播延迟的收件才满足首样本障碍。此前快速 HTTP watch 异常结束会立即记录测量缺口并结束实验,不自动重建观察或耗尽整轮预算。后续受控突发中快速 watch 也可能丢失,报告仍保留 resync。SQLite 共享传播从 owner 发布同一快照的时刻计时,并保留旧的轮询观察耗时;无法匹配的代不虚构发布时刻。各操作的 /proc I/O 差值覆盖整个进程,包括并发 origin、生产者、导出和数据库工作;重叠区间不能相加,也不能直接当作数据库独占写入量。
2026-10-02,冻结提交 63738bc 的三来源各百万 VRP、Trio SDK / asyncio 服务 / SQLite 的 --stage socket 校准在 4 CPU、8 GiB cgroup、swap=0 下失败。HTTP 参数未覆盖,实际为服务请求 120 秒、SDK 请求 180 秒、快照保留 600 秒;来源和 flush 使用本次 3600 秒实验预算,因此本次不验证它们的公共 1200/600 秒默认值。一次 10,000 项 SDK 批量完成并与本地结果核对,耗时 16.02 秒;同时进行的快照导出在等待响应头时到达 SDK 截止,180.05 秒后以由 TimeoutError 引起的 TransportError 失败。并发阶段整体在 181.57 秒后以 ExceptionGroup 结束,导出和完整更新/落盘负载没有完成,也没有执行 core 阶段。
失败后的 drain/close 耗时 124.61 秒;两个远程客户端均关闭、SDK 线程已返回、服务关闭后剩余 watch 为零,origin 无遗留已接纳连接、无额外强制关闭且监听线程已 join。该旧报告未记录服务关闭前的 watch 数,不能据此单独证明 SDK 已回收服务端订阅。整个子进程以退出码 1 结束,总耗时 1702.22 秒。采样峰值 RSS 为 5,764,136,960 bytes,cgroup 峰值为 6,405,308,416 bytes,max / oom / oom_kill 均为零;失败原因是请求超时,不是 RSS watchdog 或内核 OOM。预留一半内存的规划目标也未满足,失败报告中的完成后规划字段仍保留 null。RSS 包含同进程服务、SDK、origin、运行器和工作线程,不能作为独立服务器峰值。
这份报告没有独立的服务端响应轨迹,不能推断它何时到达 120 秒截止或是否向 SDK 交付了 503;HTTP 截止契约要求清理等待已运行的线程,SDK 在此期间仍可能先超时。原始报告和独立复核位于 .local-data/performance/concurrent-scale-v4/socket-3x1m-trio-sqlite-8g-defaults/ 与 reviewed-first-socket-default-failure.json,361 个冻结文件与该提交匹配,66 个实际执行文件与冻结清单匹配。后续提高内存或显式扩大 HTTP 期限的校准不能覆盖这一默认参数失败,也不能代替完整 all 阶段验收。
同一冻结版本、规模及后端组合随后在 16 GiB cgroup、swap=0 下显式使用服务/SDK/保留期 600/900/1800 秒,仍未完成导出。10,000 项批量在 16.24 秒完成,导出等待响应头 903.21 秒后因 SDK 截止失败;并发阶段 905.68 秒,随后真实 drain/close 366.30 秒,子进程退出码为 1,总计 2685.23 秒。采样峰值 RSS 为 7,567,777,792 bytes,cgroup 峰值为 8,372,473,856 bytes,max / oom / oom_kill 均为零;所有者、SDK 线程和 origin 正常关闭。该失败仍没有服务端导出细分轨迹,不能仅凭加长期限判断具体计算瓶颈;也没有证明完整负载或默认配置通过。原始记录在 socket-3x1m-trio-sqlite-16g-explicit-heavy/,独立复核为同目录上级的 reviewed-explicit-socket-failure.json,原始期限及未完成字段保持不变。
补充观测后的冻结 369162c 在同一 3×1,000,000、Trio SDK / SQLite、4 CPU、8 GiB、swap=0 档位保留公共 HTTP 默认值,再次以 SDK 等待响应头超时失败。实际服务端导出工作线程持续 310.10 秒,其中线程 CPU 时间 155.10 秒;SDK 在 180.17 秒先结束,服务端工作返回后 ASGI 才接纳 503 响应。该发送记录不能证明已超时的 SDK 收到 503。10,000 项批量完成用时 16.25 秒,实际发生在更新解析之前;SDK 与服务端导出均和两个解析调用重叠,与更新 commit/flush 没有相交记录,不能把宏观并发窗口当作这些操作都已重叠。
该次 SDK 线程返回后 watch 已为零;服务关闭前仍有一个活动请求,最终活动请求与 watch 均为零。Client 关闭等待 48.02 秒,随后 Uvicorn 退出等待 78.05 秒,合计 drain/close 126.61 秒。整个子进程用时 1739.39 秒、退出码 1;采样峰值 RSS 为 5,686,386,688 bytes,cgroup 峰值 6,364,221,440 bytes,无 max / oom / oom_kill 事件。原始报告及 361 个冻结文件、66 个执行文件的复核位于 .local-data/performance/concurrent-observed-v5/socket-3x1m-trio-sqlite-8g-defaults/ 和 reviewed-sqlite-defaults.json。这是导出字节复用优化之前的测量,来源/flush 仍使用 3600 秒实验预算,只有 socket 阶段;不能作为 2d94687 的性能、完整 all 阶段或原生其他平台的验收结果。
同一冻结 369162c、规模、资源和默认 HTTP 配置的 DuckDB / asyncio SDK 对照也失败:批量完成用时 15.37 秒,SDK 导出在 180.19 秒超时;服务端导出工作持续 295.91 秒、线程 CPU 150.94 秒,工作返回后 ASGI 才接纳 503。SDK 关闭后 watch 为零,服务关闭前一个请求仍在运行,最终请求与 watch 均清零;drain/close 为 113.09 秒。整个子进程用时 1890.11 秒、退出码 1,采样峰值 RSS 为 5,784,256,512 bytes,cgroup 峰值 6,311,088,128 bytes,无 max / oom / oom_kill 事件。来源版本、预算、阶段和响应接收限制与前一对照相同;原始报告及独立复核为上述目录的 socket-3x1m-asyncio-duckdb-8g-defaults/ 和 reviewed-duckdb-defaults.json。
加入 payload 字节复用后的冻结 4aab800 在相同 3×1,000,000、4 CPU、8 GiB、公共 HTTP 默认参数下,两种数据库的单 socket 对照仍失败。SQLite / Trio 的服务端导出为 265.77 秒、线程 CPU 116.12 秒,SDK 在 180.18 秒超时;DuckDB / asyncio 分别为 261.48、122.38 和 180.29 秒。两者均在导出工作返回后才有迟到的 ASGI 503,最终 watch、活动请求和拥有的资源完成清理。来源/flush 仍为 3600 秒实验预算;没有执行 core 阶段。原始失败与逐文件、响应和清理复核位于 .local-data/performance/concurrent-export-reuse-v6/,不能视为后续原生网络排序或记录分块编码的实际规模结果。
导出记录分块编码另与冻结 cce7b95 做了相同输入、同一进程、交错各三次的实际实现对照:3×10,000 条离线支持,完整结果均为 4,118,869 字节,原始中位耗时 0.56303 秒,分块实现 0.35103 秒,约减少 37.7%。完整规范字节、标准库 SHA-256 和持久化流式摘要独立一致;通用编码与导入校验保持原路径。记录块按保守上界限制在 64 KiB 编码预算内,原 payload 字典树、完整输出缓冲及 Unicode 临时存储仍存在。报告与实际源文件校验在 .local-data/performance/export-record-chunks-cce7b95/production/。该测量为 Linux x64、CPython 3.11、CPU 24–27 的小规模对照,机器同时运行其他验收;不证明三百万条的耗时、RSS、默认截止或完整并发验收通过。
冻结 cce7b95 的 SQLite / Trio 完整 all 实验在 3×1,000,000、4 CPU、16 GiB、swap=0 条件下,3600.93 秒后被整次运行看门狗以 SIGKILL 终止。初始加载与 flush 的合计阶段为 1294.88 秒;最后保存的检查点仍在第一轮并发更新,core 和 socket 均未完成,不能把这个结果归因于 HTTP 请求超时或声称正常取消清理成功。采样 RSS 峰值为 9,766,596,608 bytes,cgroup 峰值为 10,479,796,224 bytes,max / oom / oom_kill 均为零;半内存规划余量也未满足。旧运行器将同一 3600 秒同时用于整次监督和来源/flush 覆盖,此次结果不能证明产品的 1200 / 600 秒操作默认值。原始失败和 362 个冻结文件、66 个执行文件的独立复核保存在 .local-data/performance/concurrent-full-cce7b95-v7/;它早于 d60b122 分块编码优化,不应当作后继实现的规模结果。