开始
性能
用起来的实际感受,实测数字,也包括做得不好的地方:每个数字是怎么测的、在什么机器上测的。
这里是人能感觉到的数字:没下载过的文件多久开始播放,存一个大文件有多快,列一个文件夹要多久。做得不好的地方我们也一起公开,那正是接下来要改的。
结果
| 做什么 | 结果 | 说明 |
|---|---|---|
| 保存一个 1 GiB 新文件 | 168 MiB/s | CLI put,按内容切块,块都是新的 |
| 改了中间 1 MiB 后再存一次 | 1.6 秒 | 只传改动的块;时间主要花在本机重新算哈希 |
| 没下载过的文件,读前 64 KiB | 37 ms | Linux 挂载(FUSE),打开加读取 |
| 再读它末尾附近的 64 KiB | 20 ms | 只取这一处所在的块 |
| 从头读完(没缓存) | 240 MiB/s | 顺序读,来自块网关 |
| 再读一遍(已缓存) | 536 MiB/s | 本机缓存 |
| 列出 5,000 个文件的文件夹 | 132 ms | 挂载里 ls |
| 往挂载里写 500 个小文件 | 每秒 133 个 | 写完即返回,后台上传 |
| ……直到 500 个都成为服务器上的版本 | 4.0 秒 | 从第一次写开始算 |
| SDK 保存 1 KiB 文件 | p50 22 ms,p95 27 ms | Python SDK |
| 读回来 | p50 7 ms,p95 8 ms | |
| 按路径查 | p50 3 ms,p95 4 ms | |
| 末尾追加一行 | p50 67 ms,p95 72 ms | append_text |
做得不好的地方
- 末尾追加一行比重新保存整个小文件还慢 3 倍(67 ms 对 22 ms)。追加要先查一次文件,再让服务器读出原内容、拼上新的一行、整个重新切块。现在小文件直接整存更快;追加应该只重写最后一块。
- 第二次列同一个文件夹没有变快(第二次 141 ms)。挂载的目录缓存只有 1 秒,每次
ls都去问服务器。客户端本机已经有整棵树的副本,可以直接用它回答,再靠推送保持更新。 - 改了 1 MiB 后再存 1 GiB 的文件要 1.6 秒,几乎都花在把整个文件重新读一遍算哈希。挂载里写入时已经知道改了哪些字节,可以只重算受影响的块。
自己跑一遍
在仓库的检出目录里,用装了 Docker 的 Linux:
scripts/dev-up.sh --native && tests/e2e/bench.sh # BENCH_MB=2048 BENCH_FILES=10000 可以调大它会打印同样的表格,并把原始结果写成 JSON。很多人同时使用时服务器能撑多少(负载测试),见仓库里的 docs/performance.md。