# 单账号交易服务内存评估与 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` 调用。
- **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 承担。
