Redis Cluster 发布安全负向门禁诊断¶
日期:2026-08-23 状态:已修复并经真实 Docker Cluster 验证
缺陷摘要¶
assert_redis_runtime_safe 的纯函数用例已验证 INFO cluster 中
cluster_enabled:1 会返回 ClusterNotStandalone,但此前没有真实三节点 Redis
Cluster 门禁。发布检查可能因 Redis 版本、Compose 网络、INFO 实际输出或开发放宽
开关的调用路径差异而失效,却仍被文本单测掩盖。
已验证假设¶
- 生产函数先调用
validate_cluster_info,再判断开发放宽开关。 - 证据:
crates/qim-common/src/redis_runtime.rs的assert_redis_runtime_safe先读取INFO cluster,只有 standalone 后才允许QIM_REDIS_ALLOW_UNSAFE_DEV=1跳过 AOF/noeviction 检查。 - 结论:运行时契约正确;缺口是没有真实环境回归。
- 开发放宽开关只允许 loopback/localhost/Unix endpoint。
- 证据:同文件的
unsafe_dev_override_enabled。 - 结论:负向门禁必须从 loopback 暴露的真实 Cluster 节点连接,并以该开关为
1调用生产函数,不能用伪造的INFO字符串代替。
根因¶
根因是测试层只有解析级断言,没有覆盖“独立三节点 Cluster 已形成 + 通过真实连接执行 生产安全检查”的部署事实。此项不是 Redis runtime 实现缺陷,故不修改生产逻辑。
修复边界¶
- 新增独立 Compose 编排、脚本和 ignored Rust 集成测试。
- 固定
QIM_REDIS_ALLOW_UNSAFE_DEV=1,测试仍期望RedisRuntimeError::ClusterNotStandalone。 - 不修改
compose.integration.yml、scripts/integration/{lib,wait}.sh或 Redis store/runtime 代码。
失败语义¶
缺 Docker/Compose/daemon、节点未就绪、redis-cli --cluster create 失败、Cluster 未达到
cluster_state:ok/16384 slots/三个 connected master、端口无法解析或 Rust 测试失败,均使
脚本退出非零。没有 skip、模拟 Cluster 或成功回退到 standalone Redis。
验证结果¶
2026-08-23 在本机 Docker 中执行:
scripts/integration/redis-cluster-negative.sh
脚本创建项目 qim-redis-cluster-negative-u1000-1787496259-769134,redis-cli
确认三个 master 覆盖 16384 slots;以自动分配的 127.0.0.1:1026 执行:
QIM_REDIS_ALLOW_UNSAFE_DEV=1 cargo test --locked -p qim-common \
--test redis_cluster_rejection -- --ignored --exact \
redis_cluster_is_rejected_even_when_unsafe_dev_is_enabled
结果为 1 passed; 0 failed,脚本随后仅销毁该项目的三个容器、三个卷和一个网络。