Версия TL; DR
Посмотрите этот актерский состав ASCII или это видео, а затем найдите причины, по которым это происходит. Текстовое описание, которое следует, обеспечивает больше контекста.
Подробности настройки
- Machine 1 - это портативный компьютер Arch Linux, на котором
ssh
он создается, подключаясь к SBC, работающему на Armbian (Orange PI Zero). - Сам SBC подключен через Ethernet к маршрутизатору DSL и имеет IP-адрес 192.168.1.150.
- Ноутбук подключен к маршрутизатору через WiFi - с помощью официального ключа Raspberry PI WiFi.
- Есть также еще один ноутбук (машина 2), подключенный через Ethernet к маршрутизатору DSL.
Сравнительный анализ связи с iperf3
При сравнительном тестировании iperf3
связь между ноутбуком и SBC меньше теоретической скорости 56 Мбит / с, как и ожидалось, поскольку это соединение WiFi в очень «переполненном 2,4 ГГц» (жилой дом) .
Более конкретно: после запуска 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 достигает около 24 Мбит / с, а загрузка с него ( -R
) достигает 32 Мбит / с.
Бенчмаркинг с 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 в среднем достигает 400 КБ / с - то есть 3,2 Мбит / с, что намного меньше, чем ожидаемые 24 Мбит / с.)
Почему наша ссылка работает на 13% своей емкости?
Возможно, это наша /dev/urandom
вина?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
Нет, определенно нет.
Возможно, это сам SBC? Возможно, это слишком медленно для обработки? Давайте попробуем запустить ту же команду SSH (т.е. отправить данные в SBC), но на этот раз с другой машины (машина 2), которая подключена через Ethernet:
# cat /dev/urandom | \
pv -ptebar | \
ssh root@192.168.1.150 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
Нет, это работает нормально - демон SSH на SBC может (легко) обрабатывать 11 МБ / с (то есть 100 Мбит / с), которые обеспечивает его канал Ethernet.
И загружается ли процессор SBC при этом?
Нет.
Так...
- по сети (в соответствии с
iperf3
) мы должны быть в состоянии сделать в 10 раз быстрее - наш процессор может легко справиться с нагрузкой
- ... и мы не задействуем какой-либо другой тип ввода / вывода (например, накопители).
Какого черта происходит?
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 раз лучше - скорости.
Так что же произойдет, если я запускаю SSH с помощью ProxyCommand для использования nc?
# 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? т.е. создать сокет, подключиться к порту 22 SBC, а затем переложить поверх него протокол SSH?
Почему такая огромная разница в скорости?
PS Это не было академическим упражнением - borg
из-за этого мое резервное копирование выполняется в 10 раз быстрее. Я просто не знаю почему :-)
РЕДАКТИРОВАТЬ : Добавлено "видео" процесса здесь . Подсчитав пакеты, отправленные с выхода ifconfig, становится ясно, что в обоих тестах мы отправляем 40 МБ данных, передавая их примерно в пакетах по 30 КБ - просто намного медленнее, когда они не используются ProxyCommand
.
nc
использует буферизацию строки, аssh
не имеет буферизации. Так (или если так) трафик ssh включает больше пакетов.