208 lines
6.5 KiB
Markdown
208 lines
6.5 KiB
Markdown
# 扫描结果缓存分析
|
||
|
||
## 问题描述
|
||
|
||
用户担心:扫描结果缓存(8个交易对)在不同账户间共享,可能导致账户B使用了账户A的过期缓存。
|
||
|
||
## 缓存层次分析
|
||
|
||
### 1. 可以共用的缓存(中间数据)
|
||
|
||
这些是**市场数据**,不依赖于账户配置,可以安全共用:
|
||
|
||
- **24小时行情数据缓存**:`ticker_24h:all`
|
||
- TTL: 60秒
|
||
- 所有账户共用
|
||
- 这是市场原始数据,不依赖配置
|
||
|
||
- **K线数据缓存**:`klines:{symbol}:{interval}:{limit}`
|
||
- TTL: 根据interval动态设置(1h=60秒,4h=300秒)
|
||
- 所有账户共用
|
||
- 这是市场原始数据,不依赖配置
|
||
|
||
- **技术指标计算结果缓存**:`indicators:{symbol}:{primary_interval}:{confirm_interval}`
|
||
- TTL: 30秒
|
||
- 所有账户共用
|
||
- 这是基于K线计算的,不依赖配置
|
||
|
||
### 2. 扫描结果缓存(最终结果)
|
||
|
||
**缓存键**:`scan_result:top_symbols:{ns}`
|
||
**TTL**:30秒(当前)或15秒(修改后)
|
||
|
||
**问题分析**:
|
||
|
||
#### 场景1:同一账户自己再用(30秒内)
|
||
|
||
- **账户A在T0时刻扫描**,缓存了8个交易对
|
||
- **账户A在T0+20秒再次扫描**,直接使用缓存
|
||
- **问题**:
|
||
- 市场在变化,30秒内价格可能已经变化
|
||
- 这8个交易对可能已经不适合了(价格可能已经触发止损/止盈)
|
||
- 但是,如果配置相同,这8个交易对仍然是"当前市场最好的8个"
|
||
|
||
#### 场景2:不同账户共用缓存
|
||
|
||
- **账户A在T0时刻扫描**,缓存了8个交易对
|
||
- **账户B在T0+20秒扫描**,直接使用账户A的缓存
|
||
- **问题**:
|
||
- 如果账户A和账户B的配置不同,这8个交易对可能不适合账户B
|
||
- 即使配置相同,账户B也应该重新扫描,因为市场在变化
|
||
|
||
## 结论
|
||
|
||
### 扫描结果缓存不应该共用
|
||
|
||
**理由**:
|
||
|
||
1. **市场变化快**:30秒内价格可能已经变化,8个交易对可能已经不适合
|
||
2. **配置可能不同**:虽然现在使用全局配置,但未来可能不同账户有不同的配置
|
||
3. **扫描时间不同**:不同账户的扫描时间不同,不应该共用扫描结果
|
||
|
||
### 但是,中间数据可以共用
|
||
|
||
**理由**:
|
||
|
||
1. **市场数据不依赖配置**:24小时行情、K线数据、技术指标都是市场原始数据
|
||
2. **减少API请求**:多个账户共用这些缓存,可以显著减少API请求
|
||
3. **提升扫描效率**:扫描250个交易对时,如果每个账户都重新获取K线和计算技术指标,会很慢
|
||
|
||
## 解决方案
|
||
|
||
### 方案1:完全禁用扫描结果缓存(推荐)
|
||
|
||
**优点**:
|
||
- 每个账户都重新扫描,确保使用最新的市场数据
|
||
- 避免使用过期交易对的风险
|
||
|
||
**缺点**:
|
||
- 每个账户都需要重新扫描,耗时增加
|
||
- 但是,由于中间数据(K线、技术指标)已经缓存,重新扫描的耗时不会太长
|
||
|
||
### 方案2:缩短TTL并加入account_id区分(当前实现)
|
||
|
||
**优点**:
|
||
- 不同账户使用不同的缓存,避免配置不同的问题
|
||
- TTL缩短到15秒,减少使用过期数据的风险
|
||
|
||
**缺点**:
|
||
- 仍然存在使用过期数据的风险(15秒内市场可能已经变化)
|
||
- 增加了缓存键的复杂度
|
||
|
||
### 方案3:在缓存键中加入配置哈希值
|
||
|
||
**优点**:
|
||
- 如果配置不同,使用不同的缓存
|
||
- 如果配置相同,可以共用缓存
|
||
|
||
**缺点**:
|
||
- 实现复杂
|
||
- 仍然存在使用过期数据的风险
|
||
|
||
## 推荐方案
|
||
|
||
**推荐方案1:完全禁用扫描结果缓存** ✅ **已实施**
|
||
|
||
**理由**:
|
||
1. 扫描结果缓存的风险大于收益
|
||
2. 由于中间数据(K线、技术指标)已经缓存,重新扫描的耗时不会太长(约5-10秒)
|
||
3. 确保每个账户都使用最新的市场数据
|
||
|
||
**实现**:
|
||
- ✅ 移除扫描结果缓存逻辑
|
||
- ✅ 每个账户都重新扫描,但使用缓存的中间数据(K线、技术指标)
|
||
|
||
## 性能影响
|
||
|
||
### 禁用扫描结果缓存后的性能
|
||
|
||
**扫描250个交易对**:
|
||
- 获取24小时行情:1次API请求(缓存60秒,多个账户共用)✅
|
||
- 详细分析50-60个:50-60次K线API请求(有缓存,多个账户共用)✅
|
||
- 计算技术指标:50-60次计算(有缓存,多个账户共用)✅
|
||
- **总耗时**:约15-40秒(与之前相同,因为中间数据已经缓存)
|
||
|
||
**结论**:禁用扫描结果缓存后,性能影响很小,因为中间数据已经缓存。
|
||
|
||
---
|
||
|
||
## ✅ 已实施的优化(2026-01-25)
|
||
|
||
### 1. 禁用扫描结果缓存
|
||
|
||
**修改文件**:`trading_system/market_scanner.py`
|
||
|
||
**变更**:
|
||
- 移除了扫描结果缓存的读取逻辑
|
||
- 移除了扫描结果缓存的写入逻辑
|
||
- 每个账户都重新扫描,确保使用最新的市场数据
|
||
|
||
### 2. 优化多用户性能
|
||
|
||
**修改文件**:`trading_system/market_scanner.py`
|
||
|
||
**变更**:
|
||
- **降低并发数**:从5个并发降低到3个并发,确保多用户时系统稳定
|
||
- **添加超时控制**:单个交易对分析超时10秒,避免无限期阻塞
|
||
- **添加性能监控**:记录扫描耗时,如果超过60秒会发出警告
|
||
|
||
**效果**:
|
||
- 即使有多个账户同时扫描,也不会对系统造成过大压力
|
||
- 扫描过程不会错过或耽误处理
|
||
- 通过日志可以监控扫描性能
|
||
|
||
### 3. 性能监控
|
||
|
||
**新增功能**:
|
||
- 扫描完成后记录耗时
|
||
- 如果扫描耗时超过60秒,会发出警告
|
||
- 方便监控多用户时的系统压力
|
||
|
||
---
|
||
|
||
## 📊 多用户场景下的性能保证
|
||
|
||
### 优化前
|
||
- 并发数:5个
|
||
- 无超时控制
|
||
- 无性能监控
|
||
|
||
### 优化后
|
||
- 并发数:3个(降低系统压力)
|
||
- 超时控制:10秒(避免阻塞)
|
||
- 性能监控:记录耗时,超过60秒警告
|
||
|
||
### 预期效果
|
||
|
||
**单用户场景**:
|
||
- 扫描耗时:15-40秒
|
||
- 系统压力:低
|
||
|
||
**多用户场景(4个账户)**:
|
||
- 扫描耗时:15-40秒(每个账户)
|
||
- 系统压力:中等(由于中间数据缓存,实际API请求不会大幅增加)
|
||
- 不会错过或耽误处理:✅(超时控制确保不会无限期阻塞)
|
||
|
||
---
|
||
|
||
## 🚀 下一步操作
|
||
|
||
1. **重启交易进程**:
|
||
```bash
|
||
supervisorctl restart auto_sys_acc1 auto_sys_acc2 auto_sys_acc3 auto_sys_acc4
|
||
```
|
||
|
||
2. **验证优化**:
|
||
```bash
|
||
# 查看日志,确认扫描结果缓存已禁用
|
||
tail -f /www/wwwroot/autosys_new/logs/trading_*.log | grep -E "开始扫描市场|扫描完成|扫描耗时"
|
||
|
||
# 监控扫描性能
|
||
tail -f /www/wwwroot/autosys_new/logs/trading_*.log | grep -E "扫描耗时|⚠️ 扫描耗时较长"
|
||
```
|
||
|
||
3. **观察效果**:
|
||
- 观察扫描耗时是否在可接受范围内(15-40秒)
|
||
- 观察多用户时系统是否稳定
|
||
- 观察是否有超时警告
|