([Files][1])([Files][2])([Files][3])([Files][4])([Files][5]) 可以。下面我把 **知习后端 Redis 设计** 单独整理一版。 你可以把它理解成: ```text MySQL:长期真实数据,必须可靠保存 Redis:短期状态、缓存、队列、限流、锁、任务进度 ``` Redis **不需要建表**,需要设计的是: ```text 1. Redis 用在哪些场景 2. Key 怎么命名 3. Value 存什么 4. 过期时间多久 5. 哪些数据绝对不能只放 Redis ``` --- # 一、Redis 在知习里的定位 Redis 不作为主数据库。 它主要负责: ```text 1. 缓存 2. 限流 3. 队列 4. 临时任务状态 5. 分布式锁 6. 防重复提交 7. AI 调用次数统计 8. 短期 token / 黑名单 9. 通知任务调度 ``` 核心业务数据仍然必须写入 MySQL: ```text 用户 知识库 知识点 学习记录 主动回忆回答 AI 分析结果 待巩固项 复习计划 学习活跃记录 通知记录 用户设置 ``` --- # 二、Redis Key 命名规范 建议统一用这种格式: ```text 业务域:对象类型:对象ID:字段 ``` 例如: ```text cache:user:123:profile rate:user:123:ai:daily:2026-05-09 lock:ai-analysis:session:987 job:ai-analysis:abc123:status ``` 统一规则: ```text 1. 全部小写 2. 用冒号 : 分隔 3. 从大范围到小范围 4. userId、jobId、sessionId 明确写在 key 里 5. 带日期的 key 用 YYYY-MM-DD 6. 所有临时 key 必须设置 TTL ``` --- # 三、Redis 主要使用场景 ## 1. 缓存 Cache 用于缓存高频读取的数据,减少 MySQL 压力。 ### 用户资料缓存 ```text key: cache:user:{userId}:profile value: { "id": 123, "nickname": "李明", "avatarUrl": null, "learningIdentity": "系统学习者", "learningDirection": "认知科学" } ttl: 5-10 分钟 ``` ### 用户知识库列表缓存 ```text key: cache:user:{userId}:knowledge-bases value: [ { "id": 1, "title": "认知心理学", "itemCount": 42 } ] ttl: 3-5 分钟 ``` ### 当前用户设置缓存 ```text key: cache:user:{userId}:preferences ttl: 10 分钟 ``` 注意: ```text 缓存可以丢 MySQL 不能丢 缓存更新不及时也没关系,但关键业务查询必须以 MySQL 为准 ``` --- ## 2. 限流 Rate Limit 用于控制请求频率和 AI 成本。 ### 用户每日 AI 调用次数 ```text key: rate:user:{userId}:ai:daily:{date} example: rate:user:123:ai:daily:2026-05-09 value: 8 ttl: 到当天结束,或者 24 小时 ``` 用途: ```text 限制每天 AI 分析次数 限制生成回忆测试次数 限制找薄弱知识点次数 ``` --- ### IP 请求频率限制 ```text key: rate:ip:{ip}:request:{minute} example: rate:ip:1.2.3.4:request:2026-05-09T10:35 value: 42 ttl: 60-120 秒 ``` 用途: ```text 防刷接口 防反馈表单乱提交 防登录接口暴力请求 ``` --- ### 登录尝试次数 ```text key: rate:login:{ip}:{date} ttl: 10-30 分钟 ``` Apple 登录一般问题不大,但后面如果有邮箱登录、验证码登录,这个会用到。 --- ## 3. 分布式锁 Lock 用于防止重复提交。 ### 防止重复 AI 分析 ```text key: lock:ai-analysis:session:{sessionId} example: lock:ai-analysis:session:987 value: randomToken ttl: 60-300 秒 ``` 场景: ```text 用户连续点两次“提交 AI 分析” 后端只允许创建一个分析任务 ``` --- ### 防止重复导入资料 ```text key: lock:document-import:{importId} ttl: 5-30 分钟 ``` --- ### 防止重复生成复习计划 ```text key: lock:review-plan:user:{userId}:item:{itemId} ttl: 60-300 秒 ``` 注意: ```text 锁一定要设置 TTL 解锁时要校验 value,不能误删别人的锁 ``` --- ## 4. AI 分析任务状态 AI 分析建议用异步任务。 流程: ```text App 提交回答 → 后端创建 ai_analysis_jobs 记录 → 加入 Redis 队列 → 返回 jobId → Worker 调用 AI → 结果写入 MySQL → Redis 状态改为 completed ``` ### 任务状态 key ```text key: job:ai-analysis:{jobId}:status value: pending / processing / completed / failed ttl: 24 小时 ``` ### 任务进度 key ```text key: job:ai-analysis:{jobId}:progress value: 0-100 ttl: 24 小时 ``` ### 任务错误信息 ```text key: job:ai-analysis:{jobId}:error value: "AI provider timeout" ttl: 24 小时 ``` 注意: ```text Redis 只存临时状态 最终任务记录和分析结果必须写入 MySQL: ai_analysis_jobs ai_analysis_results focus_items review_cards ``` --- ## 5. 资料导入任务状态 导入资料也建议异步。 场景: ```text 上传 PDF 粘贴长文本 导入链接 AI 解析生成知识点 ``` ### 导入任务状态 ```text key: job:document-import:{importId}:status value: pending / parsing / chunking / generating / completed / failed ttl: 24 小时 ``` ### 导入进度 ```text key: job:document-import:{importId}:progress value: 0-100 ttl: 24 小时 ``` ### 导入处理中提示 ```text key: job:document-import:{importId}:message value: "正在提取关键知识点" ttl: 24 小时 ``` 最终结果写入 MySQL: ```text document_imports uploaded_files knowledge_items knowledge_item_relations tags ``` --- ## 6. BullMQ 队列 如果后端是 Node.js / NestJS,建议用 BullMQ。 队列由 BullMQ 自动管理 Redis key,不需要你自己建。 建议预留 3 个队列: ```text ai-analysis document-import notification ``` --- ### ai-analysis 队列 任务数据: ```json { "jobId": 123, "userId": 456, "sessionId": 789, "answerId": 1001, "jobType": "active_recall_analysis" } ``` 处理逻辑: ```text 读取用户回答 调用 AI 生成分析结果 写入 ai_analysis_results 生成 focus_items 生成 review_cards 发送通知 ``` --- ### document-import 队列 任务数据: ```json { "importId": 123, "userId": 456, "knowledgeBaseId": 789, "sourceType": "file" } ``` 处理逻辑: ```text 解析文件 提取文本 分段 生成知识点 写入 knowledge_items 更新 document_imports 状态 ``` --- ### notification 队列 任务数据: ```json { "userId": 456, "type": "review_due", "title": "8 张卡片今日到期复习", "data": { "reviewCount": 8 } } ``` 处理逻辑: ```text 写入 notifications 表 后面可扩展推送 APNs ``` --- # 四、Redis Key 总表 ## 缓存类 ```text cache:user:{userId}:profile cache:user:{userId}:preferences cache:user:{userId}:knowledge-bases cache:knowledge-base:{knowledgeBaseId}:summary cache:review:user:{userId}:due-count ``` --- ## 限流类 ```text rate:user:{userId}:ai:daily:{date} rate:user:{userId}:feedback:hourly rate:ip:{ip}:request:{minute} rate:ip:{ip}:login:{date} ``` --- ## 锁类 ```text lock:ai-analysis:session:{sessionId} lock:ai-analysis:answer:{answerId} lock:document-import:{importId} lock:review-plan:user:{userId}:item:{itemId} lock:feedback:ip:{ip} ``` --- ## 任务状态类 ```text job:ai-analysis:{jobId}:status job:ai-analysis:{jobId}:progress job:ai-analysis:{jobId}:error job:document-import:{importId}:status job:document-import:{importId}:progress job:document-import:{importId}:message job:document-import:{importId}:error ``` --- ## 会话临时状态 ```text session:learning:{sessionId}:heartbeat session:learning:{sessionId}:current-step session:active-recall:{sessionId}:draft ``` 例如用户正在写回答,可以短期保存草稿: ```text key: session:active-recall:{sessionId}:draft ttl: 1-24 小时 ``` 最终提交后还是写 MySQL。 --- ## Token / 黑名单 ```text auth:refresh-token:blacklist:{tokenId} auth:access-token:blacklist:{jwtId} ``` 退出登录或注销账号时可用。 --- # 五、TTL 建议 ```text 用户资料缓存:5-10 分钟 知识库列表缓存:3-5 分钟 AI 每日限流:到当天结束或 24 小时 IP 请求限流:60-120 秒 登录尝试限流:10-30 分钟 AI 分析任务状态:24 小时 资料导入任务状态:24 小时 分布式锁:60 秒到 30 分钟,按任务类型决定 学习草稿:1-24 小时 Token 黑名单:到 token 原本过期时间 ``` --- # 六、Redis 数据类型建议 ## String 最常用。 用于: ```text 缓存 JSON 计数器 状态 锁 ``` 示例: ```text rate:user:123:ai:daily:2026-05-09 = 8 job:ai-analysis:1001:status = processing ``` --- ## Hash 可选,用于对象字段更新频繁的场景。 例如: ```text job:ai-analysis:1001 status = processing progress = 40 message = 正在分析薄弱点 ``` v0.1 也可以先用 String 多 key,简单直接。 --- ## List / Stream 队列相关,但如果使用 BullMQ,不需要自己操作。 --- ## Set 可选。 比如记录某天处理过的学习项: ```text set:user:{userId}:reviewed-items:{date} ``` --- ## Sorted Set 后期可用于按时间排序的任务。 例如: ```text zset:review:due ``` 但 v0.1 可以先不做,复习到期直接查 MySQL。 --- # 七、哪些不要放 Redis 不要把这些只放 Redis: ```text 用户资料 知识库内容 知识点内容 学习记录 主动回忆回答 AI 分析结果 待巩固项 复习卡片 复习记录 学习活跃记录 通知记录 用户设置 协议同意记录 ``` 这些全部要写 MySQL。 Redis 可以缓存它们,但不是唯一来源。 --- # 八、Redis 和 MySQL 的典型组合流程 ## AI 分析流程 ```text 1. MySQL 创建 ai_analysis_jobs 2. Redis 加入 ai-analysis 队列 3. Redis 存 job 状态 processing 4. Worker 调用 AI 5. MySQL 写 ai_analysis_results 6. MySQL 写 focus_items 7. MySQL 写 review_cards 8. Redis 存 job 状态 completed 9. MySQL 写 notifications ``` --- ## 资料导入流程 ```text 1. MySQL 创建 document_imports 2. Redis 加入 document-import 队列 3. Redis 存导入进度 4. Worker 解析文件 5. MySQL 写 knowledge_items 6. MySQL 更新 document_imports 为 success 7. Redis 状态 completed ``` --- ## 学习活跃图流程 ```text 1. 用户完成学习动作 2. MySQL 写 learning_records 3. MySQL 更新 daily_learning_activities 4. Redis 可短期缓存今日活跃统计 5. App 查询活跃图时优先查 MySQL,必要时加缓存 ``` --- # 九、v0.1 Redis 最小落地范围 第一版不用把所有 Redis 场景都做完。 建议先做: ```text 1. Redis 连接 2. /health 检查 Redis 3. RedisService 4. AI 每日调用限流 5. AI 分析队列 6. AI 分析任务状态 7. 防重复提交锁 8. document-import 队列预留 9. notification 队列预留 ``` 暂时不做: ```text 复杂缓存策略 Sorted Set 复习调度 复杂分布式任务调度 全量通知推送 复杂排行榜 ``` --- # 十、给 Trae 的提示词 ```text 请为「知习」api-server 设计并接入 Redis。 注意: Redis 不需要像 MySQL 一样建表。 Redis 只用于缓存、限流、队列、临时状态、分布式锁、防重复提交和任务进度。 核心业务数据必须写入 MySQL,不能只存在 Redis。 请完成以下内容: 1. 基础接入 - docker-compose 增加 redis:7-alpine - 增加 RedisModule - 增加 RedisService - 支持 REDIS_HOST、REDIS_PORT、REDIS_PASSWORD、REDIS_DB、REDIS_URL - /health 检查 Redis 是否可用 2. RedisService 方法 - get - set - del - exists - expire - ttl - incr - setNx - lock - unlock 3. Key 命名规范 请创建文档 docs/redis-key-design.md,包含以下 key 规范: 缓存: cache:user:{userId}:profile cache:user:{userId}:preferences cache:user:{userId}:knowledge-bases 限流: rate:user:{userId}:ai:daily:{date} rate:ip:{ip}:request:{minute} rate:user:{userId}:feedback:hourly 锁: lock:ai-analysis:session:{sessionId} lock:ai-analysis:answer:{answerId} lock:document-import:{importId} lock:review-plan:user:{userId}:item:{itemId} 任务状态: job:ai-analysis:{jobId}:status job:ai-analysis:{jobId}:progress job:ai-analysis:{jobId}:error job:document-import:{importId}:status job:document-import:{importId}:progress job:document-import:{importId}:message job:document-import:{importId}:error 4. BullMQ 队列 请预留以下队列: - ai-analysis - document-import - notification 5. AI 分析任务 请实现基础队列结构: - 创建 AI 分析任务时写入 MySQL ai_analysis_jobs - 添加任务到 Redis BullMQ 队列 - Redis 记录任务 status/progress - Worker 处理完成后更新 MySQL - Redis 更新状态为 completed 6. 限流 请实现基础 AI 调用限流: rate:user:{userId}:ai:daily:{date} 用于限制用户每日 AI 分析调用次数。 7. 分布式锁 请实现 lock/unlock 工具,防止重复提交 AI 分析任务。 锁必须有 TTL。 解锁时要校验 token,不能误删其他请求的锁。 8. 注意事项 - 不要把用户、知识库、学习记录、AI 分析结果、待巩固项、复习计划只存 Redis - Redis 中所有临时状态必须设置 TTL - BullMQ 自动创建的 Redis key 不需要手动管理 - 代码要模块化,方便后续扩展 ``` --- 一句话总结: **Redis 在知习里不是“另一个 MySQL”,它是系统的加速器和调度器。MySQL 存结果,Redis 管过程。** [1]: file://my_files/file_00000000e760722fbb391fe031a23b24 "personal_developer_startup_plan.md" [2]: file://my_files/file_00000000cbe0722fb8f20caa41630738 "Pasted text.txt" [3]: file://my_files/file_0000000013c071fdbc2b510f32da8546 "Pasted text.txt" [4]: file://my_files/file_00000000ffd071fd9492b93fd9ebf5ba "Pasted text.txt" [5]: file://my_files/file_0000000061e471f590475885fd76860c "REAL_MIGRATION_STATUS.md"