mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
96b1f5c373
* feat(storage): tune gt1g get read path * docs(ops): add gt1g get benchmark guide * feat(scripts): add gt1g get fallback runner * test(storage): trim gt1g get helper warnings * test(storage): reduce gt1g get helper type complexity
5.9 KiB
5.9 KiB
Issue #713 >1GiB GET 优化与验证手册
1. 目标
本文用于收口 backlog#713 当前这一轮 >1GiB GET 优化的实现点与验证方式。
当前这轮改动先解决三件事:
sequential hint真正参与 GET I/O 策略计算- storage media buffer cap 不再被统一的
1MiBhard clamp 二次截断 >1GiB、非 range、允许 readahead 的 streaming GET,会走更大的 stream buffer 策略
2. 当前代码行为变化
2.1 多因素调度
涉及:
rustfs/src/storage/concurrency/io_schedule.rs
当前行为:
IoSchedulingContext.is_sequential_hint=true时,会优先按Sequential模式参与 buffer / readahead 决策- storage profile 提供的 media cap 现在可以真实生效
- 例如默认常量下:
NVMe:2MiBSSD:1MiBHDD:512KiB
2.2 GET body stream 策略
涉及:
rustfs/src/app/object_usecase.rs
当前行为:
optimal_buffer_size不再被额外min(base_buffer_size)压回去>1GiB、非 range、enable_readahead=true的 streaming GET,会命中:large_sequential_readahead
- 该路径当前把
ReaderStreambuffer 扩到:min(optimal_buffer_size * 2, 4MiB)
2.3 GET observability
涉及:
crates/io-metrics/src/lib.rs
新增:
rustfs_io_get_object_stream_strategy_total{strategy=...}rustfs_io_get_object_stream_buffer_size_bytes{strategy=...}rustfs_io_get_object_stream_response_size_bytes{strategy=...}
当前策略标签:
standardlarge_sequential_readahead
3. 推荐验证顺序
按下面顺序做最稳妥:
- 先准备 plain
1GiB/2GiB对象 - 先跑
sequentialbaseline - 再跑
ranged_parallel - 最后再决定是否继续补 encrypted / compressed
4. 准备测试对象
直接使用:
scripts/prepare_gt1g_get_test_objects.sh
示例:
bash scripts/prepare_gt1g_get_test_objects.sh \
--endpoint http://127.0.0.1:9000 \
--access-key rustfsadmin \
--secret-key rustfsadmin \
--bucket rustfs-bench \
--prefix bench/issue713/plain
默认会准备:
1GiB=plain-1g.bin2GiB=plain-2g.bin
默认最终对象路径:
s3://rustfs-bench/bench/issue713/plain/plain-1g.bins3://rustfs-bench/bench/issue713/plain/plain-2g.bin
5. 执行 GET 矩阵
直接使用:
scripts/run_gt1g_get_http_matrix.sh
这个脚本特点:
- 不把响应体落到本地磁盘
- 直接把 body 丢到
/dev/null - 用
curl的size_download做字节校验和吞吐计算 - 同时支持:
sequentialranged_parallel
补充说明:
- 如果本机没有
mc,脚本会自动 fallback 到仓库内置的rustfs/tests/gt1g_get_benchmark_tool.rs - fallback 模式下,结果目录会落在:
rustfs/target/bench/...
- 非 fallback 模式下,结果目录仍按脚本参数落在:
target/bench/...
5.1 baseline:sequential + ranged_parallel
bash scripts/run_gt1g_get_http_matrix.sh \
--endpoint http://127.0.0.1:9000 \
--access-key rustfsadmin \
--secret-key rustfsadmin \
--bucket rustfs-bench \
--objects '1GiB=bench/issue713/plain/plain-1g.bin,2GiB=bench/issue713/plain/plain-2g.bin' \
--modes sequential,ranged_parallel \
--concurrencies 1,4,8 \
--range-workers 4 \
--rounds 3 \
--cooldown-secs 20
5.2 只跑 sequential
bash scripts/run_gt1g_get_http_matrix.sh \
--endpoint http://127.0.0.1:9000 \
--access-key rustfsadmin \
--secret-key rustfsadmin \
--bucket rustfs-bench \
--objects '1GiB=bench/issue713/plain/plain-1g.bin,2GiB=bench/issue713/plain/plain-2g.bin' \
--modes sequential \
--concurrencies 1,4,8 \
--rounds 3 \
--cooldown-secs 20
5.3 只跑 ranged_parallel
bash scripts/run_gt1g_get_http_matrix.sh \
--endpoint http://127.0.0.1:9000 \
--access-key rustfsadmin \
--secret-key rustfsadmin \
--bucket rustfs-bench \
--objects '1GiB=bench/issue713/plain/plain-1g.bin,2GiB=bench/issue713/plain/plain-2g.bin' \
--modes ranged_parallel \
--concurrencies 1,4,8 \
--range-workers 4,8 \
--rounds 3 \
--cooldown-secs 20
6. 输出目录
默认输出:
target/bench/gt1g-get-http-<timestamp>/
重点看:
round_results.csvmedian_summary.csvlogs/
round_results.csv 字段:
object_labelobject_keymoderange_workersconcurrencyroundstatustotal_byteselapsed_msthroughput_bpsavg_client_latency_ms
7. 当前推荐观察点
7.1 sequential 是否命中大对象策略
查询:
sum by (strategy) (
increase(rustfs_io_get_object_stream_strategy_total[5m])
)
预期:
>1GiB顺序 GET 应出现large_sequential_readahead
7.2 GET stream buffer 分布
histogram_quantile(
0.95,
sum by (strategy, le) (
rate(rustfs_io_get_object_stream_buffer_size_bytes_bucket[5m])
)
)
7.3 GET 端到端完成时长
histogram_quantile(
0.95,
sum by (le) (
rate(rustfs_io_get_object_total_duration_seconds_bucket[5m])
)
)
8. 当前判断建议
如果 sequential 在 1GiB/2GiB、c1 下仍然没有明显优于旧结果,优先检查:
large_sequential_readahead是否真的命中- buffer size 是否仍停在
1MiB - 请求是否实际是 range / encrypted / compressed,从而没走当前优化路径
如果 ranged_parallel 明显优于 sequential,再继续补:
- 客户端并行分片数建议
- plain 与 encrypted/compressed 的拆分对比
9. 当前边界
这轮实现还没有直接覆盖:
- encrypted
>1GiB GET的单独 read-ahead 策略 - compressed
>1GiB GET的专门 index / range 成本优化 - server-side 主动预取缓存
因此当前更适合先做:
- plain sequential vs ranged_parallel 基线
- 命中策略与吞吐结果收敛
- 再决定下一刀是否继续进 encrypted / compressed