[PL] czy 10 ms to duzo?
Opóźnienie (latency)
Latencję najprościej można zdefiniować jako czas potrzebny na przebycie pakietu z hosta źródłowego do docelowego i jego powrót. Do pomiaru latencji możemy użyć polecenia ping,
$ ping -c 3 google.com
PING google.com (216.58.214.206) 56(84) bytes of data.
64 bytes from bud02s23-in-f206.1e100.net (216.58.214.206): icmp_seq=1 ttl=54 time=25.1 ms
64 bytes from bud02s23-in-f206.1e100.net (216.58.214.206): icmp_seq=2 ttl=54 time=24.8 ms
64 bytes from bud02s23-in-f206.1e100.net (216.58.214.206): icmp_seq=3 ttl=54 time=26.0 ms
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 24.800/25.314/26.029/0.537 ms
W moim przypadku pakiet potrzebuje ~25 ms (0.025 s) na przebycie drogi z mojego hosta do serwera Google oraz powrót.
Co wpływa na latencję?
Do głównych czynników możemy zaliczyć jakość łączy pomiędzy hostami, medium transmisyjne (kabel, światłowód, łączność bezprzewodowa), fizyczna odległość, czy aktualne obciążenie routerów przerzucających nasze pakietu z jednego interfejsu na drugi ;-)
Czy 0.025 sekundy to dużo? Sprawdźmy to :)
Na potrzeby testu przygotowałem środowisko składające się z 3 serwerów wirtualnych uruchomionych na tym samym hoście,
- web-01.lab - serwer WWW z uruchomionym Wordpress-em (domyślna instalacja)
- cli-01.lab - serwer kliencki, posłuży nam do uruchamiania testów
- db-01.lab - dedykowany serwer bazy danych MySQL (domyślna instalacja)
Wykonam 2 testy,
Test #1 - zwiększanie latencji pomiędzy hostem klienckim (cli-01.lab) oraz naszym serwerem WWW (web-01.lab)
Test #2 - zwiększanie latencji pomiędzy serwerem WWW (web-01.lab) a serwerem bazodanowym (db-01.lab)
Jako narzędzie do testów użyję Apache Benchmark oraz tc do symulacji latencji.
AB nie pobiera pełnej strony a jedynie stronę główną bez plików (css, js, grafik), więc jest wysyłane 1 żądanie i w odpowiedzi jest tylko HTML ze strony głównej.
Test #1, zwiększamy opóźnienie pomiędzy klientem a serwerem WWW
no latency
Pierwszy test będzie wzorcowy bez żadnych opóźnień (pomijalne) pomiędzy hostami,
root@cli-01:/home/jamzed# ping -c 3 web-01.lab
PING web-01.lab (192.168.10.10) 56(84) bytes of data.
64 bytes from web-01.lab (192.168.10.10): icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=2 ttl=64 time=0.140 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=3 ttl=64 time=0.089 ms
--- web-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.077/0.102/0.140/0.027 ms
Apache Benchmark,
$ ab -n 100 -c 1 http://web-01.lab/
Concurrency Level: 1
Time taken for tests: 1.232 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 81.15 [#/sec] (mean)
Time per request: 12.323 [ms] (mean)
Time per request: 12.323 [ms] (mean, across all concurrent requests)
Transfer rate: 4112.49 [Kbytes/sec] received
Stronę pobraliśmy 100 razy i udało nam się uzyskać wydajność ~81 requestów na sekundę oraz średni czas ładowania strony ~12 ms.
10 ms opóźnienia pomiędzy cli-01 i web-01 (symulacja ruchu PL -> PL)
Na serwerze web-01 dodajemy opóźnienie 10 ms
root@web-01:/home/jamzed# tc qdisc del dev eth0 root netem delay 10ms
Sprawdźmy czy rzeczywiście pomiędzy hostami cli-01.lab a web-01 mamy +10ms oóźnienia,
root@cli-01:/home/jamzed# ping -c 3 web-01.lab
PING web-01.lab (192.168.10.10) 56(84) bytes of data.
64 bytes from web-01.lab (192.168.10.10): icmp_seq=1 ttl=64 time=10.0 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=2 ttl=64 time=10.1 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=3 ttl=64 time=10.1 ms
--- web-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 10.093/10.153/10.187/0.042 ms
Yup! wszystko działa jak należy, zróbmy test przy użyciu ab,
Concurrency Level: 1
Time taken for tests: 5.183 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 19.30 [#/sec] (mean)
Time per request: 51.825 [ms] (mean)
Time per request: 51.825 [ms] (mean, across all concurrent requests)
Transfer rate: 977.86 [Kbytes/sec] received
Okazuje się, że wprowadzenie 10 ms opóźnienie powoduje duży spadek wydajności, 81 req/s -> 20 req/s (spadek 4x), oraz czas ładowania się strony wzrasta z 12 ms do 52 ms (spadek 4x)…
40 ms opóźnienia pomiędzy cli-01 i web-01 (symulacja ruchu PL -> FR)
# tc qdisc add dev eth0 root netem delay 40ms
root@cli-01:/home/jamzed# ping -c 3 web-01.lab
PING web-01.lab (192.168.10.10) 56(84) bytes of data.
64 bytes from web-01.lab (192.168.10.10): icmp_seq=1 ttl=64 time=40.1 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=2 ttl=64 time=40.1 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=3 ttl=64 time=40.1 ms
--- web-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 40.121/40.138/40.148/0.164 ms
Concurrency Level: 1
Time taken for tests: 17.332 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 5.77 [#/sec] (mean)
Time per request: 173.318 [ms] (mean)
Time per request: 173.318 [ms] (mean, across all concurrent requests)
Transfer rate: 292.40 [Kbytes/sec] received
Przy dodatkowych 40ms udaje nam się uzyskać zaledwie 5 req/s (spadek 16x) i czas potrzebny na załadowanie się strony wzrósł do 173 ms (spadek 3.5x).
120 ms opóźnienia pomiędzy cli-01 i web-01 (symulacja PL -> US)
# tc qdisc add dev eth0 root netem delay 120ms
root@cli-01:/home/jamzed# ping -c 3 web-01.lab
PING web-01.lab (192.168.10.10) 56(84) bytes of data.
64 bytes from web-01.lab (192.168.10.10): icmp_seq=1 ttl=64 time=120 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=2 ttl=64 time=120 ms
64 bytes from web-01.lab (192.168.10.10): icmp_seq=3 ttl=64 time=120 ms
--- web-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 120.094/120.113/120.152/0.401 ms
Concurrency Level: 1
Time taken for tests: 49.192 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 2.03 [#/sec] (mean)
Time per request: 491.918 [ms] (mean)
Time per request: 491.918 [ms] (mean, across all concurrent requests)
Transfer rate: 103.02 [Kbytes/sec] received
120 ms opóźnienie powoduje, że mamy tylko 2 req/s (spadek 40x) a czas potrzebny na pobranie strony wzrósł do ~500 ms (spadek 40x)
Test #2, zwiększamy opóźnienie pomiędzy serwerem WWW a serwerem bazy danych
10 ms opóźnienia pomiędzy web-01 i db-01
root@web-01:/home/jamzed# ping -c 3 db-01.lab
PING db-01.lab (192.168.10.12) 56(84) bytes of data.
64 bytes from db-01.lab (192.168.10.12): icmp_seq=1 ttl=64 time=10.1 ms
64 bytes from db-01.lab (192.168.10.12): icmp_seq=2 ttl=64 time=10.3 ms
64 bytes from db-01.lab (192.168.10.12): icmp_seq=3 ttl=64 time=10.1 ms
--- db-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 10.170/10.226/10.323/0.107 ms
Concurrency Level: 1
Time taken for tests: 28.673 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 3.49 [#/sec] (mean)
Time per request: 286.732 [ms] (mean)
Time per request: 286.732 [ms] (mean, across all concurrent requests)
Transfer rate: 176.74 [Kbytes/sec] received
10 ms połączenia pomiędzy serwerem WWW a serwerem bazy danych drastycznie wpływa na wydajność serwera WWW, 3.5 req/s (spadek 23x) oraz 286 ms (spadek 23x).
W przypadku opóźnienia pomiędzy serwerem WWW -> DB spadek wydajności jest dużo większy niż w przypadku Klient -> WWW, ponieważ Wordpress potrzebuje wielokrotnie łączyć się do bazy danych i pobierać dane, od razu na pierwszy rzut oka widać, że jakiekolwiek opóźnienia pomiędzy serwerem aplikacyjnym a bazą danych znacznie bardziej wpływają na wydajność systemu.
40 ms opóźnienia pomiędzy web-01 i db-01
root@web-01:/home/jamzed# ping -c 3 db-01.lab
PING db-01.lab (192.168.10.12) 56(84) bytes of data.
64 bytes from db-01.lab (192.168.10.12): icmp_seq=1 ttl=64 time=40.1 ms
64 bytes from db-01.lab (192.168.10.12): icmp_seq=2 ttl=64 time=40.0 ms
64 bytes from db-01.lab (192.168.10.12): icmp_seq=3 ttl=64 time=40.1 ms
--- db-01.lab ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 40.096/40.116/40.128/0.164 ms
Concurrency Level: 1
Time taken for tests: 109.934 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 5189400 bytes
HTML transferred: 5168600 bytes
Requests per second: 0.91 [#/sec] (mean)
Time per request: 1099.341 [ms] (mean)
Time per request: 1099.341 [ms] (mean, across all concurrent requests)
Transfer rate: 46.10 [Kbytes/sec] received
Spadek wydajności serwera WWW jest bardzo duży, zaledwie 1 request na sekundę i czas ładowania strony powyżej 1 sekundy. Dalsze testy ze zwiększaniem czasu nie mają sensu, szkoda życia ;-)
Wnioski
Dodatkowe milisekundy opóźnienia pomiędzy klientem a serwerem WWW potrafią bardzo wpłynąć na wydajność całego systemu i może okazać się, że wolne ładowanie się strony wcale nie jest wynikiem braku CPU, pamięci czy IO, a po prostu zbyt dużą latencją pomiędzy naszymi użytkownikami a naszym serwerem. Ten problem potrafią rozwiązać systemy CDN
Dodatkowe milisekundy opóźnienia pomiędzy serwerem WWW a serwerem bazy danych są znacznie gorsze i skutecznie mogą uniemożliwić korzystanie z WWW. Z pomocą przyjdzie każdy cache (memcached, varnish)
Zrobiłem więcej testów dla lepszego zobrazowania problemu, pierwszy wykres jest dla testu #1 (opóźnienie pomiędzy klientem a serwerem WWW)
Drugi wykres jest dla opóźnienia pomiędzy serwerem WWW a serwerem bazy danych,
Wiedziałeś o tym, że opóźnienie nawet 10ms potrafi tak wpłynąć na wydajność? ;-)
Nic nie zrozumialem. Ale widac, ze sie starales. Pozdro
Dziękuję, TLDR; im większy PING tym wolniej strony klikają ;->
Wooooow :)
meep
Congratulations @jamzed! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP