You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buffer_platform/docs/superpowers/specs/2026-07-04-analysis-storage...

5.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

comet_change role canonical_spec
analysis-storage-refactor technical-design openspec

Analysis Storage Refactor - Technical Design

1. 架构概览

1.1 目标架构

┌─────────────────────────────────────────────────────────────┐
│                     应用层                                   │
│  app/api/futures_analysis.py  ←→  app/services/cache.py     │
│                                         ↓                   │
│                                   StorageManager            │
│                                   (storage_manager.py)      │
└─────────────────────────────────────────────────────────────┘
                              ↓
        ┌─────────────────────┼─────────────────────┐
        ↓                     ↓                     ↓
   ┌─────────┐          ┌─────────┐          ┌─────────┐
   │  Redis  │          │  MySQL  │          │ SQLite  │
   │ (缓存)  │          │(持久化) │          │ (兜底)  │
   └─────────┘          └─────────┘          └─────────┘

1.2 核心组件

组件 职责
StorageManager 封装三级存储逻辑,提供统一读写接口
analysis_db.py Analysis 数据库连接管理,降级逻辑
analysis_models.py ORM 模型定义(不变)
analysis_migration.py SQLite → MySQL 数据迁移

1.3 表清单

表名 用途 缓存 TTL
futures_analysis 期货分析报告 5 分钟
watched_symbols 用户关注品种 10 分钟
ai_model_configs AI 模型配置 10 分钟
analysis_settings 分析设置 10 分钟
ai_analysis_cache AI 分析缓存 5 分钟
review_dates 复盘日期 1 小时
symbol_rankings 品种排名 1 小时
trading_plans 交易计划 1 小时
symbol_scores_v2 V2 品种评分 1 小时
trading_plans_v2 V2 交易计划 1 小时
sector_heat 板块热度 1 小时
review_plans_v2 V2 复盘计划 1 小时
trade_records 交易记录 不缓存
trade_import_batches 交易导入批次 不缓存

2. 降级策略

2.1 读取流程

读取请求
    ↓
检查 Redis 缓存
    ↓ 命中
返回数据
    ↓ 未命中
检查 MySQL 可用性
    ↓ 可用
查询 MySQL → 回填 Redis → 返回
    ↓ 不可用
降级到 SQLite → 返回

2.2 写入流程

写入请求
    ↓
删除 Redis 缓存
    ↓
写入 MySQL事务
    ↓ 成功
回填 Redis → 返回
    ↓ 失败
写入 SQLite → 返回

2.3 降级状态检测

  • 惰性检测30 秒间隔
  • Redis 不可用时跳过缓存层
  • MySQL 不可用时降级到 SQLite

3. 数据迁移

3.1 迁移时机

应用启动时(lifespan),在 MySQL 表结构初始化后执行。

3.2 迁移逻辑

def migrate_analysis_sqlite_to_mysql():
    """将 SQLite analysis 数据迁移到 MySQL"""
    # 1. 检测 MySQL 表是否已有数据
    mysql_count = count_mysql_analysis_tables()
    if mysql_count > 0:
        logger.info("MySQL analysis 表已有数据,跳过迁移")
        return
    
    # 2. 从 SQLite 读取数据
    sqlite_data = read_sqlite_analysis_data()
    
    # 3. 批量写入 MySQL
    write_mysql_analysis_data(sqlite_data)
    
    logger.info("Analysis 数据迁移完成")

3.3 幂等性

  • 检测 MySQL 表是否已有数据
  • 有数据则跳过迁移
  • 迁移失败不影响应用启动

4. 缓存策略

4.1 缓存键设计

analysis:{table_name}:{id}
analysis:{table_name}:list:{query_hash}

4.2 缓存失效

  • 写入时删除相关缓存
  • TTL 过期自动失效

4.3 缓存回填

  • 读取时未命中,查询 MySQL 后回填
  • TTL 与表类型对应

5. 兼容性

5.1 ORM 模型

  • 保持不变
  • 使用 AnalysisBase 作为基类

5.2 API 接口

  • 保持不变
  • 通过 get_analysis_db() 依赖注入

5.3 SQLite 文件

  • 保留 data/futures_analysis.db
  • 降级时使用

6. 测试策略

6.1 单元测试

场景 测试方法
Redis 缓存命中 Mock Redis验证不查询 MySQL
Redis 缓存未命中 Mock Redis 返回 None验证查询 MySQL
MySQL 降级到 SQLite Mock MySQL 不可用,验证查询 SQLite
数据迁移 验证 SQLite 数据完整迁移到 MySQL

6.2 集成测试

  • 启动应用,验证 MySQL 表创建
  • 执行迁移,验证数据完整性
  • 调用 API验证功能正常

7. 风险与缓解

风险 缓解措施
数据迁移失败 保留 SQLite 作为降级方案,迁移失败时自动降级
Redis 缓存不一致 写入时先删缓存,再写 MySQL最后回填缓存
表结构不兼容 复用现有 ORM 模型MySQL 自动创建表结构
性能下降 Redis 缓存减少 MySQL 查询压力