...

Instancje puli buforów MariaDB zapewniające maksymalną wydajność w systemach wielordzeniowych

Pokazuję, jak pracuję z Instancje bufora skalowanie pamięci podręcznej InnoDB w systemach wielordzeniowych i znaczne zmniejszenie konfliktów blokad. Główny nacisk kładziony jest na Bufor MariaDB oraz parametrem innodb_buffer_pool_instances, aby wątki miały sprawny dostęp do danych, opóźnienia były bardziej wyrównane, a przepustowość wzrosła.

Punkty centralne

  • Konflikt muteksów zminimalizować i oddzielić równoległe operacje dostępu
  • Lokalizacja pamięci podręcznej zwiększyć wydajność i lepiej wykorzystać pamięć podręczną procesora
  • Wersja sprawdzić, ponieważ parametr ten jest częściowo nieskuteczny
  • Proporcje należy uwzględnić dla każdej instancji (≥ 1 GB)
  • Monitoring wykorzystywać i stopniowo dostosowywać

Krótkie wyjaśnienie dotyczące puli buforów InnoDB

Postrzegam pulę buforów InnoDB jako węzeł komunikacyjny dla stron danych i indeksów w pamięci RAM, ponieważ określa on, jak często MariaDB może uniknąć powolnych operacji wejścia/wyjścia. Im więcej aktywnych danych zmieści się w pamięci, tym rzadziej silnik musi odczytywać dane z dysku, co skraca czas odpowiedzi i zwiększa przepustowość. Na serwerach, na których działa prawie wyłącznie MariaDB, zazwyczaj rezerwuję 60–80 % pamięci RAM, a na hostach mieszanych raczej 40–60 %, aby pozostało wystarczająco dużo pamięci dla systemu. Ważne jest, aby „gorące dane“ znalazły swoje miejsce, dzięki czemu zapytania będą ponownie odczytywane z pamięci podręcznej. W tym celu obserwuję współczynnik trafień, dostosowuję rozmiar i utrzymuję Szczyty obciążenia w skrócie.

Dlaczego na systemach wielordzeniowych stosuje się wiele instancji puli buforów?

Zmniejsz liczbę instancji Czas oczekiwania na blokadę, ponieważ wątki nie korzystają z tych samych struktur wewnętrznych. W przypadku jednej, dużej puli wzrasta rywalizacja o mutexy, co spowalnia działanie przy wysokim stopniu równoległości. Dzielę pulę, aby obciążenia rozkładały się na różne instancje, co zmniejsza prawdopodobieństwo wystąpienia punktów krytycznych. Dodatkowo poprawiam w ten sposób lokalność pamięci podręcznej, ponieważ powtarzające się operacje dostępu częściej trafiają do tej samej instancji, a pamięci podręczne procesora są wykorzystywane efektywniej. Efektem są bardziej równomierne opóźnienia i niezawodnie wyższa Przepustowość przy wysokim stopniu równoległości.

Rzeczywistość wersji: Kiedy działa parametr innodb_buffer_pool_instances

Zanim ustalę liczbę instancji, sprawdzam Wersja w mojej instancji MariaDB, ponieważ od pewnych wersji (np. 10.5.1) parametr ten czasami przestaje działać. Nowsze wersje mają ulepszony wewnętrzny mechanizm blokowania puli buforów, dzięki czemu wystarcza mniej instancji lub nie ma to w ogóle żadnego wpływu. W starszych wersjach podział ten często przynosi jednak wyraźne korzyści, zwłaszcza w przypadku dużych pul i wysokiego stopnia równoległości. Dlatego dopiero po sprawdzeniu wersji planuję, czy zoptymalizować instancje, czy też zamiast tego nadać priorytet innym parametrom. Należą do nich rozmiar puli buforów, parametry dziennika ponownego wykonania (redo log) oraz ustawienia systemowe Sterowanie wątkami.

Określenie rozmiaru puli buforów

Najpierw ustalam rozmiar puli, aby instancje miały później odpowiednią wielkość i nie były zbyt małe. Na dedykowanych serwerach baz danych planuję przeznaczyć 60–80 % pamięci RAM, a na serwerach współdzielonych raczej 40–60 %, aby system operacyjny i usługi miały wystarczającą rezerwę. Cel: utrzymywanie w puli w miarę możliwości 80–90 % aktywnych danych, aby wskaźnik trafień pozostawał na poziomie bliskim 99 %. Osoby, które chcą zagłębić się w ten temat, znajdą w zwięzłym Wymiarowanie puli buforów praktyczne wskazówki. Postrzegam wielkość jako coś zmiennego Budżet i dostosowuj je w miarę wzrostu obciążenia lub pojawiania się nowych aplikacji.

Wybór liczby instancji: praktyczne wskazówki z zachowaniem rozsądku

W przypadku większych pul chętnie zaczynam od zasady „jedna instancja na GB“, ale zazwyczaj ograniczam liczbę instancji do 8–16, aby zarządzanie nimi nie stało się zbyt uciążliwe. Przy pulach o wielkości około 1 GB rezygnuję z instancji, ponieważ korzyści z ich stosowania są niewielkie. Ponadto dbam o to, aby każda instancja miała co najmniej 1 GB, w przeciwnym razie fragmentacja będzie zbyt duża w stosunku do korzyści. Kieruję się również liczbą rdzeni procesora i przewidywanym stopniem równoległości, aby instancje były sensownie przydzielone. Na przykład na serwerze z 8 rdzeniami i pulą 16 GB uruchamiam 8 instancji po około 2 GB, co Zasoby dobrze rozłożone i zmniejszone obciążenie.

W jaki sposób InnoDB rozdziela strony między instancje

Jeśli chodzi o instancje, nie myślę o „oddzielnych pamięciach podręcznych dla każdej tabeli“, ale o wewnętrznej, rozkład deterministyczny poszczególnych stron (stron danych i indeksowych) do kilku podpul. Przypisanie opiera się na wewnętrznych identyfikatorach i skrótach; dzięki temu te same obszary są spójnie przypisywane do tej samej instancji. Jest to korzystne dla lokalności, ma jednak istotną konsekwencję: jeden jedyny Punkt newralgiczny (np. „ostatnia“ strona liścia w przypadku monotonnie rosnących kluczy głównych) pozostaje nadal punktem newralgicznym w ramach jednej instancji. Zwiększenie liczby instancji nie eliminuje takich „punktów newralgicznych” w projekcie, ale oddziela od siebie różne zestawy newralgiczne i zmniejsza globalne rywalizowanie o muteksy. Dlatego dodatkowo sprawdzam konstrukcję kluczy i profil zapytań, aby Najpopularniejsze strony nie dopuścić do tego, by w ogóle do tego doszło.

Właściwe wykorzystanie architektury NUMA i lokalności pamięci podręcznej

W systemach z architekturą NUMA sprawdzam rozmieszczenie pamięci, aby wątki wykonywały obliczenia jak najbliżej swoich danych. Dobra strategia ogranicza dostęp zdalny, co zmniejsza opóźnienia i tłumi wariancję. Dostosowuję liczbę instancji, przypisanie procesorów (CPU-Pinning) oraz politykę pamięci, aby wzmocnić lokalność pamięci podręcznej. Jeśli chcesz poznać więcej szczegółów na ten temat, zapoznaj się z krótkimi Zasady NUMA dla serwerów baz danych. W ten sposób zapewniam krótkie ścieżki transmisji danych i gwarantuję spójność Wydajność nawet pod presją.

Strategia Flush, narzędzie Page Cleaner i przepustowość wejścia/wyjścia

Dobrze rozplanowana pula buforów pokazuje swoje zalety dopiero wtedy, gdy Oczyszczanie w tle działa bez zarzutu. Obserwuję długość list flush i LRU oraz dostosowuję wydajność operacji wejścia/wyjścia, tak aby moduł Page Cleaner obsługiwał szczyty obciążenia bez powodowania gwałtownych skoków. Typowymi parametrami regulacyjnymi są innodb_io_capacity i innodb_io_capacity_max, które dostosowuję do podstawowego podsystemu pamięci masowej (dla dysków SSD wartości te są znacznie wyższe niż dla dysków HDD). Na nośnikach flash chętnie wyłączam czyszczenie sąsiedztwa („neighbors“), aby nie czyszczać niepotrzebnie stron, które i tak wkrótce zostaną zastąpione. Równomierne punkty kontrolne i krótkie kolejki fluszowania utrzymują opóźnienia na stałym poziomie – ma to bezpośredni wpływ na wydajność wielu instancji, ponieważ mniej wątków czeka na operacje zapisu w tle.

Polityka LRU, odczyt z wyprzedzeniem i ruch „zimny“

Obserwuję, jak obciążenia przesuwają strony przez LRU. W przypadku skanowania o silnym charakterze sekwencyjnym, ustawiając odpowiedni czas „Old-Blocks“, zapobiegam wypieraniu obszaru świeżych danych przez dostępy do danych zimnych. Funkcja Read-Ahead pomaga w przypadku prawdziwych sekwencji, ale w przypadku wzorców losowych obciąża pulę. W tym przypadku obowiązuje zasada: najpierw zmierzyć, a potem precyzyjnie dostosować. Celem tego ćwiczenia jest młody dział LRU zarezerwować dla danych gorących, aby zapytania były wielokrotnie tej samej Instancja i czy pamięci podręczne procesora są opłacalne. Zwłaszcza w przypadku wielu instancji nieprawidłowe odczytywanie z wyprzedzeniem jest bardziej zauważalne, ponieważ rozkłada „szum“ w zaskakująco równomierny sposób na poszczególne pule.

Adaptacyjny indeks hashowy i bufor zmian

Sprawdzam, czy Adaptacyjny indeks hashowy (AHI) czy pomaga, czy przeszkadza mojemu wzorcowi. Przy bardzo wysokim stopniu równoległości sam AHI może stać się punktem kolizji. W takim przypadku warto spróbować go tymczasowo ograniczyć lub wyłączyć i obserwować wpływ tej zmiany na opóźnienia. W przypadku obciążeń wymagających intensywnego zapisu, z dużą liczbą wstawień do indeksów pomocniczych, Zmień bufor Wpływ na operacje wejścia/wyjścia i rotację stron. Większa pula buforów zmniejsza obciążenie, ponieważ więcej stron indeksu pozostaje „gorących”, a operacje wstawiania nie trafiają tak często do struktur „zimnych”. Łączę te obserwacje z liczbą instancji: jeśli poprzez zwiększenie liczby instancji oddzielę blokady globalne, łatwiej będzie stwierdzić, czy rzeczywistym wąskim gardłem jest AHI, czy bufor zmian.

Uruchamianie na gorąco: ładowanie zrzutów puli buforów

Po ponownym uruchomieniu nie chcę widzieć „zimnych“ opóźnień trwających kilka minut. Dlatego włączam Wysypywanie i załadunek „gorących” stron podczas wyłączania/uruchamiania. Dzięki temu usługa uruchamia się z już zapełnioną pulą, wskaźnik trafień szybciej wraca do poziomu bliskiego 99 %, a ja dostrzegam wpływ wyboru instancji na wydajność bez zniekształcania obrazu przez „zimną” pamięć podręczną. Przyspiesza to zwłaszcza wdrażanie zmian i aktualizacje jądra i jest to mój standard w środowiskach produkcyjnych, w których stabilność stawiam ponad same wartości szczytowe.

Konfiguracja w pliku my.cnf i ponowne uruchomienie

Wprowadzam ustawienia do pliku my.cnf w uporządkowany sposób i dokładnie dokumentuję każdą zmianę. Ważne: najpierw należy zdefiniować docelową wielkość puli, następnie ustawić liczbę instancji, a na koniec przeprowadzić restart. Po ponownym uruchomieniu sprawdzam w poleceniu SHOW VARIABLES, czy wartości zostały zastosowane, oraz weryfikuję rozkład w poleceniu SHOW ENGINE INNODB STATUS. W ten sposób upewniam się, że maszyna rzeczywiście działa z wybranym podziałem. W przypadku dostosowań postępuję małymi krokami, aby móc jednoznacznie przypisać efekty i Stabilność nie stanowi zagrożenia dla funkcjonowania zakładu.

Przykład #
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8
innodb_log_file_size = 2G
innodb_flush_log_at_trx_commit = 1

Monitorowanie: wskaźniki, które naprawdę mają znaczenie

Najpierw mierzę współczynnik trafień puli, a następnie opóźnienia, obciążenie wejścia/wyjścia oraz czasy oczekiwania na blokady. Na co dzień wystarczy kilka, ale miarodajnych wskaźników, które regularnie sprawdzam i zapisuję w szeregach czasowych. Jeśli współczynnik trafień spadnie poniżej 99 %, rozważam zwiększenie rozmiaru puli, zanim zwiększę liczbę instancji. Jeśli czasy oczekiwania na mutexy rosną przy zasadniczo dobrym współczynniku trafień, testuję większą liczbę instancji, ale tylko stopniowo. W ten sposób zachowuję elastyczność działania, wcześnie rozpoznaję trendy i skupiam się na rzeczywistych Wąskie gardła.

Kluczowa liczba Wartość docelowa Zapytanie Wskazówka
Wskaźnik trafień w puli buforów ≥ 99 % SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_%'; Jeśli wartości są niskie, należy zwiększyć pulę lub Obciążenie pracą Optymalizacja
Odczyty/zapisy na sekundę stały SHOW GLOBAL STATUS LIKE 'Innodb_data_reads'; Skoki wskazują na wąskie gardła we/wy oraz nieprawidłowe Rozmiary tam
Czas oczekiwania na mutexy/blokady niski SHOW ENGINE INNODB STATUS; W razie wystąpienia opóźnień należy w razie potrzeby zwiększyć liczbę instancji
Zachowanie w punktach kontrolnych równomiernie SHOW GLOBAL STATUS LIKE 'Innodb_checkpoint_%'; Dostosowanie rozmiaru dziennika powtórzeń i strategii opróżniania

Łączę punkty pomiarowe z wdrożeniami, zmianami schematu i szczytami, aby móc ustalić związek przyczynowo-skutkowy. Dzięki przejrzystym notatkom oszczędzam czas i zmniejszam ryzyko powtórzenia tych samych błędów. W ten sposób stopniowo buduję solidną Podstawa praktyczna dla mojej firmy.

Dopracowywanie: stopniowe dostosowywanie zamiast radykalnych zmian

Nigdy nie zmieniam kilku parametrów jednocześnie, lecz oceniam je po kolei i w niewielkich krokach. Najpierw rozmiar puli, potem instancje, następnie strategie redo-log i flush, a na koniec parametry wątków. Po każdej zmianie czekam wystarczająco długo, aż efekt będzie widoczny, i rejestruję wskaźniki. Zwłaszcza w przypadku obciążeń o zmiennym natężeniu ruchu warto obserwować sytuację przez kilka dni. W ten sposób unikam działania na ślepo i utrzymuję Krzywa wydajności można to jednoznacznie zinterpretować.

Metodyka testów porównawczych: testy pod obciążeniem

Wyraźnie oddzielam laboratorium od produkcji. W laboratorium podgrzewam pulę, testuję różne poziomy obciążenia (np. 4/8/16/32 wątki) i zmieniam proporcje operacji odczytu i zapisu. Mierzę opóźnienia P95/P99, przepustowość oraz czasy oczekiwania na mutexy. Decydujące znaczenie ma Powtarzalność: ta sama ilość danych, ten sam rozkład danych, ten sam horyzont testowy. Dopiero gdy dana konfiguracja w dwóch lub trzech niezależnych przebiegach testów konsekwentnie osiąga lepsze wyniki, wprowadzam ją do środowiska produkcyjnego. Tam ją wdrażam canary- i porównaj szeregi czasowe sprzed i po zmianie. Takie podejście zapobiega sytuacji, w której przypadkowe wahania są mylnie interpretowane jako „optymalizacja“.

Typowe pułapki i przeciwwskazania

  • Zbyt wiele instancji: Koszty administracyjne rosną, listy LRU i flushy stają się zbyt rozdrobnione, a wątki działające w tle pracują nieefektywnie. Pozostaję ostrożny (2–8) i zwiększam wartości tylko w razie potrzeby.
  • Zbyt małe instancje: Poniżej 1 GB na instancję proporcje szybko się zmieniają. Lepiej wybrać mniej instancji, ale większych.
  • Zawieszenie pamięci podręcznej w analizach: Stwierdzenia dotyczące wpływu instancji są bez znaczenia, gdy pula jest „zimna”. Należy korzystać z uruchomień na ciepło lub długich okien testowych.
  • Błędy w projekcie strony głównej: Monotonne klucze bez rozkładu, szerokie indeksy pomocnicze lub brak indeksów pokrywających powodują powstawanie „gorących punktów”, których nie da się wyeliminować żadną liczbą instancji.
  • Niewłaściwe ustawienia wejścia/wyjścia: Dyski SSD o parametrach fluszu typowych dla dysków HDD marnują swój potencjał i generują skoki obciążenia, które są błędnie przypisywane instancjom.

Praktyczne aspekty hostingu i serwerów VPS: pamięć RAM, rdzenie, obciążenie

W środowiskach współdzielonych ustawiam pulę bardziej konserwatywnie, aby serwery WWW, pamięci podręczne i system operacyjny miały wystarczającą rezerwę. Na serwerach VPS lub dedykowanych przydzielam puli więcej pamięci RAM, aby wskaźnik trafień pozostał wysoki. Rozmieszczam instancje tak, aby sensownie pasowały do vCPU i miały co najmniej 1 GB na każdą instancję. Kto potrzebuje wydajnych rozwiązań hostingowych lub serwerowych, powinien postawić na oferty webhoster.de, ponieważ rdzenie procesorów, pamięć RAM i wydajność wejścia/wyjścia są tu zaprojektowane z myślą o intensywnej równoległości. Dzięki tej podstawie ograniczam opóźnienia i wykorzystuję w pełni Wiele rdzeni lepiej.

Pula wątków i równoległe operacje

Nawet dobrze rozdzielony bufor nie przyda mi się zbytnio, jeśli zbyt wiele połączeń konkuruje ze sobą jednocześnie. Dlatego reguluję limity połączeń i wątków oraz sprawdzam, czy Pula wątków przynosi korzyści w moim systemie. Celem jest stałe wykorzystanie mocy obliczeniowej aktywnych procesów roboczych bez powodowania zatorów. Dbam o to, by krótkie, częste zapytania nie utknęły za ciężkimi transakcjami. Dzięki sprawnemu sterowaniu zwiększam wydajność na rdzeń i zapewniam sobie niezawodną Czasy reakcji.

Krótkie podsumowanie: ustawienia, które się u mnie sprawdzają

Najpierw sprawdzam Wersja i decyduję, czy zastosować parametr `innodb_buffer_pool_instances`, czy też skupić się na rozmiarze puli, dziennikach ponownego wykonania i wątkach. Następnie dostosowuję rozmiar puli tak, aby pomieściła aktywne dane, i ustawiam liczbę instancji na poziomie zapewniającym, że każda z nich otrzyma co najmniej 1 GB. W systemach wielordzeniowych dążę do liczby instancji w zakresie 2–8 i zwiększam ją tylko w przypadku wykrytego rywalizacji o muteksy. Monitorowanie prowadzę w sposób uproszczony, ale konsekwentny, a parametry zmieniam małymi krokami, kierując się jasnymi punktami pomiarowymi. W ten sposób osiągam stałe opóźnienia, lepsze wykorzystanie zasobów i zauważalnie większą wydajność Przepustowość dla moich obciążeń MariaDB.

Artykuły bieżące