在多个模块中实现 Redis 缓存机制,优先从 Redis 读取数据,减少进程内存占用。更新 `binance_client.py`、`market_scanner.py`、`position_manager.py`、`ticker_24h_stream.py` 和 `book_ticker_stream.py`,确保在有 Redis 时优先使用其进行数据存储,降级到内存缓存。调整缓存管理逻辑,限制进程内缓存的最大条数为 500,避免内存无限增长。此改动提升了数据访问效率,优化了内存使用,增强了系统的整体性能与稳定性。
2.7 KiB
2.7 KiB
单账号交易服务内存评估与 Redis 减压
1. 单账号合理内存区间
| 组成部分 | 预估范围 | 说明 |
|---|---|---|
| Python 解释器 + asyncio | 50–80 MB | 进程基础 |
| aiohttp + WebSocket 连接 x4 | 20–50 MB | UserData / K线 / Ticker24h / BookTicker |
| Redis 客户端连接与缓冲 | 5–15 MB | 远端 Valkey |
| 各模块小缓存(有上限) | 5–20 MB | 价格、symbol_info、持仓等,已限制条数 |
| 策略/扫描/持仓状态 | 10–30 MB | active_positions、top_symbols 等 |
| 分配器碎片、未归还 OS | 50–150 MB | Python 常见 |
| 合计(合理区间) | 250–400 MB | 单账号、设计正常时 |
结论:单账号约 250–400 MB 属正常;500 MB 偏上但尚可接受;若持续升到 700 MB+ 则偏异常。
你当前「多了约 500 MB」:无服务约 720 MB,开服务约 1223 MB → 交易进程约 500 MB,处于偏上、可接受范围。目标是通过 Redis 把压力放到远端,把进程压到 300 MB 左右 并稳定。
2. 当前仍占进程内存的来源
- Ticker24h / BookTicker:refresh 循环每 2 秒从 Redis 拉全量(最多 500 条)回进程,进程内常驻一份完整拷贝(约 200+ 条 × 若干 KB),是主要可优化点。
- K 线:Leader 已只写 Redis,进程内仅少量元数据和待写队列,占比已较小。
- 持仓/余额:有 Redis 时只写 Redis,进程内几乎不保留。
- 价格 / symbol_info:有 Redis 时仅降级写,条数有上限,占比小。
因此,把 Ticker24h/BookTicker 改为“只从 Redis 按需读、进程内不再保留全量回填”,是当前最有效的 Redis 减压手段。
3. 已实现:Ticker24h/BookTicker 完全用 Redis,进程内不保留全量
- 写:Leader 不变,WS 收到后只写 Redis,并写入
market:ticker_24h:updated_at/market:book_ticker:updated_at(时间戳,供 refresh 判断是否新鲜)。 - 读:
- Ticker24h:
get_tickers_24h_from_redis(redis_cache),由 market_scanner 在is_ticker_24h_cache_fresh()为 True 时await调用,数据全部来自 Redis。 - BookTicker:
get_book_ticker_from_redis(redis_cache, symbol),由 position_manager、binance_client 在有 redis_cache 时await调用。
- Ticker24h:
- refresh 循环:只从 Redis 读取
updated_at并写回_ticker_24h_updated_at/_book_ticker_updated_at,不再拉全量数据,进程内_ticker_24h_cache/_book_ticker_cache在有 Redis 时保持为空。 - 进程内:不再保留 200~500 条 ticker/book_ticker,单账号进程内存预计可再降约 50~150MB,稳定在约 300~400MB,压力由远端 Redis 承担。