# R1.2.4 Kafka 周边内存调优任务报告

## 结论

在不改变纯 Kafka 实时/回放 SSE 架构的前提下，已将 NC01 Kafka broker、Strimzi Cluster Operator、Topic/User Entity Operator 的 JVM 与 Kubernetes 资源预算收敛到 `config/platform-infra/kafka.yaml`，并新增只针对显式 policy 的临时 SSE consumer group 自动回收。Kafka 状态、全部 topic/client、真实 producer/consumer smoke 和自动 CronJob 均已通过。

## 基线与归因

- 调整前 broker cgroup 约 1.13 GiB，Java PSS 约 1.06 GiB；JVM heap 已使用约 607 MiB，因此没有把上限冒险压到 512/768 MiB。
- 调整前 Entity Operator cgroup 约 706 MiB，Topic/User Operator Java PSS 各约 350 MiB。
- consumer group 共 4,359 至 4,360 个，其中 4,053 个同时满足 `hwlab-v03-cloud-api-sse-` 前缀、完整名称正则、`Empty` 状态和最小年龄；固定 projector group 不在 policy 范围。
- Decision Center 的历史 zombie 泄漏已由前序任务消除；本轮样本只剩 4 至 5 个分散 zombie，不再是主要物理内存来源。

## 实现

- broker 使用 YAML 声明的 1 GiB JVM heap 上限和 1,280 MiB Pod 上限；请求量与 xms 同样显式受控。
- Topic/User Operator 分别使用 192 MiB heap 上限和 384 MiB Pod 上限。
- Cluster Operator 的既有 384 MiB 预算由 owning YAML 显式接管，并通过受控 Kustomize patch 应用到官方 Strimzi manifest。
- 自动回收由 YAML 声明 schedule、image、Kafka CLI 绝对路径、deadline、批次上限和资源预算；CronJob 使用 `Forbid`，仅渲染 `automatic: true` policy。
- 回收脚本使用一次 `--describe --all-groups --state`、一次批量 `--delete --group ...` 和一次删除后复核，避免逐组启动 JVM 命令。
- `platform-infra kafka apply` 默认输出改为紧凑步骤表；group cleanup 默认只显示 10 条预览；status 新增 CronJob active/last success 和 Strimzi Pod readiness，避免过早报告 ready。

## 运行面证据

- server-side dry-run 四阶段全部成功，Strimzi CRD 接受 NodePool 和 Entity Operator JVM/resource 字段。
- 受控 apply 后 broker cgroup 降到约 664 至 732 MiB，Entity Operator 降到约 360 MiB。
- `platform-infra kafka validate --target NC01` 的 producer 与 consumer 均为 exit code 0，smoke payload hash 匹配且消息正文未披露。
- 手工 policy 批次删除 200/200 个 group，失败 0；总 group 数从 4,360 降到 4,160。
- 初版逐组自动 Job 在 YAML 的 300 秒 deadline 结束，未形成常驻进程；批量实现随后于 08:50:32 至 08:52:02 成功，下一轮于 08:53:36 成功。最终 CronJob 为 `ACTIVE=0`、`LAST_SUCCESS=2026-07-16T08:53:36Z`、schedule `*/10 * * * *`，总 group 数继续降到 4,101。
- 物理内存曾在 08:34 达到真实 `MemAvailable=4.3 GiB`，不含 swap；GC plan 当时正确返回无候选。
- 后续因 k3s-server 和 `web-terminal-7682` 活跃占用波动，`MemAvailable` 回落到约 3.6 至 3.9 GiB。一次 YAML allowlist cgroup reclaim 令 k3s/kubepods cgroup current 分别下降约 567 MiB/442 MiB，但并发业务在同一窗口重新占页，host `MemAvailable` 净变化约 -150 MiB，因此没有重复试错或扩大回收范围。

## 业务侧后续判断

- Kafka 是实时/回放事件权威，不能因内存压力废弃；本轮预算后约 1.0 GiB 的 broker+Entity 组合已进入合理范围。
- 最大长期优化对象是 k3s 控制面：样本中有约 595 个 Pod、397 个 PipelineRun、622 个 TaskRun，CI 历史对象会放大 informer/cache 与 containerd 开销，应由各 owning YAML 的 TTL/历史上限收敛。
- `web-terminal-7682` 单次样本约 1.19 GiB resident、1.4 GiB swap，`web-terminal-7683` 约 3.3 GiB swap；应按用户会话/活跃任务生命周期受控退役空闲 Codex session，而不是盲杀容器。
- Argo CD application controller 与 Tempo 各约 0.3 至 0.4 GiB，可通过应用对象规模、trace retention 和 compaction 的 owning YAML 继续优化，但不应在 Kafka PR 中越界修改。

## 验证

- `bash -n scripts/native/platform-infra/kafka-consumer-group-retention.sh`
- `bun scripts/cli.ts check --syntax-only`
- `bun scripts/cli.ts platform-infra kafka plan --target NC01`
- `bun scripts/cli.ts platform-infra kafka apply --target NC01 --dry-run`
- `bun scripts/cli.ts platform-infra kafka status --target NC01`
- `bun scripts/cli.ts platform-infra kafka validate --target NC01`
- `bun scripts/cli.ts platform-infra kafka groups cleanup --node NC01 --policy hwlab-cloud-api-sse --limit 200 --confirm`
- `bun scripts/cli.ts gc remote NC01 memory-distribution`
- `bun scripts/cli.ts gc remote NC01 plan --memory-pressure-only`
- `bun scripts/cli.ts gc remote NC01 run --confirm --memory-pressure-only`
- `git diff --check`

交付 PR：[pikasTech/unidesk#2301](https://github.com/pikasTech/unidesk/pull/2301)。
