Skip to content

fix(info): 删除硬编码假数据并接入真实 runtime、storage 与 Raft 状态 #410

Description

@AlexStocks

Bug 描述

INFO 当前返回大量硬编码值,与真实进程、配置、运行平台、Redis 8.8.1 兼容基线和 Raft 状态无关。监控系统、客户端和运维人员会把这些值当作服务事实,当前输出会提供错误的版本、OS、端口、PID、uptime 和 cluster 状态。

对比基线:

  • Rust Kiwi:main@3164d4a0fead580ac6701fb0595e50193c4edff9(2026-07-31)
  • kiwi-cpp:unstable@0fa4f1b95ff2f89873d06eb86de40532dd91d146;其 #176 也要求让 INFO 输出与 Redis 对齐

当前源码证据

InfoCmd::do_cmd() 不读取传入的 Storage,也没有 server/runtime/Raft 状态 provider,而是直接拼接常量:

  • redis_version:7.0.0,与项目固定的 Redis 8.8.1 兼容基线不一致;
  • os:Windowsmultiplexing_api:selectgcc_version:0.0.0,在 Linux/macOS 和当前 Tokio 架构下均不代表真实运行时;
  • process_id:1tcp_port:7379uptime_in_seconds:1executable:/path/to/kiwi-server,不读取实际进程和配置;
  • redis_mode:standalonecluster_enabled:0cluster_state:disabled,即使启用 OpenRaft 仍报告 standalone/disabled;
  • 未知 section 被静默降级为一小段 Server 信息,且 default 只返回 Server/Cluster 两节,没有建立 Redis 8.8.1 的 section 选择合同。

项目自己的兼容要求已经把 INFO 列为必须验证的发现接口,系统稳定门禁也要求持续记录 请求延迟、吞吐、资源、compaction stall 和 Raft commit/apply latency。当前 INFO 既不满足兼容发现,也不能作为运维观测入口。

与现有 Issue 的关系

当前没有开放 Issue 对 INFO 的硬编码错误和 Redis 8.8.1 section 合同负责。

建议设计

1. 注入只读状态 Provider

不要在 cmd crate 引入无边界全局变量。为 InfoCmd 注入只读、可测试的 ServerInfoProvider/等价接口,由 server startup 组合真实来源:

  • build identity:Kiwi 版本、Git SHA/build id、目标架构;
  • process identity:OS、PID、可执行文件、启动时间、实际监听端口、配置文件身份;
  • network/client:当前连接数、累计连接、拒绝/超时/协议错误;
  • storage/RocksDB:实例数、路径身份、内存/缓存、WAL、compaction、读写错误与 keyspace;
  • runtime/executor:queue、running worker、completed/failed/timed-out、queue wait/execution time;
  • Raft:是否启用、node id、role/leader、term、membership、last log/applied/snapshot、commit/apply latency 和 unhealthy 状态。

Provider 返回一次有边界的 snapshot;组装 INFO 时不得在每个字段重复获取锁、执行无界 RocksDB 扫描或发起网络 RPC。

2. 固定 Redis 8.8.1 section 合同

先用仓库规定的 exact Redis 8.8.1 Oracle 获取 INFO 的参数、section、默认集合、未知 section、字段格式和 RESP2/RESP3 返回类型证据,再实现 Kiwi 支持的 section。

至少分阶段覆盖:

  1. serverclientsstatspersistencereplication/clusterkeyspace
  2. memorycpucommandstatslatencystatserrorstats
  3. defaultalleverything 和多 section 组合。

对 Redis 有字段但 Kiwi 暂无等价来源的情况,应根据兼容证据决定“真实的零/状态值”或“暂不输出”,不得继续填入看似真实的常量。Kiwi 扩展字段使用稳定的 kiwi_* 命名并写入文档。

3. 安全和性能边界

  • 不输出 requirepass、完整命令参数、用户 key、凭据或未脱敏内部地址;
  • command/错误指标使用固定命令表和有界 label,不允许攻击者输入制造无界基数;
  • RocksDB property 获取必须有 timeout/缓存策略,单次 INFO 不得阻塞 storage runtime 或触发全库遍历;
  • 指标读取失败应在对应 section 显示可诊断状态或省略字段,不能退回硬编码假数据;
  • INFO 自身应继续是只读命令,不改变 Raft/storage 状态。

验证范围

命令级兼容测试

  • 用 exact Redis 8.8.1 对照无参数、单 section、多 section、defaultalleverything、未知 section 的 raw RESP;
  • RESP2/RESP3 返回均为正确的 bulk payload,CRLF、section header、字段分隔和顺序合同有测试;
  • INFO server 不再出现固定 7.0.0Windows、PID 1、端口 7379、uptime 1 或占位 executable。

真实进程测试

  • 在 Linux 随机端口启动 standalone,校验 PID、port、OS/arch、uptime 单调增长、配置身份和实际模式;
  • 建立/关闭客户端连接,验证 clients/stats 的真实变化;
  • 执行读写、错误、timeout 和 compaction/RocksDB 活动,验证相关 counter/latency 来自真实调用点;
  • 启动三节点 OpenRaft,验证 leader/follower、node id、term、membership、applied/snapshot 等字段与 Raft metrics 一致;
  • 重启后 PID/uptime 更新,持久化/复制状态仍与实际数据一致;
  • 未启用 Raft 时不得伪装 leader/cluster healthy;启用 Raft 时不得报告 standalone/disabled。

非目标

验收标准

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions