Gerade wenn man mit verteilten Computersystemen (z. B. Cluster) arbeitet, spielt die Latenz des Netzwerkes eine große Rolle, wenn es um sachen Performance geht.
Eventuell dauert die Replikation der Datenbank nicht lange, weil die Platten dicht sind, sondern einfach weil die Latenz zu Groß ist, oder die Verbindung einen hohen Package Loss aufweist.
Grund genug also zu testen, ab welcher Latenz oder Bandbreite es kritsch wird und ob etwas am Setup optimiert werden kann/sollte.
Zum Glück kann man in Linux, mit dem Tool tc
, sehr einfach Manipulationen am
Netzwerk durchführen.
Um den Versuch durchzuführen, benötigt man zwei oder mehr Systeme. Zusätzlich sollte man sich überlegen, welche Metriken man im Auge behalten möchte. Stauen sich irgendwo Dateien an, welche kopiert werden sollten? Bricht die Performance der Datenbank Replikation ein? Und so weiter...
Aufbau der Testumgebung
Ich nutze bei mir zwei VMs. Auf der einen lasse ich einen Webserver laufen und werde die Netzwerk-Manipulationen durchführen.
Die zweite Maschine wird die Daten mit wget
herunterladen. Dies ist natürlich
nur ein ganz simples Setup...
Erstellung der Testdatei
Als erstes müssen wir uns eine Datei erstellen, welche wir später über einen Webserver zum Download anbieten. Ich erstelle in meinem Beispiel einfach eine Datei mit einer Größe von 250MB.
root@ubuntu-1gb-fra1-02:/var/www/html# dd if=/dev/zero of=250mb.test bs=10485760 count=25
25+0 records in
25+0 records out
262144000 bytes (262 MB, 250 MiB) copied, 0.43299 s, 605 MB/s
Um später einen Vergleich machen zu können, lade ich diese Datei nun erst einmal herunter.
root@ubuntu-1gb-fra1-01:~# wget http://10.10.209.87/250mb.test
--2017-08-16 18:44:21-- http://10.10.209.87/250mb.test
Connecting to 10.10.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M)
Saving to: ‘250mb.test’
250mb.test 100%[===========================>] 250.00M 89.0MB/s in 2.8s
2017-08-16 18:44:24 (89.0 MB/s) - ‘250mb.test’ saved [262144000/262144000]
Zusätzlich führe ich noch einen paar Pings aus
root@ubuntu-1gb-fra1-01:~# ping -c 8 10.10.209.87
PING 10.10.209.87 (10.10.209.87) 56(84) bytes of data.
64 bytes from 10.10.209.87: icmp_seq=1 ttl=64 time=1.64 ms
64 bytes from 10.10.209.87: icmp_seq=2 ttl=64 time=0.719 ms
64 bytes from 10.10.209.87: icmp_seq=3 ttl=64 time=0.444 ms
64 bytes from 10.10.209.87: icmp_seq=4 ttl=64 time=0.428 ms
64 bytes from 10.10.209.87: icmp_seq=5 ttl=64 time=0.427 ms
64 bytes from 10.10.209.87: icmp_seq=6 ttl=64 time=0.399 ms
64 bytes from 10.10.209.87: icmp_seq=7 ttl=64 time=0.423 ms
64 bytes from 10.10.209.87: icmp_seq=8 ttl=64 time=0.500 ms
--- 10.10.209.87 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7003ms
rtt min/avg/max/mdev = 0.399/0.623/1.647/0.399 ms
Latenz erhöhen
Wie zu erwarten, ist die Latenz und die Übertragungsrate aktuell perfekt. Das ändern wir jetzt.
Wir fangen dazu einmal klein an, und setzen eine Latenz von 100ms
tc qdisc add dev eth0 root netem delay 100ms
Nun wiederholen wir unseren wget Test und die Pings
root@ubuntu-1gb-fra1-01:~# wget http://10.10.209.87/250mb.test
--2017-08-16 18:52:14-- http://10.10.209.87/250mb.test
Connecting to 10.10.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M)
Saving to: ‘250mb.test’
250mb.test 100%[===========================>] 250.00M 27.5MB/s in 18s
2017-08-16 18:52:33 (13.5 MB/s) - ‘250mb.test’ saved [262144000/262144000]
root@ubuntu-1gb-fra1-01:~# ping -c 8 10.10.209.87
PING 10.10.209.87 (10.10.209.87) 56(84) bytes of data.
64 bytes from 10.10.209.87: icmp_seq=1 ttl=64 time=102 ms
64 bytes from 10.10.209.87: icmp_seq=2 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=3 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=4 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=5 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=6 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=7 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=8 ttl=64 time=100 ms
--- 10.10.209.87 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7012ms
rtt min/avg/max/mdev = 100.423/100.797/102.240/0.647 ms
Wie man schön erkennen kann, ist die Downloadrate von 89MB/s auf 13,5MB/s gefallen und der Download der 250MB hat fast doppelt solange gedauert.
Auch die Ping Zeiten liegen nun immer ≥100ms.
Package Loss hinzufügen
Um die Lange noch zu verschlimmern, fügen wir noch etwas Package Loss hinzu. Damit müsst ihr etwas vorsichtig sein, besonders wenn ihr wie ich, über SSH auf das System zugreift! Ich setze bei mir einmal einen Wert von 20% bei 100ms Latenz.
tc qdisc change dev eth0 root netem loss 10% delay 100ms
Ok 20% war dann wohl doch etwas zu viel... Ich habe den wget Test bei mir abgebrochen weil ich keine Stunde warten wollte.
root@ubuntu-1gb-fra1-01:~# wget http://10.10.209.87/250mb.test
--2017-08-16 18:58:41-- http://10.10.209.87/250mb.test
Connecting to 10.10.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M)
Saving to: ‘250mb.test’
250mb.test 3%[===> ] 8.59M 57.1KB/s eta 59m 55s
^C
Im Ergebnis von Ping sieht man jedoch schön, was ich da angerichtet habe.
root@ubuntu-1gb-fra1-01:~# ping -c 10 10.10.209.87
PING 10.10.209.87 (10.10.209.87) 56(84) bytes of data.
64 bytes from 10.10.209.87: icmp_seq=1 ttl=64 time=101 ms
64 bytes from 10.10.209.87: icmp_seq=2 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=4 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=5 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=6 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=7 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=8 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=9 ttl=64 time=101 ms
64 bytes from 10.10.209.87: icmp_seq=10 ttl=64 time=100 ms
--- 10.10.209.87 ping statistics ---
10 packets transmitted, 9 received, 10% packet loss, time 9020ms
rtt min/avg/max/mdev = 100.430/100.720/101.765/0.527 ms
Ich habe 10 Pings abgeschickt, deshalb genau 10% Package Loss.
Ok, also weg mit dem Package Loss
tc qdisc del dev eth0 root netem loss 10% delay 100ms
Bandbreite einschränken
Je nachdem wo unsere Systeme stehen, habe diese eventuell nicht immer die beste Bandbreite zur Verfügung, ein gutes Beispiel ist der Upload am heimischen DSL Anschluss.
Ich setze also wieder eine Latenz von 100ms und beschränke die Bandbreite auf 200kbit/s
tc qdisc add dev eth0 root netem delay 100ms rate 2000kbit
root@ubuntu-1gb-fra1-01:~# wget http://10.10.209.87/250mb.test
--2017-08-16 19:17:24-- http://10.10.209.87/250mb.test
Connecting to 10.10.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M)
Saving to: ‘250mb.test’
250mb.test 3%[===> ] 8.53M 233KB/s eta 17m 41s
^C
Auch in diesem Fall hatte ich keine Lust, 18 Minuten auf wget zu warten. Man sieht allerdings gut, das die Rate bei 233KB/s liegt.
Einen Ping stört dies natürlich nicht weiter
root@ubuntu-1gb-fra1-01:~# ping -c 10 10.10.209.87
PING 10.10.209.87 (10.10.209.87) 56(84) bytes of data.
64 bytes from 10.10.209.87: icmp_seq=1 ttl=64 time=102 ms
64 bytes from 10.10.209.87: icmp_seq=2 ttl=64 time=101 ms
64 bytes from 10.10.209.87: icmp_seq=3 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=4 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=5 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=6 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=7 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=8 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=9 ttl=64 time=100 ms
64 bytes from 10.10.209.87: icmp_seq=10 ttl=64 time=101 ms
--- 10.10.209.87 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 100.776/101.065/102.247/0.598 ms
Experimentieren
Mit all diesen Werten muss man natürlich etwas experimentieren und spielen. Dabei muss dann immer die Performance der Applikation überwacht werden.
Wichtig ist auch, zu wissen was man möchte. Es macht nicht wirklich Sinn, die Applikation auf hohe Latenzen oder Package Loss zu optimiert, wenn dies in der Praxis nicht auftritt, weil alle Server im gleichen Rack hängen. Auch ist es nicht immer eine gute Idee, Cluster über mehrere Standorte zu verteilen.
Bitte vergesst nicht, die Einstellungen wieder zu löschen
tc qdisc del dev eth0 root netem delay 100ms rate 2000kbit
Ich habe das bei mir zur Sicherheit noch einmal mit wget überprüft
root@ubuntu-1gb-fra1-01:~# wget http://10.10.209.87/250mb.test
--2017-08-16 19:28:10-- http://10.10.209.87/250mb.test
Connecting to 10.10.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M)
Saving to: ‘250mb.test’
250mb.test 100%[===========================>] 250.00M 171MB/s in 1.5s
2017-08-16 19:28:12 (171 MB/s) - ‘250mb.test’ saved [262144000/262144000]