TL;DR 版本
观看此 ASCII 演员表或此视频- 然后找出发生这种情况的任何原因。下面的文字描述提供了更多的上下文。
设置细节
- 机器 1 是一台 Arch Linux 笔记本电脑,在其
ssh
上生成,连接到运行 Armbian 的 SBC(Orange PI Zero)。 - SBC 本身通过以太网连接到 DSL 路由器,IP 为 192.168.1.150
- 笔记本电脑通过 WiFi 连接到路由器 - 使用官方 Raspberry PI WiFi 加密狗。
- 还有另一台笔记本电脑(机器 2)通过以太网连接到 DSL 路由器。
使用 iperf3 对链接进行基准测试
当使用 进行基准测试时iperf3
,笔记本电脑和 SBC 之间的链接低于理论上的 56 MBits/sec - 正如预期的那样,因为这是一个非常“拥挤的 2.4GHz” (公寓楼)内的 WiFi 连接。
更具体地说:在iperf3 -s
SBC 上运行后,在笔记本电脑上执行以下命令:
# iperf3 -c 192.168.1.150
Connecting to host 192.168.1.150, port 5201
[ 5] local 192.168.1.89 port 57954 connected to 192.168.1.150 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 2.99 MBytes 25.1 Mbits/sec 0 112 KBytes
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 28.0 MBytes 23.5 Mbits/sec 5 sender
[ 5] 0.00-10.00 sec 27.8 MBytes 23.4 Mbits/sec receiver
iperf Done.
# iperf3 -c 192.168.1.150 -R
Connecting to host 192.168.1.150, port 5201
Reverse mode, remote host 192.168.1.150 is sending
[ 5] local 192.168.1.89 port 57960 connected to 192.168.1.150 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 3.43 MBytes 28.7 Mbits/sec
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 39.2 MBytes 32.9 Mbits/sec 375 sender
[ 5] 0.00-10.00 sec 37.7 MBytes 31.6 Mbits/sec receiver
所以基本上,上传到 SBC 的速度大约是 24MBits/sec,从它下载(-R
)达到 32MBits/sec。
使用 SSH 进行基准测试
鉴于此,让我们看看 SSH 的票价如何。我在使用时第一次遇到了导致这篇文章的问题rsync
-borgbackup
他们都使用 SSH 作为传输层......所以让我们看看 SSH 在同一个链接上是如何执行的:
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
嗯,这速度太快了!比预期的链接速度慢得多...
(如果您不知道pv -ptevar
:它显示通过它的数据的当前和平均速率。在这种情况下,我们看到/dev/urandom
通过 SSH 读取数据并将数据发送到 SBC平均达到 400KB/s - 即 3.2MBits/sec,远低于预期的 24MBits/sec。)
为什么我们的链路以 13% 的容量运行?
或许是我们/dev/urandom
的错?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
不,绝对不是。
也许是 SBC 本身?也许处理起来太慢了?让我们尝试运行相同的 SSH 命令(即向 SBC 发送数据),但这次来自通过以太网连接的另一台机器(机器 2):
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
不,这很好用——SBC 上的 SSH 守护程序可以(轻松地)处理它的以太网链路提供的 11MBytes/sec(即 100MBits/sec)。
执行此操作时是否加载了 SBC 的 CPU?
没有。
所以...
- 网络方面(根据
iperf3
),我们应该能够将速度提高 10 倍 - 我们的 CPU 可以轻松适应负载
- ...而且我们不涉及任何其他类型的 I/O(例如驱动器)。
到底发生了什么?
Netcat 和 ProxyCommand 进行救援
让我们尝试一下普通的旧netcat
连接——它们的运行速度和我们预期的一样快吗?
在 SBC 中:
# nc -l -p 9988 | pv -ptebar > /dev/null
在笔记本电脑中:
# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s]
有用!并以预期的速度运行 - 好得多,快 10 倍 - 速度。
那么如果我使用 ProxyCommand 运行 SSH 来使用 nc 会发生什么?
# cat /dev/urandom | \
pv -ptebar | \
ssh -o "Proxycommand nc %h %p" [email protected] 'cat >/dev/null'
101MiB 0:00:30 [3.38MiB/s] [3.33MiB/s]
作品!10倍速度。
现在我有点困惑——当使用“naked”nc
作为 aProxycommand
时,你基本上不是在做与 SSH 完全相同的事情吗?即创建一个套接字,连接到 SBC 的 22 端口,然后将 SSH 协议铲到上面?
为什么产生的速度会有如此大的差异?
PS 这不是一个学术练习——因此我的borg
备份运行速度快了 10 倍。我只是不知道为什么:-)
编辑:在此处添加了该过程的“视频” 。计算从 ifconfig 的输出发送的数据包,很明显在两个测试中我们都发送了 40MB 的数据,以大约 30K 数据包的形式传输它们——在不使用ProxyCommand
.