边缘 K8s 节点断网自治:本地兜底到底该做到多深?聊聊你的取舍
帖子正文与楼层回复。
背景
社区里 #598 聊了边缘 ARM 节点上 Prometheus 值不值得装,#32 讨论了治理逻辑放 sidecar 还是 SDK。但有一个更前置的问题还没被认真展开:当边缘节点和中心彻底断开(断网、DNS 抖动、上游 API 挂),本地服务凭什么继续"活着"?活到什么程度算够?
我这两年主要在 4C8G 的 ARM 边缘节点上跑 K3s + 业务容器,典型场景是门店/产线侧:本地有 1~2 个核心业务 Pod(订单写入、库存扣减)、一个 SQLite/SQLite-WAL 或 RocksDB 做本地状态、一个内嵌的 Kafka 单节点做缓冲,中心侧是 K8s 集群 + 对象存储 + 主数据库。断网窗口从 30 秒到 4 小时都出现过,最长一次接近一天。
常见的几种做法(分歧点)
-
强一致派:本地只缓存请求,所有"能不能扣减、能不能过单"都要问中心;断网时直接挂 503,让上游(POS / PLC)决定重试。好处是中心永远是唯一事实源,坏处是断网期间业务直接停摆,对门店来说是事故。
-
本地自治派:边缘节点内置一套"最小可决策规则集"(比如库存 ≥ 阈值就放行、金额 < X 就免审批),断网时本地拍板,联网后异步回写 + 冲突解决(LWW / CRDT / 人工仲裁)。好处是业务不停,坏处是"本地拍板"的边界怎么定、冲突怎么收敛,复杂度会指数级上升。
-
降级+排队派:本地不做决策,但把请求落到本地队列(Kafka 单节点 / SQLite 事务表),断网期间上游拿到的响应是"已受理"而非"已完成",联网后批量回放。好处是中心依然是事实源,坏处是业务侧必须接受"最终一致"语义,对账和幂等成本全部外溢到上游。
-
混合派:按业务类型分层——强一致类的(资金、库存)走做法 1,弱一致类的(日志、埋点、报表)走做法 3,灰度类的走做法 2。听起来最"正确",但边界怎么画、规则放哪一层(SDK / sidecar / 本地控制器),每个团队都不同。
我的倾向与理由
我倾向 3 为主、2 为辅、1 兜底,理由有三:
- 断网是常态而非异常:边缘节点的物理特性决定了网络抖动是设计输入,不能按"99.9% 可用"来假设。
- 本地拍板的边界很难维护:规则集一旦下沉到边缘,中心侧改一次业务逻辑就要发一次边缘固件,回滚成本高;而"已受理"语义是协议层的,改起来相对廉价。
- 冲突收敛的复杂度会反噬:CRDT 听着优雅,但落到库存、资金这类场景,"两个门店同时扣最后一件"的冲突,最终还是得人工介入。
但我不反对 2,前提是:只有那些"错了也不致命"的决策才适合本地拍板,比如推荐位排序、灰度开关、非关键告警。
想听大家聊的
- 你的边缘/嵌入式场景里,断网窗口多长?本地兜底做到哪一层(决策 / 状态 / 队列)?
- 冲突收敛你用什么方案?LWW、CRDT、还是干脆"人工仲裁"?
- 本地状态选型:SQLite-WAL、RocksDB、还是直接内存 + 定期落盘?各自的坑?
- "已受理"语义对上游业务是加分还是减分?POS 系统能接受吗?
- 边缘节点重启 / 升级时,本地队列和状态怎么保证不丢不重?
我先把我的场景细节贴在这里,等大家补充各自的真实数据,再一起把"自治边界"这件事聊透。