auto_trade_sys/docs/内存优化_修复K线缓存.md
薇薇安 a498520c51 feat(kline_stream): 优化 Redis 写入逻辑与内存管理
在 `kline_stream.py` 中增强了 Redis 写入机制,限制待处理队列大小以防止无限增长,并在 Redis 处理失败时降级到进程内存。更新了缓存管理逻辑,确保在有 Redis 时优先使用 Redis 进行数据存储,提升了系统的内存使用效率与稳定性。同时,调整了日志记录以减少高负载时的输出频率。此改动进一步优化了消息处理与系统性能。
2026-02-19 00:26:34 +08:00

104 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 内存优化:修复 K 线缓存仍占用进程内存的问题
## 问题
即使配置了 RedisK 线数据仍然在进程内存中累积,导致内存持续增长。
## 根本原因
`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` 等是否正常清理