TL; DR版本
观看此ASCII转换或该视频 -然后提出发生这种情况的任何原因。下面的文字描述提供了更多的上下文。
设置细节
- 机器1是一台Arch Linux笔记本电脑,在其
ssh
上生成,并连接到运行Armbian的SBC(橙色PI Zero)。 - SBC本身通过以太网连接到DSL路由器,并且IP为192.168.1.150
- 笔记本电脑通过Raspberry PI WiFi官方加密狗通过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 /秒,从SBC的下载速度(-R
)达到32MBits /秒。
使用SSH进行基准测试
鉴于此,让我们看看SSH的价格如何。我首先经历了使用rsync
和时导致这篇文章的问题borgbackup
-两者都使用SSH作为传输层...所以让我们看看SSH如何在同一链接上执行:
# cat /dev/urandom | \
pv -ptebar | \
ssh root@192.168.1.150 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
好吧,那真是太糟糕了!比预期的链接速度慢得多...
(如果您不知道pv -ptevar
:它显示通过它的当前数据速率和平均数据速率。在这种情况下,我们看到/dev/urandom
通过SSH 读取数据并将数据发送到SBC平均达到400KB / s,即3.2MBits /秒,远低于预期的24MBits /秒。)
为什么我们的链接以其容量的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 root@192.168.1.150 '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]
有用!并以预期的速度(好得多,好十倍)运行。
那么,如果我使用ProxyCommand来运行nc来运行SSH,会发生什么?
# cat /dev/urandom | \
pv -ptebar | \
ssh -o "Proxycommand nc %h %p" root@192.168.1.150 'cat >/dev/null'
101MiB 0:00:30 [3.38MiB/s] [3.33MiB/s]
作品!10倍速度。
现在我有点困惑-当使用“裸” nc
作为时Proxycommand
,您基本上不是在做与SSH完全相同的事情吗?即创建一个套接字,连接到SBC的端口22,然后通过它铲除SSH协议?
为什么最终的速度会有如此巨大的差异?
PS:这不是学术活动,因此我的borg
备份运行速度提高了10倍。我只是不知道为什么:-)
编辑:在此处添加了该过程的“视频” 。计算从ifconfig输出发送的数据包,很明显,在这两个测试中,我们正在发送40MB的数据,并以大约30K的数据包传输它们-不使用时速度要慢得多ProxyCommand
。
nc
使用行缓冲,而ssh
没有缓冲。因此(如果是这样),ssh流量涉及更多数据包。