Perl und SSH – Benchmarks
Endlich komme ich mal wieder dazu etwas zu schreiben.
Unsere Hostingsoftware kontrolliert alle Serversysteme uA über simple Kommandoabgabe per SSH .. quasi SSH PUSH. Unter Perl gibt es dafür drei gängige Wege:
Da ich bisher gute Erfahrungen mit Net::SSH::Perl gesammelt hatte, entschied ich damals auch wieder dafür. Jetzt kam ich aber endlich mal dazu ein paar Benchmarks laufen zu lassen.
Installation
Dafür wollte ich alle Module auf meinem Laptop (Ubuntu 8.04) installieren. Hier fangen die ersten Probleme schon an. Als Debian-Administrator sollte man normalerweise bei seinem/-n Repository/-ies bleiben. Wenn mal das ein oder andere Programm nicht verfügbar ist, dann kann man ein lokales Repository aufsetzen und es hier selber erstellen. Nur im schlimmsten Fall sollte man den “./configure && make && make install”-Weg gehen. Wenn man diese Denke einmal hat, dann bleibt man zumeist dabei. Daher habe ich erst einmal versucht alle Module per apt-get zu installieren. Net::SSH und Net::SSH::Expect sind kein Problem:
apt-get install libnet-ssh-perl libnet-ssh-expect-perl
Da es aber dh-make-perl gibt und ich damit bisher überaus gute Erfahrungen gesammelt habe.. also los:
dh-make-perl --build --cpan Net::SSH::Perl
OOps, jetzt geht es los: Dependencies.Wir brauchen: Crypt::Random, Crypt::Primes, Tie::EncryptedHash, Convert::ASCII::Armour, Digest::MD2, Sort::Versions un deren dependencies.
Einige davon sind wiederum im Standard Ubuntu Repo:
apt-get install libdigest-md5-perl libsort-versions-perl
Den Rest (und deren Dependencies) muss man selbst bauen. Das habe ich gemacht, daher für alle die auch fanatisch auf .debs beharren:
- libclass-loader-perl_2.03-1_all.deb
- libconvert-ascii-armour-perl_1.4-1_all.deb
- libcrypt-dsa-perl_0.14-1_all.deb
- libcrypt-primes-perl_0.50-1_all.deb
- libcrypt-random-perl_1.25-1_all.deb
- libcrypt-rsa-perl_1.97-1_all.deb
- libexpect-perl_1.21-1_all.deb
- libmath-pari-perl_2.010800-1_i386.deb
- libnet-ssh2-perl_0.18-1_i386.deb
- libnet-ssh-expect-perl_1.09-1_all.deb
- libnet-ssh-perl-perl_1.33-1_all.deb
- libtie-encryptedhash-perl_1.24-1_all.deb
Außerdem sollte man noch unbedingt Math::BigInt::GMP damit für Arithmetic mit sehr großen Integern (z.B. Primzahlen für RSA) die GMP Bibliothek verwendet werden kann.
apt-get install libpari2-gmp libmath-bigint-gmp-perl
Benchmark
Nachdem ich nun alles installiert hatte konnte es los gehen. Da ich in unserer App ausschließlich Authentifikation per Publickey verwende habe ich das auch im Benchmark so verwenden.
Auch nach mehrmaligem hin und her habe ich es leider nicht geschaft Net::SSH::ssh_cmd zu überzeugen einen anderen Port als 22 zu verwenden. Da ich von dem nicht-objektorientiertem Ansatz aber sowieso nicht sehr angetan war habe ich mich auch nicht weiter bemüht und es vom Benchmark ausgeschlossen.
mit `ssh $host $cmd` ..
Test plain ssh Test 0 Create: 7e-06 Cmds : 2.497795 End : 1.3e-05 Total : 2.497815 Test 1 Create: 7e-06 Cmds : 2.357254 End : 1.4e-05 Total : 2.357275 Test 2 Create: 7e-06 Cmds : 2.342908 End : 1.4e-05 Total : 2.342929 Test 3 Create: 6e-06 Cmds : 2.377186 End : 1.4e-05 Total : 2.377206 Test 4 Create: 7e-06 Cmds : 2.35976 End : 1.4e-05 Total : 2.359781 Test 5 Create: 7e-06 Cmds : 2.319784 End : 1.4e-05 Total : 2.319805 Test 6 Create: 7e-06 Cmds : 2.412413 End : 1.5e-05 Total : 2.412435 Test 7 Create: 7e-06 Cmds : 2.319923 End : 1.4e-05 Total : 2.319944 Test 8 Create: 7e-06 Cmds : 2.339805 End : 1.5e-05 Total : 2.339827 Test 9 Create: 7e-06 Cmds : 2.380184 End : 1.4e-05 Total : 2.380205 -> 10 Times in 23.708172ms, 2.3708172ms each
Für Net::SSH::Expect
Test Net::SSH::Expect Test 0 Create: 0.004561 Cmds : 10.234262 End : 1.000475 Total : 11.239298 Test 1 Create: 0.007057 Cmds : 10.292379 End : 1.00037 Total : 11.299806 Test 2 Create: 0.005133 Cmds : 10.264342 End : 1.000371 Total : 11.269846 Test 3 Create: 0.005487 Cmds : 10.343972 End : 1.000357 Total : 11.349816 Test 4 Create: 0.005119 Cmds : 10.355061 End : 1.000344 Total : 11.360524 Test 5 Create: 0.005352 Cmds : 10.283438 End : 1.000371 Total : 11.289161 Test 6 Create: 0.005112 Cmds : 10.354367 End : 1.000346 Total : 11.359825 Test 7 Create: 0.014362 Cmds : 10.232602 End : 1.000225 Total : 11.247189 Test 8 Create: 0.009221 Cmds : 10.283014 End : 1.000368 Total : 11.292603 Test 9 Create: 0.005114 Cmds : 10.321884 End : 1.000341 Total : 11.327339 -> 10 Times in 113.036898ms, 11.3036898ms each
Für Net::SSH::Perl
Test Net::SSH::Perl Test 0 Create: 2.73767 Cmds : 0.787246 End : 0.000604 Total : 3.52552 Test 1 Create: 2.424129 Cmds : 0.735019 End : 0.000221 Total : 3.159369 Test 2 Create: 2.236475 Cmds : 0.816222 End : 0.000232 Total : 3.052929 Test 3 Create: 2.473703 Cmds : 0.779792 End : 0.000136 Total : 3.253631 Test 4 Create: 2.240349 Cmds : 0.802453 End : 0.000266 Total : 3.043068 Test 5 Create: 2.244083 Cmds : 0.815537 End : 0.000157 Total : 3.059777 Test 6 Create: 2.280868 Cmds : 0.785698 End : 0.000128 Total : 3.066694 Test 7 Create: 2.268959 Cmds : 0.786562 End : 0.000223 Total : 3.055744 Test 8 Create: 2.285328 Cmds : 0.808838 End : 0.000129 Total : 3.094295 Test 9 Create: 2.274975 Cmds : 0.834888 End : 0.000128 Total : 3.109991 -> 10 Times in 31.422326ms, 3.1422326ms each
Für Net::SSH2
Test Net::SSH2 Test 0 Create: 0.323864 Cmds : 2.697024 End : 0.000811 Total : 3.021699 Test 1 Create: 0.38504 Cmds : 2.661479 End : 0.000668 Total : 3.047187 Test 2 Create: 0.357351 Cmds : 2.666086 End : 0.000306 Total : 3.023743 Test 3 Create: 0.341225 Cmds : 2.664191 End : 0.00075 Total : 3.006166 Test 4 Create: 0.446899 Cmds : 2.652236 End : 0.000758 Total : 3.099893 Test 5 Create: 0.342783 Cmds : 2.686329 End : 0.000668 Total : 3.02978 Test 6 Create: 0.384013 Cmds : 2.665152 End : 0.000585 Total : 3.04975 Test 7 Create: 0.357921 Cmds : 2.663923 End : 0.000754 Total : 3.022598 Test 8 Create: 0.44129 Cmds : 2.707881 End : 0.000611 Total : 3.149782 Test 9 Create: 0.352843 Cmds : 2.65385 End : 0.000556 Total : 3.007249 -> 10 Times in 30.458972ms, 3.0458972ms each
Fazit
Der Aufruf mit Backticks ist tatsächlich am schnellsten. Wenn man bei Net::SSH::Perl allerdings mehrere Aufrufe bündelt dann sollte man hier bessere Werte erreichen da der Hauptzeitanteil im “create” liegt. Net::SSH2 ist erstaunlich langsam. Net::SSH::Expect schneidet am schlechtesten ab und bietet sich nur an wenn man einzelne Aufrufe macht und sich auf dem Zielsystem (wegen der massiven Abhängigkeiten) kein Net::SSH::Perl installieren lässt.
Ich habe noch ein wenig mit verschieden Verschlüsselungen (3des-cbc,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128) getestet aber konnte keine signifikanten Unterschiede messen.
Hier das Benchmarkscript zum download
My Name is Ulrich Kautz and this is my private blog about server administration, perl programming and some other stuff that is on my mind. I study part-time computer sience at FU Berlin and work as sys admin and web developer at our hosting company