# 内存优化:修复 K 线缓存仍占用进程内存的问题 ## 问题 即使配置了 Redis,K 线数据仍然在进程内存中累积,导致内存持续增长。 ## 根本原因 在 `kline_stream.py` 的 `_handle_message_async` 中,即使有 Redis,代码仍然**先更新进程内存 `_kline_cache`**,然后再批量写入 Redis。这导致: 1. **数据双重存储**:进程内存和 Redis 都有数据 2. **批量写入延迟**:在批量写入之前(最多 2 秒),数据一直留在进程内存 3. **写入失败时数据残留**:如果 Redis 写入失败,数据不会从进程内存删除 ## 修复方案 ### 1. 修改 K 线处理逻辑 **文件**: `trading_system/kline_stream.py` **修改前**: - 先更新 `_kline_cache`(进程内存) - 然后标记需要写入 Redis - 批量写入 Redis 后删除进程内存中的 key **修改后**: - **有 Redis 时**:直接从 Redis 读取当前数据,更新后写回 Redis,**完全不写进程内存** - **无 Redis 时**:才写进程内存(降级) ### 2. 限制 Redis 写入队列大小 `_redis_write_pending` 字典可能无限增长,添加了大小限制: - 最多保留 **100 个**待写入项 - 超出时删除最旧的项 ### 3. 删除重复定义 修复了代码中重复定义的变量(复制粘贴错误)。 ## 修改详情 ### `_handle_message_async` 方法 ```python # 修改前:总是先写进程内存 if key not in _kline_cache: _kline_cache[key] = [] cache_list = _kline_cache[key] # ... 更新 cache_list ... # 然后标记写入 Redis # 修改后:有 Redis 时只写 Redis if self._redis_cache: # 从 Redis 读取 existing = await self._redis_cache.get(rkey) cache_list = list(existing) if existing else [] # 更新 cache_list # 标记写入 Redis(不写进程内存) else: # 无 Redis 时才写进程内存 ... ``` ## 预期效果 - **进程内存占用大幅降低**:有 Redis 时,K 线数据不再存储在进程内存中 - **内存增长停止**:不再有数据在进程内存中累积 ## 需要重启服务 **重要**:修改后需要重启交易服务才能生效。 ```bash # 重启交易服务 pkill -f "python.*trading_system.main" # 然后重新启动 ``` ## 验证 重启后,检查内存使用: ```bash # 查看进程内存 ps aux | grep "trading_system.main" | awk '{print "MEM:", $4"%", "RSS:", $6/1024"MB"}' # 或使用诊断脚本 cd backend ./检查内存问题.sh ``` 正常情况下,有 Redis 时: - K 线缓存进程内存应该**接近 0**(只有降级时的少量数据) - 内存占用应该**稳定**,不再持续增长 ## 其他可能的内存增长源 如果重启后内存仍在增长,检查: 1. **WebSocket 消息队列**:检查是否有消息堆积 2. **日志**:检查日志文件大小 3. **数据库连接**:检查连接池是否正常释放 4. **其他缓存**:检查 `_price_cache`、`_symbol_info_cache` 等是否正常清理