# bytehaul 性能调优指南

本文介绍影响 bytehaul 下载性能和资源占用的关键参数。

[English Version](tuning.md)

## `piece_size`

**默认值：** 1 MiB  
**取值范围：** 必须大于 0

分片大小决定了多连接下载和断点续传的粒度。每个分片都会独立分配给某个 Worker 下载，并在控制文件中单独记录完成状态。

| 场景 | 建议值 |
|------|--------|
| 小文件（< 10 MB） | 256 KiB - 512 KiB |
| 中等文件（10 MB - 1 GB） | 1 MiB（默认） |
| 大文件（> 1 GB） | 4 MiB - 16 MiB |

**权衡点：**

- 分片更小：续传粒度更细，但调度开销更大，控制文件也会更大
- 分片更大：管理开销更低，但如果某个分片中途失败，恢复时可能需要重下更多数据

## `memory_budget`

**默认值：** 64 MiB  
**取值范围：** 必须大于 0

控制回写缓存中最多允许缓冲多少数据，超过后会对 Worker 施加背压。也就是说，当缓存达到阈值时，Worker 会暂停继续读取网络数据，直到 Writer 把缓存刷到磁盘。

| 系统内存 | 建议预算 |
|----------|----------|
| ≤ 2 GB | 16 - 32 MiB |
| 4 - 8 GB | 64 MiB（默认） |
| ≥ 16 GB | 128 - 256 MiB |

**权衡点：**

- 预算更低：内存占用更少，但在慢盘上更容易因为等待 flush 导致 Worker 停顿
- 预算更高：快网络 + 慢磁盘场景下吞吐更平滑，但会占用更多内存

## `max_connections`

**默认值：** 4  
**取值范围：** 必须大于等于 1

单个下载任务可使用的并行 HTTP 连接数。每个 Worker 会并发抓取不同的分片。

| 网络 / 服务端类型 | 建议值 |
|--------------------|--------|
| 单台源站，家庭网络 | 2 - 4 |
| CDN 后端，高带宽链路 | 8 - 16 |
| 易限速或较脆弱的服务端 | 1 - 2 |

**权衡点：**

- 更多连接：总吞吐通常更高（直到触及网络或服务端极限），但会增加服务端压力
- 更少连接：对服务端更友好，失败时也更容易定位问题
- 许多服务端会按 IP 限制连接数；超过限制后可能出现 429 或连接重置

## `channel_buffer`

**默认值：** 64  
**取值范围：** 必须大于 0

HTTP 流读取层和回写缓存之间内部 Tokio channel 的缓冲区大小。它决定了网络层和缓存层之间最多允许多少个数据块处于 in-flight 状态。

大多数场景下默认值已经足够。只有在你确认 Worker 经常阻塞在 channel send 上时，才值得上调；这类情况通常能在 `trace` 级别日志中观察到。

## `min_split_size`

**默认值：** 10 MiB

小于这个阈值的文件会始终使用单连接下载，不受 `max_connections` 影响。这样可以避免小文件为了多连接协调而付出额外开销。

## `control_save_interval`

**默认值：** 5 秒

控制下载过程中 `.bytehaul` 控制文件落盘的频率。值越小，崩溃后可恢复的精度越高，但磁盘写入次数也越多；值越大，I/O 开销更低，但进程异常退出时会损失更多尚未保存的进度。

| 场景 | 建议值 |
|------|--------|
| 高速网络，大文件 | 2 - 3 秒 |
| 慢速或按量计费网络 | 10 - 30 秒 |
| SSD 存储 | 3 - 5 秒（默认） |
| HDD 或网络存储 | 10 - 15 秒 |

## `max_download_speed`

**默认值：** 0（不限速）  
**单位：** 字节/秒

下载速率限制器。设置为非零值后，可以限制 bytehaul 占用的带宽，适合与其他应用共享链路时使用。

## 重试参数

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `max_retries` | 5 | 单次请求失败后最多重试多少次 |
| `retry_base_delay` | 1 秒 | 初始退避延迟 |
| `retry_max_delay` | 30 秒 | 退避最大上限 |
| `max_retry_elapsed` | None | 总重试时间预算（`None` 表示不限时） |

重试采用指数退避，并叠加完整抖动，以降低多个客户端下载同一服务端时同时重试造成的冲击。