# Redis + 实时数据架构 > 更新: 2026-05-22 — 修正 Redis key 命名和刷新间隔 ## 架构 ``` Agent(60s心跳) → Redis heartbeat:{id} (HSET, TTL=600s) → API 即时返回 ↑ heartbeat_flush(10min) → MySQL (历史快照) ``` ## 数据分布 | 数据 | Redis Key | 类型 | TTL | 用途 | |------|-----------|------|-----|------| | 心跳数据 | `heartbeat:{server_id}` | HSET | 600s | is_online, system_info, agent_version, last_heartbeat | | 告警标记 | `alerts:{server_id}` | SET | 3600s | 服务器处于告警状态 | | 告警广播 | `nexus:alerts` | Pub/Sub | — | WebSocket 跨 worker 告警推送 | | 推送进度 | `sync:progress:{op}:{ts}` | STRING | — | 批量推送进度 | | 名称/IP/密码/配置 | — (MySQL) | — | 永久 | 写少读多,不需要缓存 | ## 实现点 1. **连接池**: `redis.asyncio.BlockingConnectionPool` (ADR-008),启动强校验 (ADR-009) 2. **心跳写入**: Agent `POST /api/agent/heartbeat` → `HSET heartbeat:{id}` + TTL 续期 3. **批量刷新**: heartbeat_flush 每 10min → SCAN `heartbeat:*` → MySQL `UPDATE servers` 4. **API /servers**: MySQL 查基础信息 + Redis `HGETALL heartbeat:{id}` 合并实时状态 5. **API /stats**: MySQL COUNT + Redis `EXISTS alerts:{id}` 统计告警数 6. **健康检测**: Redis `HGETALL heartbeat:{id}` 不存在或 is_online=False → 离线 7. **告警推送**: WebSocket broadcast (内存 + Redis Pub/Sub 两层, ADR-010) + Telegram 8. **告警冷却**: Redis `SETNX alerts:{id}` TTL=3600s 防重复告警 9. **Dashboard**: WebSocket 实时更新,收到 alert/recovery/system 事件时刷新统计 ## Redis Key 完整规范 | Key 模式 | 类型 | TTL | 写入者 | 读取者 | |----------|------|-----|--------|--------| | `heartbeat:{server_id}` | HSET | 600s | agent.py | servers.py, heartbeat_flush.py | | `alerts:{server_id}` | SET | 3600s | agent.py | servers.py (stats) | | `nexus:alerts` | Pub/Sub | — | websocket.py | websocket.py (跨 worker) | ### heartbeat:{server_id} HSET 字段 | 字段 | 类型 | 说明 | |------|------|------| | is_online | string ("True"/"False") | 在线状态 | | system_info | string (JSON) | 系统信息 (CPU/内存/磁盘/OS) | | agent_version | string | Agent 版本号 | | last_heartbeat | string (ISO8601) | 最后心跳时间 |