Atakowanie problemu od różnych stron



Dzisiaj napiszę o sieciach (mój konik), problemie z opóźnieniami i dwóch rozwiązaniach (krótko- i długoterminowym).

Problem

Problem miała firma Meta (wtedy jeszcze nazywała się Facebook), a winne były: geografia i fizyka. Pierwsza, bo firma serwerownie miała tylko w Stanach Zjednoczonych, natomiast produkt^W klientów np. w Azji. Druga, fizyka – bo światło z Indii do Kalifornii leci prawie 50 milisekund, a w światłowodzie to, o panie!, nawet 75 ms.

Trzecim winnym jest historyczny stos protokołów – TCP/IP, HTTP, TLS. I ich gadatliwość, zanim można coś użytecznego odebrać. Pamiętając o tych nieskracalnych 75 milisekundach w jedną stronę, wyobraźmy sobie Prakesha chcącego otworzyć stronę Facebook. Załóżmy, że lokalny DNS zna już adres IP.

Nawiązanie połączenia TCP/IP wymaga wymiany przez obie strony 3 pakietów (z flagamia SYN→, SYN+ACK← i ACK→). Zestawienie połączenia musi potrwać co najmniej 225 milisekund.

Cool, możemy rozmawiać z serwerem FB. No to uzgodnijmy szyfrowanie, powiedzmy TLS1.2. Ta pogadanka to już 4 pakiety. Kolejne +300 milisekund przy dobrych wiatrach.

Teraz już możemy wysłać zapytanie HTTP (+75ms) i dostać odpowiedź (+75ms).

W ten sposób od żądania do otrzymania pierwszego bajtu minęło prawie ¾ sekundy. O ile Prakesh jeszcze czeka (bo przy obecnych attention spans mógł już się znudzić i pójść gdzieś indziej), zacznie mu się powoli ładować strona Facebooka. Powoli, bo każdy element strony to osobne zapytanie i odpowiedź HTTP (+150ms).

Jeśli przeglądarka jest w miarę ogarnięta, to otworzy kilka połączeń i będzie równolegle wysyłać zapytania. „W locie” możemy mieć dużo pakietów, ale każda między każdą parą zapytania-odpowiedzi musi minąć czas fizycznej propagacji.

Rozwiązanie na szybko

Inżynierowie Facebooka chcieli ułatwić życie użytkownik z Azji, wdrożyli więc rozwiązanie w postaci lokalnych punktów obecności (ang. points of presence, PoP). To taki punkt łączności znajdujący się (sieciowo) blisko Prakesha. Blisko, to znaczy nie 150 ms stąd, ale powiedzmy ~10 ms. Wciąż nawiązanie szyfrowanego połączenia to wymiana kilku pakietów, ale ponieważ cel jest blisko, to pierwsze pełnoprawne zapytanie można wysłać już po 50 milisekundach.

W pierwszej chwili może się wydawać, że zapytanie do PoP nie ma większego sensu. Dane i tak są przecież w serwerowni FB w Stanach, 75 ms stąd, i tam trzeba sięgnąć. Ale tutaj dzieje się ważna rzecz. PoP ma pewną pulę uprzednio zestawionych, szyfrowanych połączeń z serwerownią w USA. Nie trzeba otwierać nowego za każdym razem. Zapytanie użytkownika z Azji można od razu wysłać i po 150 ms dostać odpowiedź.

W ten sposób zamiast po 750 ms, pierwsze bajty dotrą już po 50+150+50 ms, czyli 3× szybciej. Not great, not terrible. Całość strony też załaduje się odpowiednio szybciej.

Rozwiązanie poprawne

Point-of-presence to fajny hack, ale długofalowe rozwiązanie wymagało dużych inwestycji, lat pracy i współpracy różnych podmiotów.

Lokalne serwerownie. Duży wydatek i wysiłek organizacyjny, ale też duży uzysk. Z Singapuru do Indii jest tylko 16 ms (tj. około 3,5 tys. km). Na innych kontynentach Meta też postawiła kilka lokalnych DC.

Jak inaczej można jeszcze dorzucić do pieca?

TCP Fast Open https://en.wikipedia.org/wiki/TCP_Fast_Open było próbą otwierania połączeń TCP/IP szybciej, mniejszą liczbą pakietów (pamiętamy, że każdy kosztuje nas 150 ms). Nie zażarło, ale za to…

Protokół QUIC pozbył się w ogóle TCP. “U” w nazwie jest od UDP, które jest bezpołączeniowe i pozwala zacząć rozmowę szybciej. Przyjął się, za chwilę do niego wrócimy. Jak również do zbliżonego protokołu SPDY, który próbował być szybszym HTTP z użyciem TCP.

TLS1.3. Szyfrowanie było najwolniejszym elementem nawiązywania połączenia (4 pakiety!). Opracowanie trybu 0rtt pozwoliło na nawiązywanie szyfrowanych sesji już pojedyńczą wymianą, o ile strony rozmawiały ze sobą wcześniej.

HTTP/2 i HTTP/3. W końcu samo wysyłanie zapytań o elementy strony też poprawiono. Co prawda już HTTP/1.1 z końca ubiegłego wieku pozwalało na wysłanie kilku zapytań na raz, zamiast sekwencyjnie (tzw. pipelinining), ale działało to tak se. W wyższych wersjach jest to dobrze rozwiązane. Nie musząc zestawiać nowych połączeń można dostać całą stronę szybciej.

Wspomniany wcześniej protokół SPDY był podstawą opracowania HTTP/2. Natomiast QUIC jest fundamentem na którym działa HTTP/3.

Points of Presence były sprytnym, szybkim rozwiązaniem. Dogłębne rozpykanie problemu wymagało współpracy wielu podmiotów – Meta, Google, programistów Linuksa, IETF i twórców przeglądarek. Ale dzięki temu możemy oglądać kotki szybciej.

Comments


Comments powered by Disqus