SOP —— 只读探测批量化(同主机拼 shell + 主机间并发 + 进程内缓存)¶
变更日期:2026-10-08 | 工程:
monitoring-p2-20261001关联:backup/probe-batch-20261008/(备份台账)| 运行见同目录 RUNBOOK.md
目录¶
1. 背景¶
本工程的只读探测存在两类低效:
- 主机间串行:
utils/precheck.py::_check_hosts对 16 台集群外主机逐台ssh.run, 每台一次完整握手/执行,墙钟 ≈ 各台耗时之和。 - 同主机多次往返:
modules/host_filebeat.py::converge_one对同一主机串行发起 3 次只读探测(包probe_pkg→ 配置probe_config→ 服务probe_service), 3 次握手只为取 3 条短命令。deployer.py的cmd_verify/cmd_drift同样逐台串行。
共享库 ~/py_public_modules/precheck_module.py 已提供两件通用能力(本次不改共享库):
build_probe_shell(probes)/parse_probe_output(raw, keys):把{键: 命令}拼成一段 shell(每段echo '@@键'→ 命令 →echo "@@rc_键=$?"),逐条退出码不失真;ProbeBatch(ssh_exec):collect([...])只记录命令 →prefetch()每台一条 shell (主机间并发)→ 之后run(host, cmd)命中缓存;未预取的命令自动回落逐条下发, 语义与改造前完全一致。
2. 目标¶
| 项 | 目标 | 判据 |
|---|---|---|
| 报告不变 | precheck 报告逐项与改造前逐字一致 |
两次运行互 diff + 与改造前基线 diff 均为空(忽略时间戳) |
| 三态不变 | probe_pkg/config/service 的 done/pending/unknown 与返回文案不变 |
16 台逐台「串行 vs 批量」两两比对,mismatch=0 |
| 往返下降 | converge_one 每台 3 次 → 1 次;跨主机循环并发 |
计数 harness:converge 48 → 16;precheck 墙钟 7.7s → 2.7s |
| 顺序不变 | 报告行与 drift/verify 清单顺序与串行版一致 |
ThreadPoolExecutor.map 保序 / 并发取回后按原顺序 add |
3. 前置条件¶
| # | 条件 | 说明 |
|---|---|---|
| 1 | 工程 venv 且 py_public_modules.pth 生效 |
python -c "import precheck_module" 可通 |
| 2 | 16 台集群外主机 SSH 可达 | root 免密;本批实测全部可达 |
| 3 | 改前基线报告 | 改造前跑一次 main.py precheck 落 reports/,供逐项比对 |
| 4 | 备份 | backup/probe-batch-20261008/ 存三份 .bak(600) |
4. 影响范围¶
| 对象 | 动作 | 是否停服 | 是否触碰远端 |
|---|---|---|---|
utils/precheck.py |
_check_hosts 主机间并发、保序汇总 |
否 | 否(只读) |
modules/host_filebeat.py |
probe_* 加可选 exec_ssh;converge_one 三探测合并为一条 shell |
否 | 否(只读路径);变更类命令(install/write/restart)仍逐条串行 |
deployer.py |
cmd_verify / cmd_drift 跨主机只读循环并发 + 合并 |
否 | 否(只读) |
边界:仅只读探测可并发/合并;
rm、systemctl restart|reload、写文件、dnf install等变更类命令保持逐条串行,未被并入任何批量 shell。
5. 分步操作¶
实现体改动(详见各文件注释);以下为关键点:
_check_hosts:把每台的ssh.run(script)收敛为一个_probe(node),用ThreadPoolExecutor(max_workers=min(8, N)).map(...)保序取回,再按原顺序处理, 报告行与串行版逐字一致。probe_pkg/config/service:新增exec_ssh=None形参,内部改走(exec_ssh or self.ssh).run(...);默认行为不变,既有调用方无需改动。converge_one:先render_config得到expected,用ProbeBatch(self.ssh)collect三个探测 →prefetch一次取回 → 后续三次调用命中缓存。 缓存键 =(host, 命令原文),故三个探测的命令文本由配置确定性派生、预取与调用逐字相同。cmd_verify/cmd_drift:collect全主机 →prefetch→ 按原顺序回填problems/drift/unknown。
⚠ 【新增坑·必读】
probe_pkg的rpm -q --qf '%{VERSION}'/dpkg-query -W -f='${Version}'输出无换行,在批量 shell 里会与紧随其后的echo "@@rc_p0=$?"粘成一行 (8.19.0@@rc_p0=0),使退出码行不匹配、被parse_probe_output判为unknown。 修复:格式串改为'%{VERSION}\n'/'${Version}\n'(值后自带换行)。这是既有文档 「RPM--qf粘行坑」在批量化下的新表现形式。
6. 验证¶
工程 venv 下执行:
cd /home/rain/Documents/k8s_ins/monitoring-p2-20261001
.venv/bin/python -c "import deployer, utils.precheck, modules.host_filebeat" # 导入冒烟
.venv/bin/python main.py precheck && .venv/bin/python main.py precheck # 两次回归
.venv/bin/python main.py drift ; .venv/bin/python main.py verify # 只读路径
实测原始输出(2026-10-08):
- 导入冒烟:
import smoke OK,语言诊断 0 条。 - 两次
precheck(135...报告):diff(忽略时间戳)→ IDENTICAL; 与改造前基线reports/precheck-20261008-133525.mddiff → IDENTICAL。 - 逐台三态等价:串行
serial_calls=48vs 批量batch_calls=16,mismatch_count=0(rpm 主机.16与 deb 主机.249样例均为done/pending/done)。 driftrc=0、verifyrc=0;批量 shell 输出示例:@@p0\n8.19.0\n@@rc_p0=0(解析正确)。- 循环往返计数:
converge48 → 16;precheck17(本就 1 台 1 次,靠并发降墙钟 7.698s → 2.744s)。
7. 回滚¶
改动全在操作机 Python 逻辑、未触远端、未改配置/清单,回滚即覆盖回原文件:
cd /home/rain/Documents/k8s_ins/monitoring-p2-20261001
cp backup/probe-batch-20261008/utils/precheck.py.bak.20261008-134056 utils/precheck.py
cp backup/probe-batch-20261008/modules/host_filebeat.py.bak.20261008-134056 modules/host_filebeat.py
cp backup/probe-batch-20261008/deployer.py.bak.20261008-134056 deployer.py
回滚后复跑 main.py precheck 应仍为「无 BLOCK 项」。
8. 风险说明¶
| 风险 | 评估 | 缓解 |
|---|---|---|
| 预取时机早于 install / write-config | converge_one 在任何变更前取回三态。分析:install 不改 filebeat.yml 内容判定(缺失/变化均为 pending)、不改服务运行态;write-config 不启动服务。故决策与最终态不变 |
逐台串行/批量两两比对 mismatch=0;_install_pkg / write-config / restart 仍逐条串行,未被批量吞并 |
| 命令文本逐字一致 | 三探测命令均由配置确定性派生,collect 与调用处同源 |
缓存未命中即回落逐条,结论不变(仅无收益) |
| 并发下的 SSH 连接池 | SSHRunner.run 按 host 取连接,主机间并发互不干扰 |
实测 16 台并发 + verify/drift 均正常 |
nested ThreadPoolExecutor |
converge_all(5 并发)× 每台 ProbeBatch.prefetch(单台 1 worker) |
单台仅 1 worker,无放大;实测通过 |
尚未在真实 deploy(非 dry-run)全链路验证 |
仅对只读路径(precheck/drift/verify/converge dry-run)取证 | 变更类命令未改动;建议下次变更窗口首跑 deploy --limit <单台> 观察 |
来源:
/home/rain/Documents/k8s_ins/monitoring-p2-20261001/docs/SOP-parallel-probe.md| 最后更新:2026-10-08 13:46(由build/sync.py同步,请勿在站点侧修改)