Files
Chan/research/live/deploy/README.md
T
jackandCursor 54792fe015 把 compute_ms 拆成排队与纯计算,据此否掉换机器这个方向
compute_ms 一直是「提交进程池到拿到结果」的墙钟时间,排队和纯计算混在一个
数里,所以「加核有没有用」只能靠猜——这也是原先打算在 AWS 开第二台比 CPU
的依据。

worker 内部自己计时,连同父进程传入的提交时刻一起回传,拆出 queue_ms 与
inner_ms。实测中位 3ms / 695ms:2 个 worker 跑 3 个币并不排队,因为三个币的
收盘消息错峰到达。瓶颈全在单线程,加核压不到。

顺带把 README 里的内存数据从臆测的 1.5GB 改成实测 410MiB,并注明跨站点比
CPU 收益有限。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 03:02:06 +08:00

150 lines
6.4 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.
# 影子采集器部署
在第二台机器上跑一套完全相同的采集,用来看不同地理位置的数据差异。
## 先看这一节:延迟的瓶颈不在机房
滑点里最大的一项是**延迟漂移**,所以延迟越低越好。但延迟拆开之后,可优化的
地方和直觉不一样。腾讯云新加坡实测(2026-08-28):
| 构成 | 中位 | 随机房位置变化吗 |
| --- | --- | --- |
| 数据到达(交易所推送 + 回源 + 网络) | 506ms | 只有网络那段,**2ms** |
| 信号计算(本机 CPU | **646ms** | 不变,取决于 CPU |
| 合计到可下单 | 1315ms | |
`ws.bitget.com` 解析出来是 **CloudFront**`dxotqhr62n6z4.cloudfront.net`),
落在新加坡的 AS16509(Amazon)。所以我们连的是 AWS 的 CDN 边缘,不是 Bitget
自己的机房。从腾讯云新加坡到这个边缘:
ICMP 往返 2.1ms
TCP 握手 3.3ms
TLS 完成 9.0ms
首字节 87.8ms ← 减去 TLS 的 9ms,约 79ms 是 CloudFront 回源开销
回源那 79ms 和交易所自己的推送节奏,不管我们坐在哪都一样。而随位置变化的
只有那 2ms 往返。**换机房的全部空间是 1~2ms,占总延迟 1315ms 的 0.1%。**
真正的大头是本机 646ms 的信号计算:每根 K 线要在 2000 根 1m 加 800 根 5m 上
重建缠论结构,三个币同时收盘而本机只有 2 核、2 个计算进程,第三个币还要排队。
**所以第二台机器该测的是 CPU 规格,不是地理位置。**`compute_ms`,不是
`lag_data_ms`。3 个币至少要 3 个 worker,`--workers` 给到核数减一。
## 三个必须一致,一个必须不同
必须一致,否则差异分不清是地理位置还是环境造成的:
- **代码版本**`git_commit`)——同一个 commit
- **镜像摘要**`image_digest`)——同一个 hummingbot 镜像
- **时钟**——两台都同步到 NTP,偏移都在 10ms 内
必须不同:
- **`SHADOW_SITE`**——写进每一行数据,是合并后区分来源的唯一依据
`start.sh` 会把这四项连同内核、核数、内存一起写进
`research/out/run_meta_<site>.json`。两地数据对不上时先看这个文件。
## 时钟为什么是硬门槛
所有延迟数字都是「本地时钟 − 交易所 K 线收盘时间戳」。时钟偏 50ms,全部
延迟就同向偏 50ms,而且**不会有任何报错**——只会让跨地对比得出一个干净、
自信、且完全错误的结论。所以 `start.sh` 在时钟未同步或偏移超阈值时直接
拒绝启动,而不是打个警告了事。
## 步骤
在新机器上:
```bash
git clone ssh://jack@git.jackyu66.com:2222/jack/chan.git
cd chan && git checkout chan
bash research/live/deploy/setup.sh # 装 docker + chrony,拉镜像
# 站点名带上机型,因为要比的是 CPU 而不是位置
SHADOW_SITE=aws-sg-c7a4x WORKERS=3 bash research/live/deploy/start.sh
```
`WORKERS` 按核数减一给。3 个币同时收盘,worker 少于 3 就会排队,而排队时间
直接计入 `compute_ms`。本机 2 核只能给 2,这本身就是 646ms 里的一部分。
确认健康:
```bash
bash research/live/deploy/status.sh
```
启动日志里应当看到:
```
[补丁] 覆盖生效:基类取首元素 … 本地取末元素 …
成交流已挂 ['BTC', 'ETH', 'SOL']
就绪 3.0s · 1m [2001, 2001, 2001] 根 · 5m [801, 801, 801] 根
```
第一行尤其重要。上游 Bitget 连接器的换根解析有 bug(只取多根消息的首元素),
补丁把它修掉拿回约 1.06 秒。补丁若失效是静默的——不崩不报错,只是延迟悄悄
退回 1.4 秒,所以启动时做了断言。
## 对比
把两站的 `research/out/` 收到一处(同名文件会覆盖,所以分目录放):
```bash
mkdir -p collected/sg collected/aws
rsync -av sg-box:chan/research/out/ collected/sg/
rsync -av aws-box:chan/research/out/ collected/aws/
python research/live/compare_sites.py \
--glob 'collected/*/shadow_latency.csv' \
--drift-glob 'collected/*/shadow_drift.csv' \
--meta-dir collected/sg --meta-dir collected/aws
```
对比脚本做两件事值得说明:
- **只取各站都有的 K 线**做配对比较。不取交集就可能在比不同时段,而延迟对
市场活跃度敏感。
- 报**配对差的符号占比**而不只是两个中位数相减。同根配对消掉了市场状态,
「A 比 B 慢的根占多少」比「两个中位数差多少」更能说明有无系统性差异。
判读上有一条自检:**同一个固定延迟点上,两站的漂移应当几乎相同**——漂移是
市场性质,与机器位置无关。若漂移也差很多,先怀疑时钟或时段没对齐,而不是
急着下结论。
同理,`lag_data_ms` 两站也应当几乎相同(网络那段只有 2ms 空间)。真正该出现
差异的是 `compute_ms`。如果 `lag_data_ms` 差很多,先查时钟——比查网络更可能。
⚠ 但先读下面「资源占用」一节:`compute_ms` 的差异几乎全部来自单核性能,而
现役机型之间单核差距很小。**跨站点比 CPU 这件事本身收益有限**,本节流程保留
是为了比网络与时钟,不建议为了比 CPU 单独开机器。
## 资源占用
本机实测(2 vCPU EPYC 9K65 / 3 个币 / 2 worker):内存 **410MiB**CPU 均值
1~3%。盘口与成交流落盘约 15MB/天(gzip),一周在百 MB 内。
内存和平均 CPU 都不是约束。约束是**单根 K 线的计算延迟**,而它是纯单线程的:
```
compute_ms 中位 764ms 父进程测的墙钟,含排队
queue_ms 中位 3ms 等空闲 worker
inner_ms 中位 695ms 进程内真正在算
```
`queue_ms` 只有 3ms,说明 **2 个 worker 跑 3 个币并不排队**——三个币的收盘消息
错峰到达(SOL 最晚,排 66ms),没有真正的并发争抢。
**这条结论直接否掉了「换更强机器」这个方向。** 加核只能压 queue_ms,而它已经
是 3ms;695ms 全在单线程里,取决于单核性能。t3a.mediumZen 12017)单核比
本机 Zen 5 慢 1.8~2 倍,换过去 compute_ms 会涨到 1200ms 以上。c7a / c6a 这类
现代机型单核与本机相当,也换不到东西。
要压这 695ms 只有算法一条路:现在每分钟把 2001 根从头算一遍,其中 2000 根的
结构与上一分钟完全相同。
`--workers 2` 是因为信号计算走独立进程池、不能阻塞事件循环。币数超过 worker
数才会看到 queue_ms 上来;届时加 worker 有效,加到与币数相等即可。