- Move api-server design docs into 设计/ subdirectory - Move ios/web UI-UX audit reports into 已完成/ subdirectories - Rename 服务器凭据.md → 轻量云服务器凭据.md - Add 蜂驰云服务器凭据.md (120.53.227.155) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.7 KiB
7.7 KiB
source, updated
| source | updated |
|---|---|
| AI回答.md | 2026-05-09 |
知习 Redis 设计
Redis 在知习里不是"另一个 MySQL",它是系统的加速器和调度器。MySQL 存结果,Redis 管过程。
1. Redis 定位
Redis 不作为主数据库,只负责:
- 缓存
- 限流
- 队列(BullMQ)
- 临时任务状态
- 分布式锁
- 防重复提交
- AI 调用次数统计
- 短期 Token / 黑名单
- 通知任务调度
- 学习会话草稿
2. Key 命名规范
统一格式:
业务域:对象类型:对象ID:字段
示例:
cache:user:123:profile
rate:user:123:ai:daily:2026-05-09
lock:ai-analysis:session:987
job:ai-analysis:abc123:status
规则:
- 全部小写
- 用冒号
:分隔 - 从大范围到小范围
- userId、jobId、sessionId 明确写在 key 里
- 带日期的 key 用
YYYY-MM-DD - 所有临时 key 必须设置 TTL
3. Key 总表
缓存类
| Key | 用途 | TTL |
|---|---|---|
cache:user:{userId}:profile |
用户资料 | 5-10 分钟 |
cache:user:{userId}:preferences |
用户偏好设置 | 10 分钟 |
cache:user:{userId}:knowledge-bases |
用户知识库列表 | 3-5 分钟 |
cache:knowledge-base:{kbId}:summary |
知识库摘要 | 5 分钟 |
cache:review:user:{userId}:due-count |
到期复习数量 | 1-3 分钟 |
限流类
| Key | 用途 | TTL |
|---|---|---|
rate:user:{userId}:ai:daily:{date} |
用户每日 AI 调用次数 | 到当天结束或 24h |
rate:user:{userId}:feedback:hourly |
用户每小时反馈次数 | 1 小时 |
rate:ip:{ip}:request:{minute} |
IP 每分钟请求频率 | 60-120 秒 |
rate:ip:{ip}:login:{date} |
IP 每日登录尝试 | 10-30 分钟 |
分布式锁类
| Key | 用途 | TTL |
|---|---|---|
lock:ai-analysis:session:{sessionId} |
防止重复提交 AI 分析 | 60-300 秒 |
lock:ai-analysis:answer:{answerId} |
防止同回答重复分析 | 60-300 秒 |
lock:document-import:{importId} |
防止重复处理导入 | 5-30 分钟 |
lock:review-plan:user:{userId}:item:{itemId} |
防止重复生成复习计划 | 60-300 秒 |
lock:feedback:ip:{ip} |
防止 IP 刷反馈 | 60-300 秒 |
任务状态类
| Key | Value 示例 | TTL |
|---|---|---|
job:ai-analysis:{jobId}:status |
pending / processing / completed / failed |
24h |
job:ai-analysis:{jobId}:progress |
0-100 |
24h |
job:ai-analysis:{jobId}:error |
错误信息字符串 | 24h |
job:document-import:{importId}:status |
pending / parsing / chunking / generating / completed / failed |
24h |
job:document-import:{importId}:progress |
0-100 |
24h |
job:document-import:{importId}:message |
"正在提取关键知识点" |
24h |
job:document-import:{importId}:error |
错误信息字符串 | 24h |
会话临时状态类
| Key | 用途 | TTL |
|---|---|---|
session:learning:{sessionId}:heartbeat |
学习会话心跳 | 30 分钟 |
session:learning:{sessionId}:current-step |
当前学习步骤 | 2 小时 |
session:active-recall:{sessionId}:draft |
回答草稿暂存 | 1-24 小时 |
Token / 黑名单
| Key | 用途 | TTL |
|---|---|---|
auth:refresh-token:blacklist:{tokenId} |
注销后刷新 Token 失效 | 到 token 过期 |
auth:access-token:blacklist:{jwtId} |
注销后 JWT 失效 | 到 token 过期 |
Set 类(可选)
| Key | 用途 |
|---|---|
set:user:{userId}:reviewed-items:{date} |
当天已复习项去重 |
4. Redis 数据类型选择
| 类型 | 用途 | 示例 |
|---|---|---|
| String | 最常用:缓存 JSON、计数器、状态、锁 | rate:user:123:ai:daily:2026-05-09 = 8 |
| Hash | 可选,任务多字段频繁更新的场景 | job:ai-analysis:1001 → status=processing, progress=40 |
| List/Stream | 队列,BullMQ 自动管理,不需要手动操作 | - |
| Set | 去重,如当天已复习项集合 | set:user:123:reviewed-items:2026-05-09 |
| Sorted Set | 后期按时间排序的复习调度,v0.1 先不做 | - |
5. 核心流程中 Redis 与 MySQL 的配合
5.1 AI 分析流程
1. MySQL 创建 ai_analysis_jobs
2. Redis 加入 ai-analysis 队列(BullMQ)
3. Redis 存 job:xxx:status = processing
4. Worker 调用 AI
5. MySQL 写 ai_analysis_results
6. MySQL 写 focus_items
7. MySQL 写 review_cards
8. Redis 存 job:xxx:status = completed
9. MySQL 写 notifications
5.2 资料导入流程
1. MySQL 创建 document_imports
2. Redis 加入 document-import 队列(BullMQ)
3. Redis 存导入进度
4. Worker 解析文件
5. MySQL 写 knowledge_items
6. MySQL 更新 document_imports 为 success
7. Redis 存状态 completed
5.3 学习活跃图流程
1. 用户完成学习动作
2. MySQL 写 learning_records
3. MySQL 更新 daily_learning_activities
4. Redis 可短期缓存今日活跃统计
5. App 查询活跃图优先查 MySQL,必要时加缓存
6. BullMQ 队列
BullMQ 自动管理 Redis key,不需要手动建。建议预留 3 个队列:
| 队列名 | 任务数据 | 处理逻辑 |
|---|---|---|
ai-analysis |
{ jobId, userId, sessionId, answerId, jobType } |
读取回答 → 调 AI → 写结果 → 生成待巩固项 → 生成复习卡片 → 发通知 |
document-import |
{ importId, userId, knowledgeBaseId, sourceType } |
解析文件 → 提取文本 → 分段 → 生成知识点 → 写 knowledge_items → 更新状态 |
notification |
{ userId, type, title, data } |
写 notifications 表,后续可扩展 APNs 推送 |
7. 哪些绝对不能只放 Redis
以下全部必须写 MySQL,Redis 只能做缓存,不是唯一来源:
用户资料 → users, user_profiles
知识库内容 → knowledge_bases
知识点内容 → knowledge_items
学习记录 → learning_records
主动回忆回答 → active_recall_answers
AI 分析结果 → ai_analysis_results
待巩固项 → focus_items
复习卡片 → review_cards
复习记录 → review_logs
学习活跃记录 → daily_learning_activities
通知记录 → notifications
用户设置 → user_preferences
协议同意记录 → user_consents
8. v0.1 Redis 最小落地范围
必须做
1. Redis 连接
2. /health 检查 Redis
3. RedisModule + RedisService(get/set/del/exists/expire/ttl/incr/setNx/lock/unlock)
4. AI 每日调用限流(rate:user:{userId}:ai:daily:{date})
5. AI 分析队列(BullMQ ai-analysis)
6. AI 分析任务状态(job:ai-analysis:{jobId}:status/progress/error)
7. 防重复提交锁(lock:ai-analysis:session:{sessionId})
8. document-import 队列预留(BullMQ document-import)
9. notification 队列预留(BullMQ notification)
暂时不做
复杂缓存策略
Sorted Set 复习调度
复杂分布式任务调度
全量通知推送(APNs)
复杂排行榜
9. RedisService 方法清单
get(key) — 读取
set(key, value) — 写入
del(key) — 删除
exists(key) — 判断存在
expire(key, ttl) — 设置过期
ttl(key) — 查看剩余时间
incr(key) — 自增(限流计数)
setNx(key, value) — 不存在才写入(锁)
lock(key, ttl) — 获取分布式锁,返回 token
unlock(key, token) — 释放锁,校验 token,防止误删
锁的实现注意:
- 锁必须设置 TTL
- 解锁时必须校验 value/token,不能误删别人的锁
- 锁的 value 用随机 token,解锁时比对
10. 一句话总结
Redis 在知习里不是"另一个 MySQL",它是系统的加速器和调度器。MySQL 存结果,Redis 管过程。