auto_trade_sys/docs/REDIS_CACHE_ANALYSIS.md
薇薇安 86b85c2609 a
2026-01-25 11:19:39 +08:00

7.6 KiB
Raw Blame History

Redis 缓存优化分析

当前缓存情况

1. 内存缓存(进程内)

  • 交易对信息缓存 (_symbol_info_cache): 缓存交易对的精度、最小数量等信息
  • 价格缓存 (_price_cache): 缓存 WebSocket 价格数据TTL 60秒
  • 配置缓存: 数据库配置的内存缓存

2. 频繁的 API 调用

  • get_symbol_info(): 每次下单前调用,获取交易对精度信息
  • get_ticker_24h(): 频繁获取价格信息
  • get_klines(): 每次扫描时获取 K 线数据用于技术指标计算
  • futures_exchange_info(): 获取交易对信息

Redis 缓存优化方案

高优先级(显著提升性能)

1. 交易对信息缓存

当前问题:

  • 每次下单前都要调用 get_symbol_info() 获取精度信息
  • 交易对信息变化频率低,但每次都要 API 请求

Redis 缓存方案:

# 缓存键: symbol_info:{symbol}
# TTL: 1小时交易对信息很少变化
# 数据结构: Hash
{
    "quantityPrecision": 3,
    "pricePrecision": 2,
    "minQty": 0.001,
    "stepSize": 0.001,
    "minNotional": 5.0
}

性能提升:

  • 减少 API 调用:从每次下单 1 次 API 调用 → 0 次(缓存命中)
  • 降低延迟:从 ~100ms → ~1msRedis 本地访问)
  • 降低 API 频率限制风险

2. K 线数据缓存

当前问题:

  • 每次市场扫描都要获取 50 根 K 线数据
  • 相同时间周期的 K 线数据在短时间内不会变化
  • 扫描多个交易对时重复获取相同数据

Redis 缓存方案:

# 缓存键: klines:{symbol}:{interval}:{limit}
# TTL: 根据 interval 动态设置1m=10秒, 5m=30秒, 1h=5分钟
# 数据结构: List (JSON 序列化)

性能提升:

  • 减少 API 调用:扫描 10 个交易对,从 10 次 → 0-2 次(缓存命中)
  • 加速市场扫描:从 ~5-10 秒 → ~1-2 秒
  • 降低 API 频率限制风险

3. 24小时行情数据缓存

当前问题:

  • get_all_tickers_24h() 每次扫描都调用
  • 数据更新频率相对较低24小时统计

Redis 缓存方案:

# 缓存键: ticker_24h:{symbol} 或 ticker_24h:all
# TTL: 30秒24小时统计数据更新不频繁
# 数据结构: Hash 或 String (JSON)

性能提升:

  • 减少 API 调用:从每次扫描 1 次批量请求 → 0 次(缓存命中)
  • 加速市场扫描:从 ~2-3 秒 → ~0.1 秒
  • 降低 API 频率限制风险

中优先级(适度提升性能)

4. 配置信息缓存

当前问题:

  • 每次获取配置都要查询数据库
  • 配置变化频率低

Redis 缓存方案:

# 缓存键: config:{key}
# TTL: 5分钟配置可能通过前端修改
# 数据结构: String

性能提升:

  • 减少数据库查询:从每次获取配置 1 次查询 → 0 次(缓存命中)
  • 降低数据库负载

5. 市场扫描结果缓存

当前问题:

  • 扫描结果可以短期缓存,避免重复扫描

Redis 缓存方案:

# 缓存键: scan_result:top_symbols
# TTL: 30秒扫描间隔内可以复用
# 数据结构: List (JSON)

性能提升:

  • 减少重复计算:在扫描间隔内可以复用结果

低优先级(提升有限)

6. 价格缓存(已有 WebSocket

当前情况:

  • 已有 WebSocket 实时价格推送
  • 内存缓存已足够

建议:

  • 保持现有内存缓存
  • Redis 可以作为 WebSocket 的备份(如果 WebSocket 断开)

性能提升评估

预期提升

场景 当前延迟 Redis 缓存后 提升
下单前获取交易对信息 ~100ms ~1ms 99%
市场扫描10个交易对 ~5-10秒 ~1-2秒 70-80%
获取 K 线数据 ~200ms/次 ~1ms/次 99.5%
获取 24h 行情 ~2-3秒 ~0.1秒 95%

API 调用减少

API 端点 当前频率 Redis 缓存后 减少
futures_exchange_info 每次下单 每小时 1 次 99%+
futures_klines 每次扫描 每 5 分钟 1 次 90%+
futures_ticker 每次扫描 每 30 秒 1 次 95%+

风险降低

  1. API 频率限制风险:显著降低
  2. 网络延迟影响:大幅减少
  3. 系统响应速度:明显提升

实现建议

1. 使用 aioredis 库(异步 Redis 客户端)

pip install aioredis

2. 创建 Redis 缓存管理器

# trading_system/redis_cache.py
import aioredis
import json
from typing import Optional, Dict, Any
import logging

logger = logging.getLogger(__name__)

class RedisCache:
    def __init__(self, redis_url: str = "redis://localhost:6379"):
        self.redis_url = redis_url
        self.redis: Optional[aioredis.Redis] = None
    
    async def connect(self):
        """连接 Redis"""
        try:
            self.redis = await aioredis.from_url(self.redis_url)
            await self.redis.ping()
            logger.info("✓ Redis 连接成功")
        except Exception as e:
            logger.warning(f"Redis 连接失败: {e},将使用内存缓存")
            self.redis = None
    
    async def get(self, key: str) -> Optional[Any]:
        """获取缓存"""
        if not self.redis:
            return None
        try:
            data = await self.redis.get(key)
            if data:
                return json.loads(data)
        except Exception as e:
            logger.debug(f"Redis 获取失败 {key}: {e}")
        return None
    
    async def set(self, key: str, value: Any, ttl: int = 3600):
        """设置缓存"""
        if not self.redis:
            return False
        try:
            await self.redis.setex(key, ttl, json.dumps(value))
            return True
        except Exception as e:
            logger.debug(f"Redis 设置失败 {key}: {e}")
        return False
    
    async def close(self):
        """关闭连接"""
        if self.redis:
            await self.redis.close()

3. 集成到现有代码

修改 binance_client.py:

from .redis_cache import RedisCache

class BinanceClient:
    def __init__(self, ...):
        # ... 现有代码 ...
        self.redis_cache = RedisCache()
    
    async def connect(self, ...):
        # ... 现有代码 ...
        await self.redis_cache.connect()
    
    async def get_symbol_info(self, symbol: str):
        # 先查 Redis 缓存
        cache_key = f"symbol_info:{symbol}"
        cached = await self.redis_cache.get(cache_key)
        if cached:
            return cached
        
        # 缓存未命中,调用 API
        info = await self._fetch_symbol_info(symbol)
        
        # 写入 Redis 缓存TTL: 1小时
        if info:
            await self.redis_cache.set(cache_key, info, ttl=3600)
        
        return info

总结

推荐实施优先级

  1. 交易对信息缓存 - 立即实施,效果最明显
  2. K 线数据缓存 - 高优先级,显著提升扫描速度
  3. 24小时行情缓存 - 高优先级,减少批量请求
  4. 配置信息缓存 - 中优先级,适度提升
  5. 市场扫描结果缓存 - 低优先级,提升有限

预期效果

  • API 调用减少: 70-90%
  • 系统响应速度: 提升 70-80%
  • API 频率限制风险: 显著降低
  • 系统稳定性: 提升(减少网络依赖)

注意事项

  1. 缓存一致性: 需要合理设置 TTL确保数据及时更新
  2. Redis 可用性: 需要处理 Redis 不可用的情况(降级到内存缓存)
  3. 内存使用: Redis 内存使用需要监控
  4. 部署复杂度: 需要部署和维护 Redis 服务