Wprowadzenie: przyczyny i łagodzenie opóźnień DNS
Strony internetowe stają się coraz bardziej złożone i odwołują się do zasobów z wielu domen, dlatego wyszukiwania DNS mogą bardzo utrudniać przeglądanie stron. Za każdym razem, gdy klient musi wysyłać zapytania do resolvera DNS przez sieć, opóźnienia mogą być znaczne, w zależności od odległości i liczby serwerów nazw, które musi wykonać zapytanie (więcej niż 2 rzadko, ale może się to zdarzyć). Na przykład takie zrzuty ekranu pokazują dane o czasie zarejestrowane w narzędziu do pomiaru szybkości działania stron. Każdy słupek przedstawia zasób, do którego odwołuje się strona, czarne segmenty wskazują wyszukiwania DNS. Na tej stronie w ciągu pierwszych 11 sekund następuje 13 wyszukiwań. Chociaż kilka wyszukiwań jest przeprowadzanych równolegle, zrzut ekranu pokazuje, że wymagane jest 5 serii wyszukiwania, co pozwala uwzględnić kilka sekund całkowitego czasu wczytywania strony.
Opóźnienie DNS składa się z 2 elementów:
- Czas oczekiwania między klientem (użytkownikiem) a serwerem DNS. W większości przypadków wynika to zwykle z ograniczeń czasu błądzenia (RTT) w systemach sieciowych: odległości między komputerami klienta i serwerów, zatłoczenia sieci, utraty pakietów i opóźnień opóźnień w ponownym przesyłaniu (średnio jedna sekunda), przeciążenia serwerów, ataków typu „odmowa usługi” itp.
- Czas oczekiwania między rozpoznaniem serwerów a innymi serwerami nazw.
To źródło opóźnienia jest spowodowane głównie przez następujące czynniki:
- Brak w pamięci podręcznej. Jeśli nie można wyświetlić odpowiedzi z pamięci podręcznej resolvera, ale wymaga ona rekurencyjnego wysyłania zapytań do innych serwerów nazw, dodane opóźnienie sieci jest znaczne, szczególnie wtedy, gdy wiarygodne serwery są zdalne.
- Obsługa administracyjna jest poniżej założeń. Jeśli resolvery DNS są przeciążone, muszą znajdować się w kolejce żądań odpowiedzi DNS i odpowiedzi na nie oraz mogą zacząć rzucać i ponownie przesyłać pakiety.
- Szkodliwy ruch. Nawet jeśli usługa DNS zostanie ograniczona, ruch DoS może powodować nadmierne obciążenie serwerów. Analogicznie do ataków w stylu Kaminskiego mogą zaliczać się rozwiązania do powodzi, które gwarantują zapełnienie pamięci podręcznej i wymagają wychodzących żądań rozwiązania problemu.
Uważamy, że najczęstszą przyczyną opóźnienia DNS jest najczęstsza przyczyna braku pamięci podręcznej, więc omówimy ją poniżej.
Brak w pamięci podręcznej
Nawet jeśli resolver ma dużo zasobów lokalnych, trudno jest unikać podstawowych opóźnień związanych z rozmowami ze zdalnymi serwerami nazw. Innymi słowy, przy założeniu, że resolver jest wystarczająco sprawny, aby działania w pamięci podręcznej nie zajmowały czasu po stronie serwera, opóźnienia w pamięci podręcznej pozostają bardzo drogie ze względu na czas oczekiwania. Aby rozwiązać problem z pominięciem danych, resolver musi porozmawiać z co najmniej 1 serwerem nazw, ale często z użyciem co najmniej 2 zewnętrznych serwerów nazw. W przypadku robota indeksującego Google zaobserwowaliśmy, że w przypadku serwerów nazw średni czas oczekiwania na odpowiedź wynosi 130 ms. Jednak pełne wykorzystanie 4–6% żądań spowodowało przekroczenie limitu czasu z powodu utraty pakietów UDP i nieosiągalnych serwerów. Jeśli uwzględnimy błędy, takie jak utrata pakietów, serwery nazw, błędy konfiguracji DNS itd., rzeczywisty średni czas zakończenia obsługi wynosi 300–400 ms. Występuje jednak duża zmienność i długi ogon.
Choć współczynnik wypełnienia pamięci podręcznej może się różnić w zależności od serwera DNS, jej brak może być trudny z następujących powodów:
- Rozmiar internetu i jego rozwój. W miarę jak internet się powiększa, większość nowych treści ma znaczenie marginalne. Mimo że kilka witryn (i tym samym nazw DNS) jest bardzo popularnych, większość z nich interesuje tylko kilku użytkowników i rzadko uzyskuje do nich dostęp. Dlatego większość żądań skutkuje brakiem pamięci.
- Długi czas życia danych (TTL). Trend względem niższych wartości TTL DNS oznacza, że rozdzielczość wymaga częstszych wyszukiwań.
- Izolacja pamięci podręcznej. Serwery DNS są zwykle wdrażane za systemami równoważenia obciążenia, które przypisują zapytania do różnych maszyn losowo. Dzięki temu każdy serwer zachowuje osobną pamięć podręczną, zamiast ponownie używać rozdzielczości zapisanych w pamięci podręcznej ze wspólnej puli.
Łagodzenie
W Google Public DNS wdrożyliśmy kilka metod przyspieszania wyszukiwania DNS. Niektóre z nich są dość standardowe, a inne eksperymentalne:
- Odpowiednio udostępnij serwery, by radził sobie z obciążeniem ruchu klientów, w tym złośliwego.
- Zapobieganie atakom typu DoS i atakom wzmacniającym. Choć jest to głównie problem związany z bezpieczeństwem, ma wpływ na mniejszą liczbę resolverów niż otwarte, co zapobiega też atakom DoS, ponieważ zmniejsza obciążenie dodatkowe serwerów DNS. Informacje o stosowanych przez nas metodach minimalizowania szans na atak znajdziesz na stronie z korzyściami bezpieczeństwa.
- Zrównoważone obciążenie w przypadku współdzielonego pamięci podręcznej – ma to na celu ulepszenie zagregowanego współczynnika trafień w pamięci podręcznej w klastrze obsługującym.
- Zapewniania globalnej zasięgu w celu informowania wszystkich użytkowników o bliskiej odległości.
Odpowiednie udostępnianie klastrów
Urządzenia do buforowania DNS muszą wykonywać bardziej kosztowne operacje niż wiarygodne serwery nazw, ponieważ wielu odpowiedzi nie można udostępnić z pamięci. Zamiast tego wymagają one komunikacji z innymi serwerami nazw, a tym samym wymagają wielu danych wejściowych/wyjściowych sieci. Ponadto otwarte resolvery są bardzo narażone na próby zatrucia pamięci podręcznej, co zwiększa współczynnik braku pamięci podręcznej (takie ataki wysyłają żądania o fałszywych nazwach, których nie można rozwiązać z pamięci podręcznej) oraz ataki DoS, które zwiększają obciążenie ruchu. Jeśli resolvery nie są udostępniane i nie nadążają za obciążeniem, może to mieć bardzo negatywny wpływ na wydajność. Pakiety są odrzucane i muszą być ponownie przesłane, żądania dotyczące serwerów nazw itd. Wszystkie te czynniki zwiększają opóźnienia.
Dlatego ważne jest, aby resolvery DNS obsługiwały duże dane wejściowe/wyjściowe. Obejmuje to obsługę potencjalnych ataków DDoS, w przypadku których jedynym efektywnym rozwiązaniem jest nadmierna obsługa wielu komputerów. Jednocześnie ważne jest, aby nie obniżać współczynnika trafień w pamięci podręcznej podczas dodawania komputerów. Wymaga to zastosowania skutecznej zasady równoważenia obciążenia, którą opisujemy poniżej.
Równoważenie obciążenia dla współdzielonego pamięci podręcznej
Skalowanie infrastruktury resolvera przez dodanie maszyn może w rzeczywistości doprowadzić do pożaru i zmniejszyć współczynnik trafień w pamięci podręcznej, jeśli nieprawidłowe równoważenie obciążenia nie jest prawidłowe. W typowym wdrożeniu wiele systemów znajduje się za systemem równoważenia obciążenia, który równomiernie rozkłada ruch na każdą maszynę przy użyciu prostego algorytmu, takiego jak algorytm karuzelowy. W rezultacie każdy komputer zachowuje własną niezależną pamięć podręczną, dzięki czemu treści są zapisywane w pamięci podręcznej w izolacji między komputerami. Jeśli każde przychodzące zapytanie jest rozłożone na maszynie losowej, w zależności od charakteru ruchu, efektywny odsetek pamięci podręcznej może zostać zwiększony proporcjonalnie. Na przykład w przypadku nazw z długimi zapytaniami o wartości TTL, które są powtarzane wielokrotnie, wskaźnik braku pamięci podręcznej może zostać zwiększony przez liczbę maszyn w klastrze. W przypadku nazw z bardzo krótką wartością TTL, które są rzadko wysyłane lub powodują błędy w pamięci podręcznej (0 – TTL i błędy), dodanie maszyny do pamięci podręcznej nie ma wpływu na odsetek błędów pamięci podręcznej.
W celu zwiększenia liczby trafień dla nazw pamięci podręcznej ważne jest, aby serwery równoważenia obciążenia nie były fragmentowane w pamięci podręcznej. W Google Public DNS DNS stosujemy 2 poziomy buforowania. W jednej puli maszynowej, znajdującej się bardzo blisko użytkownika, niewielka pamięć podręczna na każdym komputerze zawiera najpopularniejsze nazwy. Jeśli zapytanie nie może zostać wykonane z tej pamięci podręcznej, jest wysyłane do innej puli komputerów, które partycjonują pamięć podręczną według nazw. W przypadku tej pamięci podręcznej drugiego poziomu wszystkie zapytania o tej samej nazwie są wysyłane do tego samego komputera, na którym nazwa jest zapisana w pamięci podręcznej lub zawiera błąd.
Dystrybucja klastrów obsługujących w dużym zakresie geograficznym
Nie dotyczy to zamkniętych resolverów. W przypadku resolverów otwartych im bliżej serwerów znajdują się użytkownicy, tym krótsze opóźnienie po stronie klienta. Wystarczająca zasięg geograficzny może pośrednio obniżyć cały czas oczekiwania, ponieważ serwery nazw zwykle zwracają wyniki zoptymalizowane pod kątem lokalizacji resolvera DNS. Oznacza to, że jeśli dostawca treści hostuje dublowane witryny na całym świecie, serwery nazw tego dostawcy będą zwracać adres IP znajdujący się w pobliżu odległości od resolvera DNS.
Publiczny serwer DNS Google jest hostowany w centrach danych na całym świecie i korzysta z routingu anycast, aby kierować użytkowników do najbliższego centrum danych.
Oprócz tego publiczny serwer DNS Google obsługuje podsieć klienta DNS (ECS), czyli rozszerzenie protokołu DNS do przekazywania lokalizacji klienta na serwery nazw, które może zwracać odpowiedzi wrażliwe na lokalizację dla rzeczywistego adresu IP, a nie adresu IP resolvera. Więcej informacji znajdziesz w najczęstszych pytaniach. Publiczny serwer DNS Google automatycznie wykrywa serwery nazw, które obsługują podsieć klienta EDNS.