Procesor serwera Klasy harmonogramu kontrolują, który proces otrzymuje czas obliczeniowy i kiedy, a także w jaki sposób priorytety wyzwalają przesunięcie, aby czasy odpowiedzi pozostały niskie, a przepustowość pozostała przewidywalna. Pokazuję, w jaki sposób klasy, Priorytety oraz jak mogę kontrolować rozkład obciążenia za pomocą zaledwie kilku ustawień.
Punkty centralne
- Klasy harmonogramu organizować obciążenia zgodnie z zasadami i wpływać na czas reakcji.
- Priorytety zdecydować, kto pierwszy otrzyma czas CPU, a kto poczeka.
- Wyłączenie wypiera uruchomione zadania, gdy ważniejsze zadania są w toku.
- Sprawiedliwość zapobiega trwałej dominacji poszczególnych procesów.
- Pomiar sprawia, że efekty są widoczne i prowadzi do lepszych ustawień.
Dlaczego klasy schedulerów wpływają na wydajność serwera
W środowiskach produktywnych serwery WWW, bazy danych i zadania konkurują ze sobą o to samo. Procesory, właśnie dlatego regulowana alokacja jest kluczowa. Polegam na jasnych klasach, aby interaktywne żądania nie pozostawały w tyle za zadaniami wsadowymi, a działania użytkowników otrzymywały szybkie odpowiedzi. Jasny podział usług na klasy skraca czas oczekiwania, obniża limity czasu i sprawia, że zachowanie jest przewidywalne, nawet podczas szczytowego obciążenia. Bez takiej kategoryzacji istnieje zwiększone ryzyko, że proces wymagający dużej mocy obliczeniowej może niezauważalnie przeciążyć system. Czasy reakcji wszystkich innych ulega pogorszeniu. Dlatego priorytetowo traktuję ścieżki o krytycznym znaczeniu dla biznesu, ponieważ tam liczy się każda milisekunda.
Podstawy: Priorytet, klasy, wycinki czasu
Każdy harmonogram łączy Priorytet, priorytetów, klas i wycinków czasu w celu alokacji czasu obliczeniowego i kontroli przemieszczania. Wyższy priorytet skraca czas oczekiwania, ale zbyt wysokie wartości blokują inne procesy, co powoduje uczucie zacinania się. Odcinki czasu ograniczają czas obliczeń wykonywanych przez dany proces przed przejściem do kolejnego zadania, co promuje sprawiedliwość. Klasy definiują również, czy zadanie jest przetwarzane preferencyjnie, równomiernie lub zgodnie z regułami dotyczącymi terminów. Oceniam te dźwignie razem, ponieważ tylko ich kombinacja może zoptymalizować ogólną wydajność. Planowanie realistycznie odzwierciedlone.
CFS w szczegółach: vruntime, ziarnistość i okno opóźnienia
Z systemem LinuxCFS Nie liczy się czas rzeczywisty, ale wirtualny czas działania (vruntime) zadania. Im więcej CPU otrzymało zadanie, tym bardziej wzrasta jego vruntime i tym później jest ono ponownie zaplanowane. Ten mechanizm tworzy Sprawiedliwość, ale może generować bardzo różne opóźnienia w zależności od liczby aktywnych wątków. The Okno opóźnienia (sched_latency) określa okres czasu, w którym CFS przydziela „sprawiedliwy“ czas wszystkim wykonywalnym zadaniom. Dla wielu zadań, CFS skraca Minimalna ziarnistość na zadanie, dzięki czemu każdy ma swoją kolej, co skutkuje zwiększoną liczbą zmian kontekstu. Przy mniejszej liczbie zadań, kwanty, a tym samym przepustowość ciężkich zadań wzrasta.
Dokonuję tylko ostrożnych korekt: nieco wyższy min_granularity łagodzi burze przełączania kontekstu z tysiącami aktywnych wątków roboczych. Nieco większy wakeup_granularity uniemożliwia świeżo wybudzonym, krótkotrwałym zadaniom wyprzedzanie wątków, które działają zbyt często. Testuję zmiany osobno dla profili dziennego i szczytowego obciążenia, ponieważ to samo ustawienie nagle wykazuje zupełnie inne efekty przy nocnym obciążeniu.
Krótkie wyjaśnienie klas Linux Scheduler
W systemie Linux klasy oddzielają typowe zadania serwera według Zasady i oczekiwania, aby zadania interaktywne nie zostały przyćmione przez długie zadania obliczeniowe. CFS obsługuje ogólne procesy, podczas gdy klasy czasu rzeczywistego zajmują się twardymi celami reakcji, a DEADLINE zapewnia bardziej precyzyjne specyfikacje czasowe. Wyspecjalizowane klasy, takie jak Idle lub Batch, obejmują pracę w tle bez zakłócania usług na pierwszym planie. Dla każdej usługi sprawdzam, która klasa odpowiada jej wzorcowi komunikacji, zamiast po prostu dostosowywać ładne wartości. Jeśli chcesz zagłębić się w temat, znajdziesz praktyczne informacje na temat CFS i alternatywy, które sprawdziły się w codziennym hostingu.
| Klasa | Typowe zastosowanie | Cecha | Ryzyko błędnej konfiguracji |
|---|---|---|---|
| CFS (SCHED_OTHER) | Ogólne Usługi | Udział godziwy według terminu zapadalności | Narciarze biegowi subtelnie wypierają lżejsze prace |
| Czas rzeczywisty (SCHED_FIFO/RR) | Krytyczne opóźnienia Zadania | Preferowany projekt | Głód możliwy dla procesów CFS |
| TERMIN | Ścisłe limity czasowe | Zarezerwowany procesor według budżetu/okresu | Brak budżetu prowadzi do porzucania nauki |
| Batch/Idle | Kopie zapasowe, analizy | Biegaj, gdy jest na to czas | Wydłużony czas pracy pod dużym obciążeniem |
Systemd, cgroups i narzędzia do wdrażania
Priorytety ustalam nie tylko doraźnie, ale również w ramach Jednostki oraz cgroups aby reguły pozostały stabilne: CPUSchedulingPolicy i CPUSchedulingPriority kontrolują klasę i priorytet usługi, CPUWeight/CpuQuota sprawiedliwie przydzielają rdzenie. W cgroup v2 używam cpu.max oraz cpu.weight, do łączenia twardych ramek (quota/burst) i miękkiego ważenia. Dzięki temu ścieżka odpowiedzi jest zwinna, podczas gdy wypełnienia lub raporty niezawodnie odbierają wydajność bez przerywania.
W przypadku korekt selektywnych miły/renomowany (ważenie CFS), chrt (atrybuty czasu rzeczywistego/DEADLINE), zestaw zadań (powinowactwo CPU) i ionice (priorytet we/wy). Włączam to do skryptów startowych zamiast ręcznie dostosowywać. Ważne: ustawiam tylko wąsko zdefiniowane podfunkcje na czas rzeczywisty - np. płukanie dziennika - i pozostawiam resztę w CFS, aby nie wpływać na cały system. stabilny pozostaje.
Rozsądne ustalanie priorytetów: Praktyczny przewodnik
Zaczynam od umiarkowanego Priorytety i stopniowo zwiększam wartości w miarę monitorowania opóźnień, kradzieży procesora i przełączania kontekstu. Pracownicy front-endowi mają nieco wyższy priorytet, aby żądania nie czekały na raporty, ale zostawiam miejsce na wątki bazy danych. Przenoszę zadania wsadowe poza godziny szczytu lub przypisuję je do klas wsadowych/idle, aby godziny szczytu pozostały wolne. W przypadku trudnych celów reakcji sprawdzam, czy niewielka, jasno określona część w klasach czasu rzeczywistego ma sens bez wywierania presji na cały system. W tym przewodniku przedstawiam ustrukturyzowaną procedurę, aby Optymalizacja priorytetów, który opisuje krok po kroku zmiany i punkty pomiarowe.
Wpływ na opóźnienia i przepustowość
Wysokie priorytety zmniejszają Opóźnienie interaktywnych żądań, ale ograniczają czas obliczeń dla zadań w tle. Zrównoważone odcinki czasu zapobiegają zbyt długiemu zajmowaniu procesora przez pojedynczego pracownika i powiększaniu się kolejek. W zależności od obciążenia, krótkie kwanty zwiększają szybkość reakcji, podczas gdy długie kwanty sprzyjają przepustowości strumieniowania lub kompresji. Dlatego też mierzę zarówno 95. i 99. percentyl czasu odpowiedzi, jak i żądania przetwarzane na sekundę. Używam tych wskaźników, aby rozpoznać, kiedy muszę zmienić priorytety lub przydzielić fragmenty czasu. Kalibracja.
NUMA, powinowactwo i kontrola przerwań
W systemach wielogniazdowych podejmuję świadomą decyzję o NUMA-przynależność i Przynależność procesora. Wiążę usługi o krytycznym opóźnieniu z rdzeniami w węźle NUMA i upewniam się, że ich pamięć jest przydzielana lokalnie. W ten sposób unikam zdalnego dostępu z dodatkowymi opóźnieniami. W przypadku hostów z dużą bazą danych oddzielam wątki OLTP i konserwację w tle (np. wskaźniki kontrolne) do różnych grup rdzeni, aby transakcje o krótkim opóźnieniu nie konkurowały o rdzenie z zadaniami długoterminowymi.
Również Przerwania W tym celu pozwalam irqbalance działać, ale w razie potrzeby wyłączam rdzenie hot-path. Przypisuję przerwania sieciowe (RX/TX) do kilku rdzeni, aby stos sieciowy nie stał się wąskim gardłem. W przypadku usług bardzo wrażliwych na opóźnienia, zlecam głośne źródła przerwań oddzielnym rdzeniom. Ta separacja przestrzenna uzupełnia priorytety i klasy - nie zastępuje ich.
Monitorowanie i metryki: podejmowanie decyzji na podstawie danych
Cenię Metryki takie jak obciążenie procesora, długość kolejki uruchamiania, przełączanie kontekstu i kradzież procesora w celu wyraźnego przydzielenia wąskich gardeł. Rosnące kolejki uruchomień przy spadającej przepustowości wskazują na nieprawidłowe priorytety lub zbyt wąskie przedziały czasowe. Niezwykle wysoka liczba przełączeń kontekstu ujawnia, że wątki wykonują obliczenia zbyt krótko, a samo zarządzanie pochłania czas. W przypadku obciążeń mieszanych sprawdzam miary sprawiedliwości, aby żadna klasa usług nie straciła na stałe. Dobre wprowadzenie do wytycznych i kompromisów można znaleźć w tym artykule na stronie Zasady planowania, których używam jako podstawy do podejmowania decyzji.
Śledzenie, profilowanie i powtarzalne testy
Zanim naprawię tuning, chcę zobaczyć przyczynę i skutek. Używam Profilowanie oraz Śledzenie, do wizualizacji gorących ścieżek, czasów oczekiwania na blokadę i częstotliwości wywoływania wstępnego. Krótkie, powtarzalne testy obciążeniowe z fazą rozgrzewki zapobiegają błędnym interpretacjom z powodu zimnych pamięci podręcznych lub rozgrzewki JIT. Zbieram percentyle w ciągu kilku minut i kilku przebiegów, zamiast porównywać tylko wartości szczytowe. Ważna jest czysta separacja: najpierw linia bazowa, potem zmiana, a następnie identyczny test. Dokumentuję pomiary pośrednie z parametrami hosta i jądra, dzięki czemu mogę odtworzyć dokładnie to samo środowisko kilka tygodni później.
Typowe pułapki i przeciwwskazania
Podnoszę Priorytety Nigdy dla całych usług, ponieważ to tylko przesuwa hierarchię i tworzy nowe wąskie gardła. Stale wysokie wartości czasu rzeczywistego mogą łatwo doprowadzić do przeciągnięcia normalnych procesów i stworzyć nieprzewidywalne efekty uboczne. Zbyt małe wycinki czasu powodują zmiany kontekstu, a wydajność spada, mimo że procesor oczywiście działa. Mieszanka zadań obciążających CPU i I/O bez wyraźnego wyboru klas marnuje wydajność w naprzemiennej kąpieli. Systematyczne podejście oszczędza czas, zapobiega regresji i utrzymuje wydajność. Stabilność wysoki.
SMT, stany energetyczne i efekty turbo
SMT/Gwintowanie nadprądowe duplikuje rdzenie logiczne, ale współdzieli fizyczne jednostki wykonawcze. Dlatego wolę planować wątki krytyczne pod względem opóźnień na różnych rdzeniach fizycznych, zanim przydzielę ich siostrzane rdzenie SMT. W przeciwnym razie współdzielona logika obliczeniowa może wydłużyć czas oczekiwania. Obserwuję również Turbo- oraz Stany CGłębokie stany uśpienia oszczędzają energię, ale kosztują czas wybudzania. Na ścieżkach opóźnień redukuję głębokie stany C lub utrzymuję „ciepłe“ rdzenie, jeśli pozwala na to polityka energetyczna. I odwrotnie, celowo pozwalam klasom wsadowym spać głębiej - korzystają one z wydajności bez spowalniania użytkowników.
Przykłady dostrajania według typu obciążenia
Dla serwerów internetowych zapewniam światło pierwszeństwo-Ustawienia obsługi żądań i uruchamianie procesów buforowania tuż pod nimi. Bazy danych korzystają ze zrównoważonych wycinków czasu, wystarczającej liczby aktywnych wątków roboczych i ograniczonego wykorzystania w czasie rzeczywistym tylko do spłukiwania dzienników lub wskaźników kontrolnych. Zadania wsadowe przenoszę do klas idle/batch, aby wykorzystywały wolne cykle bez spowalniania ścieżek frontendu. Oddzielam analitykę i ETL od usług interaktywnych, często używając oddzielnej klasy lub kontenera z limitami CPU. Pozwala mi to kontrolować opóźnienia bez dodatkowych kosztów. Sprzęt zapewnić.
Zjazdy, poręcze i trasy powrotne
Przeprowadzam tuning schedulera jak release: z Kanarek-hosty, jasne kryteria anulowania i szybkie wycofywanie. Definiuję wartości progowe dla opóźnienia P99, wskaźnika błędów i kradzieży procesora. Jeśli wartość wzrośnie powyżej progu, automatycznie przywracam ostatnią stabilną konfigurację. Ograniczam zmiany na iterację: tylko priorytety lub tylko wycinki czasu - nigdy oba jednocześnie. Przechowuję wersje wszystkich ustawień i dokumentuję założenia oraz wyniki pomiarów. W ten sposób ścieżka do dobrej konfiguracji pozostaje identyfikowalna, nawet jeśli zmienią się ludzie lub platformy.
Wirtualizacja i hosty współdzielone
Na współdzielonych hostach, które kontroluję CPU-quotas, pinning i NUMA affinity, zanim dostosuję priorytety. Maszyny wirtualne współdzielą fizyczne rdzenie, więc kradzież CPU znacząco zmienia zmierzone czasy oczekiwania. Planuję rezerwacje dla krytycznych usług, aby ich wątki otrzymywały przewidywalny czas obliczeń. Wiążę kontenery z limitami, aby zapobiec eskalacji przez poszczególnych klientów. Dopiero gdy ta podstawa jest na miejscu, dostosowuję przypisanie klas i Priorytet na proces.
Podsumowanie dla codziennego życia
Najpierw przypisuję usługi do znaczących klasy ustawić umiarkowane priorytety i monitorować opóźnienia, przepustowość i kolejki uruchamiania. Małe kroki przynoszą wyraźne efekty, duże skoki zaciemniają przyczyny i utrudniają wycofanie. Tam, gdzie liczy się czas reakcji, zezwalam na ograniczoną priorytetyzację; tam, gdzie liczy się przepustowość, wydłużam kwanty i utrzymuję priorytety na płaskim poziomie. Metryki kierują każdą decyzją, a nie instynkt, ponieważ harmonogramy łatwo pokazują nieintuicyjne wyniki. Dzięki tej dyscyplinie wykorzystuję Serwer-Wydajność procesora, szybkość reakcji i sprawiedliwość między wszystkimi usługami.


