Brendan Gregg, jeden z twórców DTrace, obecnie rozwija narzędzia do analizy wydajności oparte na BPF w jądrze Linux, podsumował doświadczenia zdobyte podczas rozwiązywania problemów z wydajnością, z jakimi zmagała się firma Netflix przy migracji bazy danych Cassandra z CentOS na Ubuntu w środowiskach uruchamianych w chmurze Amazon EC2 opartych na Xen. Po migracji obciążenie CPU wzrosło o 30%, a opóźnienia w wykonywaniu operacji zapisu również wzrosły o mniej więcej tyle samo. Jak się okazało, wydajność aplikacji intensywnie zapytujących o czas, bardzo zależy od wybranego w systemie źródła dokładnego czasu.
Na początku przyczyna spadku wydajności nie była oczywista, a diagnostyka rozpoczęła się od monitorowania wpływu stale działających lub okresowo uruchamianych zasobożernych procesów systemowych za pomocą narzędzi top i execsnoop. Jednak wszystko wskazywało na to, że zużycie zasobów wzrosło właśnie w bazie danych Cassandra napisanej w języku Java. Porównanie wyników profilowania dwóch procesów Cassandra, uruchomionych równolegle w CentOS i Ubuntu, przetwarzających te same zapytania, pokazało, że około 32% całego czasu zużywane jest na wywołanie os::javaTimeMillis(), używanego do uzyskania informacji o aktualnym czasie.
Następnie przeprowadzono eksperyment, w którym napisano prostą aplikację w języku Java, w pętli wywołującą sto milionów razy metodę System.currentTimeMillis(). Uruchomienie aplikacji wykazało, że w CentOS do jej wykonania potrzebne było 13 sekund, podczas gdy w Ubuntu — około 68 sekund, co oznacza, że była pięć razy wolniejsza. W języku C napisana została podobna aplikacja, wywołująca sto milionów razy funkcję gettimeofday(), jednak podczas jej wykonywania uzyskano podobne wyniki.
Ponieważ stało się jasne, że źródłem problemu jest funkcja zwracania bieżącego czasu, uwaga skupiła się na zmianie wskaźników podczas wyboru różnych źródeł dokładnego czasu w systemie. Z treści „/sys/devices/system/clocksource/clocksource0/current_clocksource” wynika, że domyślnie przy uruchamianiu systemu Linux w systemie gościa używany był zegar „xen”. Po zmianie źródła czasu na „tsc”, czas wykonania aplikacji testowej w Ubuntu skrócił się z 68 do 3,3 sekundy, co oznacza, że był 20 razy szybszy. Dodatkowo przeprowadzono test wydajności źródła czasu kvm-clock, który wykazał wzrost opóźnień o 20% w porównaniu z TSC. $ cat /sys/devices/system/clocksource/clocksource0/available_clocksource xen tsc hpet acpi_pm $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource xen $ time java TimeBench real 1m8.300s user 0m38.337s sys 0m29.875s $ echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource $ time java TimeBench real 0m3.370s user 0m3.353s sys 0m0.026s
Do uzyskania czasu z wyborem źródła TSC używana jest instrukcja procesora RDTSC, której wykonanie nie wymaga wywołania systemowego (instrukcja nie wymaga podwyższonych uprawnień i zwraca wartość z wbudowanego w CPU licznika czasu). Domyślnie TSC nie jest aktywowane, ponieważ w przeszłości to źródło nie wykluczało stopniowego dryfu czasu, który w innych regulatorach jest korygowany programowo w celu osiągnięcia dokładniejszych wskazań. Według inżyniera specjalizującego się w projektowaniu procesorów, obawy o przesunięcia czasu przy użyciu TSC dawno przestały być zasadne, a nowoczesnych procesorach to źródło może przez lata dostarczać stabilnych odczytów.
Przejście do źródła TSC serwerów w Netflix spowodowało zmniejszenie opóźnień podczas zapisu o 43% i osiągnięcie wyników w Ubuntu, które czterokrotnie przewyższały konfiguracje z CentOS z źródłem czasu „xen”. Wyniki przeprowadzonego badania zostały przekazane firmie Amazon, która oficjalnie zaleciła w środowiskach AWS EC2 opartych na hypervisorze Xen, aby domyślnie używać źródła czasu TSC (w środowiskach opartych na hypervisorze Nitro nadal rekomendowany jest kvm-clock).
Źródło: opennet.ru
