Versi TL; DR
Tonton pemeran ASCII ini atau video ini - lalu buat alasan mengapa ini terjadi. Deskripsi teks berikut ini memberikan lebih banyak konteks.
Detail pengaturan
- Mesin 1 adalah laptop Arch Linux, yang mana
ssh
melahirkan, menghubungkan ke SBC yang menjalankan Armbian (sebuah Orange PI Zero). - SBC itu sendiri terhubung melalui Ethernet ke router DSL, dan memiliki IP 192.168.1.150
- Laptop terhubung ke router melalui WiFi - menggunakan dongle WiFi Raspberry PI resmi.
- Ada juga laptop lain (Mesin 2) yang terhubung melalui Ethernet ke router DSL.
Benchmarking tautan dengan iperf3
Ketika diperbandingkan dengan iperf3
, tautan antara laptop dan SBC kurang dari yang teoritis 56 MBits / detik - seperti yang diharapkan, karena ini adalah koneksi WiFi dalam 2,4GHz yang sangat ramai (gedung apartemen) .
Lebih khusus: setelah berjalan iperf3 -s
di SBC, perintah berikut dijalankan di laptop:
# 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
Jadi pada dasarnya, mengunggah ke SBC mencapai sekitar 24MBits / detik, dan pengunduhan darinya ( -R
) mencapai 32MBits / detik.
Pembandingan dengan SSH
Mengingat itu, mari kita lihat bagaimana tarif SSH. Saya pertama kali mengalami masalah yang mengarah ke pos ini saat menggunakan rsync
dan borgbackup
- keduanya menggunakan SSH sebagai lapisan transpor ... Jadi, mari kita lihat kinerja SSH pada tautan yang sama:
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
Nah, itu kecepatan yang luar biasa! Jauh lebih lambat daripada kecepatan tautan yang diharapkan ...
(Jika Anda tidak menyadarinya pv -ptevar
: ini akan menampilkan laju saat ini dan rata-rata data yang melewatinya. Dalam hal ini, kami melihat bahwa pembacaan dari /dev/urandom
dan mengirim data melalui SSH ke SBC rata-rata mencapai 400KB / dtk - yaitu 3,2 MB / dtk, angka yang jauh lebih rendah dari yang diharapkan 24Mt / dtk.)
Mengapa tautan kami berjalan pada 13% dari kapasitasnya?
Apakah ini mungkin /dev/urandom
kesalahan kita?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
Tidak, pasti tidak.
Apakah mungkin SBC itu sendiri? Mungkin terlalu lambat untuk diproses? Mari kita coba menjalankan perintah SSH yang sama (yaitu mengirim data ke SBC) tetapi kali ini dari komputer lain (Mesin 2) yang terhubung melalui Ethernet:
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
Tidak, ini berfungsi dengan baik - daemon SSH pada SBC dapat (dengan mudah) menangani 11MBytes / detik (yaitu 100MBits / detik) yang disediakan oleh tautan Ethernet.
Dan apakah CPU dari SBC dimuat saat melakukan ini?
Nggak.
Begitu...
- Dari segi jaringan (per
iperf3
) kita harus dapat melakukan 10x kecepatan - CPU kami dapat dengan mudah mengakomodasi beban
- ... dan kami tidak melibatkan jenis I / O lainnya (mis. drive).
Apa yang terjadi?
Netcat dan ProxyCommand untuk menyelamatkan
Mari kita coba netcat
koneksi lama biasa - apakah mereka berjalan secepat yang kita harapkan?
Dalam SBC:
# nc -l -p 9988 | pv -ptebar > /dev/null
Di laptop:
# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s]
Berhasil! Dan berjalan pada kecepatan yang diharapkan - jauh lebih baik, 10x lebih baik -.
Jadi apa yang terjadi jika saya menjalankan SSH menggunakan ProxyCommand untuk menggunakan 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]
Bekerja! Kecepatan 10x.
Sekarang saya agak bingung - ketika menggunakan "telanjang" nc
sebagai Proxycommand
, bukankah pada dasarnya Anda melakukan hal yang sama persis seperti SSH? yaitu membuat soket, menghubungkan ke port SBC 22, dan kemudian menyekop protokol SSH di atasnya?
Mengapa ada perbedaan besar dalam kecepatan yang dihasilkan?
PS Ini bukan latihan akademis - borg
cadangan saya berjalan 10 kali lebih cepat karena ini. Aku hanya tidak tahu mengapa :-)
EDIT : Menambahkan "video" dari proses di sini . Menghitung paket yang dikirim dari output ifconfig, jelas bahwa dalam kedua pengujian kami mengirim data 40MB, mentransmisikannya dalam paket sekitar 30K - hanya lebih lambat jika tidak digunakan ProxyCommand
.
sumber
nc
menggunakan buffering garis, sedangkanssh
tidak memiliki buffering. Jadi (atau jika demikian) lalu lintas ssh melibatkan lebih banyak paket.Jawaban:
Banyak terima kasih kepada orang-orang yang mengirimkan ide dalam komentar. Saya melewati semuanya:
Merekam paket dengan tcpdump dan membandingkan konten di WireShark
Tidak ada perbedaan yang penting dalam paket yang direkam.
Memeriksa pembentukan lalu lintas
Tidak tahu tentang ini - tetapi setelah melihat halaman "tc", saya bisa memverifikasi itu
tc filter show
tidak mengembalikan apa puntc class show
tidak mengembalikan apa puntc qdisc show
... mengembalikan ini:
... yang sepertinya tidak membedakan antara "ssh" dan "nc" - pada kenyataannya, saya bahkan tidak yakin apakah traffic shaping dapat beroperasi pada level proses (saya berharap ini bekerja pada alamat / port / Diferensial Bidang Layanan dalam IP Header).
Debian Chroot, untuk menghindari potensi "kepintaran" di klien Arch Linux SSH
Tidak, hasil yang sama.
Akhirnya - Nagle
Melakukan strace di pengirim ...
... dan melihat apa yang sebenarnya terjadi pada soket yang mentransmisikan data, saya perhatikan "pengaturan" ini sebelum transmisi yang sebenarnya dimulai:
Ini mengatur soket SSH untuk menonaktifkan algoritma Nagle. Anda dapat Google dan membaca semua tentang hal itu - tetapi apa artinya, adalah bahwa SSH memberikan prioritas untuk responsif terhadap bandwidth - ia memerintahkan kernel untuk mengirimkan apa pun yang tertulis pada soket ini segera dan tidak "menunda" menunggu pengakuan dari jarak jauh.
Apa artinya ini, secara sederhana, adalah bahwa dalam konfigurasi standarnya, SSH BUKAN cara yang baik untuk memindahkan data - bukan ketika tautan yang digunakan lambat (yang merupakan kasus bagi banyak tautan WiFi). Jika kami mengirim paket melalui udara yang "kebanyakan header", bandwidthnya terbuang sia-sia!
Untuk membuktikan bahwa ini memang penyebabnya, saya menggunakan LD_PRELOAD untuk "menjatuhkan" syscall khusus ini:
Di sana - kecepatan sempurna (well, secepat iperf3).
Moral cerita
Jangan menyerah :-)
Dan jika Anda memang menggunakan alat seperti
rsync
atauborgbackup
yang mengangkut data mereka melalui SSH, dan tautan Anda lambat, coba hentikan SSH dari menonaktifkan Nagle (seperti yang ditunjukkan di atas) - atau gunakanProxyCommand
untuk beralih SSH untuk terhubung melaluinc
. Ini dapat diotomatisasi dalam $ HOME / .ssh / config Anda:... sehingga semua penggunaan "orangepi" di masa depan sebagai host target di ssh / rsync / borgbackup untuk selanjutnya akan digunakan
nc
untuk terhubung (dan karenanya meninggalkan Nagle sendiri).sumber