TL、DRバージョン
このASCII変換を見るまたはこの動画- その後、これが起こる理由を学びます。以下のテキストの説明は追加のコンテキストを提供します。
設定の詳細
ssh
Machine 1は、Armbianを実行しているOrange PI Zero(SBC)に接続されたビルドを構築したArch Linuxノートブックです。- SBC自体はIP 192.168.1.150のイーサネットを介してDSLルータに接続されます。
- ラップトップは公式Raspberry PI WiFiアダプタを使用してWiFi経由でルーターに接続されます。
- イーサネット経由でDSLルーターに接続されている他のノートブック(マシン2)があります。
iperf3を使用したベンチマークリンク
ノートブックとSBCの間のリンクは、以下を使用してベンチマークしたときにiperf3
理論的な56MBits /秒未満でした。(アパート)。
具体的には、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 /秒、-R
SBC()からダウンロードする速度は最大32MBits /秒です。
SSHを使用したベンチマーク
これを念頭に置いて、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 /秒です。予想される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 [email protected] 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
いいえ、これはうまくいきます。 SBCのSSHデーモンは、イーサネットリンクで提供される11MBytes /秒(100MBits /秒)を(簡単に)処理できます。
これを行うと、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を使ってncを使ってSSHを実行するとどうなりますか?
# 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倍速いです。
今少し混乱しています。nc
のように "naked"を使用するとき、Proxycommand
基本的にSSHと同じことをするのではありませんか?つまり、ソケットを作成してSBCのポート22に接続し、ここにSSHプロトコルを追加しますか?
最終速度になぜそんなに大きな違いがありますか?
PS:これはありません学業練習-borg
その結果、バックアップは10倍速く実行されます。なぜそうなのか分からない :-)
編集する:コース「ビデオ」を追加ここ。 ifconfigの出力から送信されたパケットを数えてみると、両方のテストで40MBのデータを送信し、約30Kパケットで送信したことが明らかです。使用しないときははるかに遅いですProxyCommand
。
答え1
コメントでアイデアを提供してくださった方々に心から感謝します。私はこれらすべてを経験しました:
tcpdump を使用してパケットを記録し、WireShark の内容を比較します。
# tcpdump -i wlan0 -w good.ssh & \
cat signature | ssh -o "ProxyCommand nc %h %p" \
[email protected] 'cat | md5sum' ; \
killall tcpdump
# tcpdump -i wlan0 -w bad.ssh & \
cat signature | ssh [email protected] 'cat | md5sum' ; \
killall tcpdump
記録されたパケットに大きな違いはありません。
トラフィック形式の確認
これについて何も知らないが、「tc」マンページを見てこれを確認することができました。
tc filter show
何も返さないtc class show
何も返さないtc qdisc show
...次を返します。
qdisc noqueue 0: dev lo root refcnt 2
qdisc noqueue 0: dev docker0 root refcnt 2
qdisc fq_codel 0: dev wlan0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 32Mb ecn
...これは「ssh」と「nc」を区別できないようです。実際には、トラフィックの調整がプロセスレベルで機能しているかどうかはわかりません(アドレス/ポート/差別化で動作することを期待しています))のIPヘッダーサービスフィールド。
Arch Linux SSHクライアントの潜在的な「賢さ」を避けるためのDebian Chroot
いいえ、結果は同じです。
最後に - Nagel
送信者からstraceを実行します...
pv data | strace -T -ttt -f ssh 192.168.1.150 'cat | md5sum' 2>bad.log
...そして、データが転送されるソケットで実際に何が起こっているのかを確認するために、実際の転送が始まる前に次の「設定」を確認しました。
1522665534.007805 getsockopt(3, SOL_TCP, TCP_NODELAY, [0], [4]) = 0 <0.000025>
1522665534.007899 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0 <0.000021>
Nagleのアルゴリズムを無効にするようにSSHソケットを設定します。 Google でこれに関するすべての内容を読むことができます。しかし、これが意味するのは、SSHが帯域幅よりも応答性を優先するということです。これは、リモートチェックから出るまで「遅延」するのではなく、このソケットに書き込まれたすべてのコンテンツをすぐに送信するようにカーネルに指示します。
簡単に言えば、これは基本的な構成では、SSHがデータを転送する良い方法ではないことを意味します。つまり、使用されているリンクが遅い場合(多くのWiFiリンクの場合のように)。 「ほとんどのヘッダー」パケットをワイヤレスで送信すると、帯域幅が無駄になります!
これが実際に犯人であることを証明するために、LD_PRELOADを使用してこの特定のシステムコールを「削除」しました。
$ cat force_nagle.c
#include <stdio.h>
#include <dlfcn.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
int (*osetsockopt) (int socket, int level, int option_name,
const void *option_value, socklen_t option_len) = NULL;
int setsockopt(int socket, int level, int option_name,
const void *option_value, socklen_t option_len)
{
int ret;
if (!osetsockopt) {
osetsockopt = dlsym(RTLD_NEXT, "setsockopt");
}
if (option_name == TCP_NODELAY) {
puts("No, Mr Nagle stays.");
return 0;
}
ret = osetsockopt(socket, level, option_name, option_value, option_len);
return ret;
}
$ gcc -fPIC -D_GNU_SOURCE -shared -o force_nagle.so force_nagle.c -ldl
$ pv /dev/shm/data | LD_PRELOAD=./force_nagle.so ssh [email protected] 'cat >/dev/null'
No, Mr Nagle stays.
No, Mr Nagle stays.
100MiB 0:00:29 [3.38MiB/s] [3.38MiB/s] [================================>] 100%
そこには完璧な速度があります(iperf3ほど高速です)。
ストーリー詐欺
決してあきらめないでください:-)
rsync
SSH経由でデータを転送するなどのツールを使用していて、borgbackup
リンクが遅い場合は、Nagleを無効にしてSSHをブロックするか(上記を参照)、Nagleを使用してProxyCommand
SSHを切り替えてみてくださいnc
。これは$ HOME /で自動的に実行できます。 SSH/構成から:
$ cat .ssh/config
...
Host orangepi
Hostname 192.168.1.150
User root
Port 22
# Compression no
# Cipher None
ProxyCommand nc %h %p
...
nc
...以降、ssh / rsync / borgbackupでターゲットホストとして "orangepi"を使用するすべての操作が接続に使用されます(したがってNagleを気にしないでください)。