[PL] czy 10 ms to duzo?

in #polish7 years ago (edited)


steem_latency.png

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,


infra.png

  • 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,


no_latency.png

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


10ms_latency.png

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)


40ms_latency.png

# 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)


120ms_latency.png

# 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


db10ms_latency.png

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


db40ms_latency.png

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)


latency_request_load_time.png

Drugi wykres jest dla opóźnienia pomiędzy serwerem WWW a serwerem bazy danych,


latency_www_db.png

Wiedziałeś o tym, że opóźnienie nawet 10ms potrafi tak wpłynąć na wydajność? ;-)


Jeśli podobał Ci się post, zagłosuj i zacznij mnie śledzić ;-)

Sort:  

Nic nie zrozumialem. Ale widac, ze sie starales. Pozdro

Dziękuję, TLDR; im większy PING tym wolniej strony klikają ;->

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

By upvoting this notification, you can help all Steemit users. Learn how here!

Coin Marketplace

STEEM 0.28
TRX 0.11
JST 0.034
BTC 66077.75
ETH 3167.77
USDT 1.00
SBD 4.01