Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Transkrypcja referatu z 2015 roku Iłji Kosmodiemiańskiego "Tuning Linuxa w celu poprawy wydajności PostgreSQL"

Zastrzeżenie: Zauważam, że ten referat datowany jest na listopad 2015 roku – minęło ponad 4 lata, a czas płynął. Wersja omówiona w referacie 9.4 już nie jest wspierana. Przez poprzednie 4 lata wydano 5 nowych wersji PostgreSQL i 15 wersji jądra Linux. Jeśli miałbym przepisać te fragmenty, powstałby w rezultacie inny referat. Niemniej jednak omawiamy fundamentalny tuning Linuxa dla PostgreSQL, który jest aktualny także dzisiaj.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański


Odtwarzaj wideo

Nazywam się Iłja Kosmodiemiański. Pracuję w firmie PostgreSQL-Consulting. Teraz opowiem trochę o tym, co robić z Linuxem w kontekście baz danych ogólnie oraz PostgreSQL w szczególności, ponieważ zasady są dość podobne.

O czym będzie mowa? Jeśli komunikujesz się z PostgreSQL, to w pewnym zakresie musisz być administratorem UNIX’a. Co to oznacza? Jeśli porównamy Oracle i PostgreSQL, to w Oracle musisz być w 80% administratorem bazy danych i w 20% administratorem Linuxa.

Z PostgreSQL jest trochę trudniej. Z PostgreSQL musisz znacznie lepiej rozumieć, jak działa Linux. Przy tym trzeba trochę biec za pociągiem, ponieważ ostatnio wszystko jest na bieżąco aktualizowane. Nowe jądra są wydawane, nowa funkcjonalność się pojawia, wydajność się poprawia itd.

Dlaczego mówimy o Linuxie? Nie dlatego, że jesteśmy na konferencji Linux Piter, ale dlatego, że w obecnych warunkach jednym z najbardziej uzasadnionych systemów operacyjnych do pracy z bazami danych ogólnie oraz z PostgreSQL w szczególności jest Linux. Gdyż FreeBSD, niestety, rozwija się w bardzo dziwnym kierunku. Będą problemy zarówno z wydajnością, jak i z wieloma innymi rzeczami. Wydajność PostgreSQL na Windows to w ogóle osobny, surowy temat, który wynika z tego, że Windows nie ma takiej pamięci współdzielonej jak UNIX, a PostgreSQL jest na tym oparty, ponieważ jest systemem wieloprocesowym.

A egzotyka typu Solaris myślę, że interesuje w mniejszym stopniu, więc ruszajmy dalej.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

W nowoczesnej dystrybucji Linuxa jest ponad 1000 parametrów syctl, w zależności od tego, jak skompilować jądro. Przy tym, jeśli spojrzymy jeszcze na różne u ustawienia, to we wiele sposobów można jeszcze coś dostosować. Są parametry systemów plików, jak je montować. Jeśli chodzi o pytania, jak uruchomić: co w BIOS włączyć, jak konfiguracja sprzętu itp.

To jest bardzo obszerna kwestia, o której można mówić przez kilka dni, a nie w krótkim wykładzie, ale skupię się teraz na ważnych aspektach, jak unikać tych pułapek, które na pewno nie pozwolą wam efektywnie korzystać z bazy danych na Linuksie, jeśli ich nie naprawicie. Ważnym punktem jest to, że wiele parametrów domyślnie nie jest ustawionych w sposób właściwy dla bazy danych. To znaczy, że domyślnie może działać słabo lub w ogóle nie działać.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Jakie są tradycyjne cele optymalizacji w Linuksie? Myślę, że ponieważ wszyscy zajmujecie się administracją Linuksem, nie ma potrzeby szczególnie wyjaśniać, czym są cele.

Można optymalizować:

  • Procesor.
  • Pamięć.
  • Zasoby dyskowe.
  • Inne. O tym porozmawiamy na końcu jako przystawkę. Nawet takie parametry, jak polityka oszczędzania energii, mogą w bardzo nieprzewidywalny i nieprzyjemny sposób wpłynąć na wydajność.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Jakie są specyfiki PostgreSQL i bazy danych w ogóle? Problem polega na tym, że nie można po prostu dostroić jakiejś pojedynczej śrubki i zobaczyć, czy wydajność się poprawiła.

Tak, takie śrubki istnieją, ale baza danych to skomplikowana rzecz. Współdziała ze wszystkimi zasobami serwera i preferuje pełne wykorzystanie tych zasobów. Jeśli spojrzysz na współczesne zalecenia Oracle dotyczące użytkowania systemu operacyjnego hosta, przypomina to anegdotę o mongolskim kosmonaucie – nakarmić psa i nic nie ruszać. Dajemy bazie wszystkie zasoby, a baza danych sama wszystko ogarnie.

W zasadzie, w pewnym zakresie sytuacja z PostgreSQL jest podobna. Różnica polega na tym, że baza danych nie potrafi sama wydobyć wszystkich zasobów, to znaczy, że gdzieś na poziomie Linuksa trzeba to wszystko samodzielnie zorganizować.

Główna idea polega na tym, aby nie wybierać jakiegoś pojedynczego celu i zaczynać go optymalizować, na przykład pamięć, CPU lub coś w tym stylu, ale analizować obciążenie i starać się maksymalnie poprawić przepustowość, aby przez naszą bazę danych jak najefektywniej przechodziło obciążenie stworzone przez dobrych programistów, w tym naszych użytkowników.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Oto obrazek, który wyjaśnia, co to jest. Istnieje bufor systemu operacyjnego Linux, a także pamięć współdzielona oraz bufory współdzielone PostgreSQL. W przeciwieństwie do Oracle, PostgreSQL działa bezpośrednio tylko przez bufor jądra, to znaczy, aby strona z dysku trafiła do jego pamięci współdzielonej, musi przejść przez bufor jądra, a sytuacja wygląda dokładnie tak samo w drugą stronę.

Pod tym systemem znajdują się dyski. Zobrazowałem to jako dyski. W rzeczywistości może tam być kontroler RAID itd.

I ten proces wejścia-wyjścia w ten czy inny sposób zachodzi przez to wszystko.

PostgreSQL to klasyczna baza danych. Wewnątrz znajdują się strony. Cały proces wejścia-wyjścia odbywa się za pomocą stron. Podnosimy bloki do pamięci za pomocą stron. I jeśli nic się nie zdarzyło, po prostu je odczytaliśmy, to stopniowo opuszczają one ten cache, z bufory współdzielone i trafiają z powrotem na dysk.

Jeśli gdzieś coś zamieniliśmy, cała strona jest oznaczona jako brudna. Oznaczyłem je tutaj na niebiesko. Oznacza to, że ta strona musi być zsynchronizowana z pamięcią blokową. To znaczy, kiedy ją zrobiliśmy brudną, zapisaliśmy w WAL. A w pewnym pięknym momencie przyszło zjawisko zwane checkpointem. I w tym logu zapisano informację o tym, że się pojawiło. To znaczy, że wszystkie brudne strony, które były w tym momencie w tych bufory współdzielonych, zostały zsynchronizowane z dyskiem pamięci za pomocą fsync przez bufor jądra.

Po co to wszystko zrobić? Jeśli zniknie zasilanie, nie będziemy mieli sytuacji, w której wszystkie dane znikają. Pamięć trwała, o której wszyscy nam opowiadali, to na razie teoria bazy danych – to jasna przyszłość, do której oczywiście dążymy i która nam się podoba, ale na razie żyją jeszcze w minus 20 lat. Oczywiście, trzeba to wszystko monitorować.

Celem maksymalizacji przepustowości jest dostosowanie wszystkich tych etapów, aby wszystko szybko się poruszało tam i z powrotem. Pamięć współdzielona to głównie cache strona. W PostgreSQL wysłaliśmy zapytanie select coś tam, on pobrał te dane z dysku. Trafiły one do bufory współdzielonych. Odpowiednio, żeby to lepiej działało, musi być dużo pamięci.

Aby wszystko działało dobrze i szybko, musisz prawidłowo skonfigurować system operacyjny na wszystkich etapach. Należy również wybrać zrównoważony sprzęt, ponieważ, jeśli w jakimś miejscu wystąpi nierównowaga, możesz mieć bardzo dużo pamięci, ale będzie ona obsługiwana z niewystarczającą prędkością.

Przyjrzymy się wszystkim tym punktom.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Aby te strony poruszały się tam i z powrotem szybciej, musisz osiągnąć następujące cele:

  • Po pierwsze, należy efektywniej zarządzać pamięcią.
  • Po drugie, ten proces przejścia, kiedy strony przechodzą z pamięci na dysk, musi być bardziej efektywny.
  • I po trzecie, powinny być dobre dyski.

Jeśli masz 512 GB pamięci RAM w serwerze a wszystko to ostatecznie trafia na dysk twardy SATA bez żadnej pamięci podręcznej, cały serwer baz danych staje się nie tylko dynią, ale dynią z interfejsem SATA. Będziesz się z tym bezpośrednio zderzać. I nic cię nie uratuje.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Jeśli chodzi o pierwszy punkt dotyczący pamięci, istnieją trzy rzeczy, które mogą znacznie utrudnić życie.

Pierwsza z nich to NUMA. NUMA to rzecz, która ma na celu poprawę wydajności. W zależności od obciążenia można optymalizować różne rzeczy. W swoim nowym obecnym kształcie nie jest zbyt dobra dla aplikacji takich jak baz danych, które intensywnie korzystają z pamięci podręcznej stron.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Krótko mówiąc, jak zrozumieć, że coś jest nie tak z NUMA? Masz jakiś nieprzyjemny hałas, nagle któryś z procesorów jest przeciążony. Analizujesz zapytania w PostgreSQL i widzisz, że nie ma tam nic, co by to uzasadniało. Te zapytania nie powinny tak intensywnie obciążać CPU. Można to łapać długo. Prościej skorzystać na samym początku z właściwej rekomendacji, jak skonfigurować NUMA dla PostgreSQL.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Co tak naprawdę się dzieje? NUMA to Non-Uniform Memory Access. O co chodzi? Masz CPU, obok niego jest jego lokalna pamięć. Ta pamięć może przyciągać pamięć z innych CPU przez interkonekty.

Jeśli uruchomisz numactl --hardware, to zobaczysz duży zestaw danych. Między innymi będzie tam pole distances. Będą cyfrówki – 10-20, coś w tym stylu. Te cyfrówki to nic innego jak liczba hopów, aby podłączyć tę zdalną pamięć i używać jej lokalnie. W zasadzie to dobry pomysł. Przy odpowiednich obciążeniach znacznie przyspiesza wydajność.

Wyobraź sobie, że masz jeden CPU, który najpierw próbuje korzystać z własnej pamięci lokalnej, a następnie próbuje załadować inną pamięć przez interconnect do czegoś. Cała pamięć podręczna strony PostgreSQL trafia na ten CPU – to wszystko, ileś tam gigabajtów. Zawsze dostajesz najgorszy przypadek, ponieważ w module pamięci bezpośrednio podłączonym do tego CPU zazwyczaj jest mało pamięci. A cała pamięć, która jest obsługiwana, przemieszcza się przez te interconnecty. To jest wolne i smutne. I masz procesor, który obsługuje ten węzeł, non-stop przeciążony. A czas dostępu do tej pamięci – jest zły, wolny. To sytuacja, której nie chcesz, jeśli używasz tego do bazy danych.

Dlatego bardziej poprawną opcją dla bazy danych jest całkowite ukrycie działania systemu operacyjnego Linux. Powinna ona odnosić się do pamięci tak, jak zwykle to robi.

Dlaczego tak? Wydawałoby się, że powinno być na odwrót. Dzieje się tak z jednego prostego powodu – potrzebujemy wiele pamięci dla pamięci podręcznej strony – dziesiątki, setki gigabajtów.

A jeśli to wszystko przydzielimy i zbuforujemy nasze dane w niej, to zysk z wykorzystania buforu będzie zdecydowanie większy niż korzyść z takiego sprytnego dostępu do pamięci. W ten sposób zyskamy nieporównywalnie więcej niż w przypadku bardziej efektywnego dostępu do pamięci z wykorzystaniem NUMA.

Dlatego w chwili obecnej istnieją dwa podejścia, dopóki jasna przyszłość nie nastała i baza danych nie nauczyła się sama rozumieć, na których CPU działa i skąd powinna coś pobrać.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Dlatego prawidłowym podejściem jest całkowite wyłączenie NUMA, na przykład przy ponownym uruchomieniu. W większości przypadków zyski są tak duże, że w ogóle nie ma pytania, co jest lepsze.

Jest inna opcja. Częściej korzystamy z niej niż z pierwszej, ponieważ, gdy klient zgłasza się do nas z problemem, ponowne uruchomienie serwera to dla niego duża sprawa. Jego biznes tam działa. A oni doświadczają problemów z NUMA. Dlatego staramy się wyłączyć to mniej inwazyjnymi metodami niż reboot, ale tutaj trzeba ostrożnie sprawdzić, czy zostało to wyłączone. Ponieważ doświadczenie pokazuje, że wyłączając NUMA dla głównego procesu PostgreSQL, to działa dobrze, ale niekoniecznie jest gwarancją, że to zadziała. Należy sprawdzić i upewnić się, że rzeczywiście to wyłączono.

Jest dobry post Roberta Haasa. To jeden z komitujących do PostgreSQL. Jeden z kluczowych deweloperów wszystkich niskopoziomowych komponentów. Jeśli przejdziecie przez linki zawarte w tym poście, opisuje kilka barwnych historii o tym, jak NUMA utrudniała życie. Spójrzcie, przestudiujcie checklistę administratora systemu, co należy skonfigurować na serwerze, aby nasza baza danych działała dobrze. Te ustawienia należy zanotować i monitorować, ponieważ w przeciwnym razie będzie to miało nieprzyjemne skutki.

Zwracam uwagę, że to dotyczy wszystkich ustawień, o których będę mówił. Zazwyczaj bazy danych są konfigurowane w trybie master-slave dla zapewnienia odporności na awarie. Nie zapomnijcie wprowadzić tych ustawień na slave, ponieważ w pewnym momencie dojdzie do awarii, przestawicie się na slave, a on stanie się masterem.

W sytuacji awaryjnej, gdy wszystko jest bardzo źle, telefon non stop dzwoni, a szef przybiega z dużą pałą, nie będziecie mieli czasu na myślenie o sprawdzeniu. A wyniki mogą być bardzo niekorzystne.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Następny aspekt to huge pages. Huge pages trudno przetestować osobno, a w zasadzie nie ma sensu, chociaż są benchmarki, które potrafią to zrobić. Łatwo je znaleźć w Internecie.

Na czym to polega? Macie serwer, który nie jest bardzo drogi, ale ma dużo pamięci RAM, na przykład powyżej 30 GB. Nie używacie huge pages. To oznacza, że macie z pewnością overhead związany z używaniem pamięci. A ten overhead wcale nie jest przyjemny.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Dlaczego tak jest? Co się dzieje? System operacyjny przydziela pamięć w małych kawałkach. To wygodne, tak historycznie się ułożyło. A jeśli wniknąć w szczegóły, to OS musi przetłumaczyć adresy wirtualne na fizyczne. Proces ten nie jest najprostszy, dlatego OS przechowuje wynik tej operacji w buforze Translation Lookaside Buffer (TLB).

Ponieważ TLB to pamięć podręczna, to w takiej sytuacji występują wszystkie charakterystyczne problemy związane z pamięcią podręczną. Po pierwsze, jeśli macie bardzo dużo pamięci RAM i jest ona przydzielona w małych fragmentach, to bufor staje się bardzo duży. A jeśli pamięć podręczna jest duża, to jej przeszukiwanie zajmuje więcej czasu. Overhead jest znaczny, a on sam zajmuje miejsce, to znaczy, że pamięć RAM konsumuje coś niepoprawnego. To pierwsza kwestia.

Im więcej rośnie pamięć podręczna w takiej sytuacji, tym większe prawdopodobieństwo, że doświadczysz błędów pamięci podręcznej. A efektywność tej pamięci podręcznej szybko spada wraz ze wzrostem jej rozmiaru. Dlatego w systemach operacyjnych wymyślono prosty sposób. W Linuksie jest to od dawna stosowane. W FreeBSD wprowadzono to niedawno. Ale mówimy o Linuksie. To są huge pages.

Warto zaznaczyć, że huge pages jako koncepcja została pierwotnie wprowadzona przez społeczności, które obejmowały Oracle i IBM, co oznacza, że producenci baz danych mocno zastanawiali się, jak to przyda się także dla baz danych.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Jak to połączyć z PostgreSQL? Po pierwsze, w jądrze Linuksa muszą być włączone huge pages.

Po drugie, muszą być wyraźnie określone przez parametr sysctl – ile ich ma być. Liczby tutaj pochodzą z jakiegoś starego serwera. Możesz obliczyć, ile mniej więcej masz shared buffers, aby huge pages mogły się tam zmieścić.

Jeśli cały serwer jest dedykowany PostgreSQL, dobrym punktem wyjścia jest przydzielenie 25% pamięci RAM na shared buffers lub 75%, jeśli jesteś pewien, że w tych 75% twoja baza danych na pewno się zmieści. To jest pierwszy punkt wyjścia. Oblicz, jeśli masz 256 GB pamięci RAM, to odpowiednio 64 GB będzie twoimi shared buffers. Oblicz to z pewnym zapasem – na jaką wartość powinieneś ustawić tę liczbę.

Do wersji 9.2 (jeśli się nie mylę, to od wersji 8.2) można było połączyć PostgreSQL z huge pages za pomocą zewnętrznej biblioteki. Zawsze należy to robić. Po pierwsze, musisz mieć pewność, że jądro potrafi poprawnie przydzielać huge pages. Po drugie, aplikacja działająca z nimi musi móc z nich skorzystać. Tak po prostu nie skorzysta. Ponieważ PostgreSQL przydzielał pamięć w stylu systemu 5, można było to zrobić za pomocą libhugetlbfs – pełna nazwa biblioteki.

W wersji 9.3 poprawiono wydajność PostgreSQL w zakresie zarządzania pamięcią i porzucono metodę przydzielania pamięci systemu 5. Wszyscy się ucieszyli, ponieważ w przeciwnym razie próbując uruchomić dwa instancje PostgreSQL na jednej maszynie, otrzymywałeś komunikat o braku pamięci współdzielonej. I mówił, że trzeba poprawić sysctl. A tam taki sysctl, że trzeba jeszcze zrestartować system itp. Ogólnie rzecz biorąc, wszyscy się ucieszyli. Jednak przydzielanie pamięci mmap zepsuło użycie huge pages. Większość naszych klientów korzysta z dużych buforów współdzielonych. I zdecydowanie zalecaliśmy, aby nie przechodzić na wersję 9.3, ponieważ overhead zaczynał się liczyć w sporych procentach.

Ale z drugiej strony społeczność zwróciła uwagę na ten problem i w wersji 9.4 bardzo dobrze przemyślano tę kwestię. W wersji 9.4 pojawił się parametr w postgresql.conf, który pozwala włączyć tryb try, on lub off.

Try to najbardziej bezpieczny parametr. Podczas uruchamiania PostgreSQL, kiedy przydziela pamięć współdzieloną, próbuje przejąć tę pamięć z huge pages. I jeśli się nie uda, wraca do zwykłego przydzielania. Jeśli korzystasz z FreeBSD lub Solaris, możesz ustawić try, to zawsze jest bezpieczne.

Jeśli on, to po prostu nie uruchomi się, jeśli nie uda mu się przydzielić z huge pages. Tutaj już – komu co bardziej odpowiada. Ale jeśli masz try, sprawdzaj, czy na pewno przydzieliło to, co trzeba, ponieważ jest dużo przestrzeni na błąd. Obecnie ta funkcjonalność działa tylko na systemach Linux.

Jeszcze jedna mała uwaga, zanim przejdziemy dalej. Transparent huge pages – to nie jest opcja dla PostgreSQL jak dotąd. Nie może ich wykorzystać w sposób prawidłowy. A przy Transparent huge pages dla takiego obciążenia, które wymaga dużych fragmentów pamięci współdzielonej, korzyści pojawiają się tylko przy naprawdę dużych pojemnościach. Jeśli masz terabajty pamięci, wtedy może mieć to znaczenie. Jeśli mówimy o bardziej codziennych zastosowaniach, gdy masz 32, 64, 128, 256 GB pamięci na maszynie, to zwykłe huge pages są ok, a Transparent po prostu wyłączamy.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

I ostatnia sprawa, dotycząca pamięci, niezwiązana bezpośrednio z wydajnością, może bardzo uprzykrzyć życie. Cała przepustowość może bardzo ucierpieć, gdy serwer stale wymienia pamięć.

I to będzie bardzo nieprzyjemne w wielu momentach. A zasadnicza nieprzyjemność polega na tym, że w nowoczesnych jądrach zachowanie różni się nieco od starszych jąder Linux. I to jest coś, na co denerwująco się natykamy, ponieważ, gdy mówimy o pracy z swap'em, kończy się to nieterminowym przybyciem OOM-killera. A OOM-killer, który przyszedł za późno i zabił PostgreSQL, to nieprzyjemna sytuacja. Dowie się o tym każdy, to znaczy aż do ostatniego użytkownika.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Co się dzieje? Masz tam dużą ilość pamięci operacyjnej, wszystko działa dobrze. Ale z jakiegoś powodu serwer zawiesza się w swapie i zwalnia się przez to. Wydawałoby się, że jest dużo pamięci, ale tak się dzieje.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Kiedyś doradzaliśmy, aby ustawić vm.swappiness na zero, tzn. wyłączyć swap. Kiedyś wydawało się, że 32 GB pamięci operacyjnej i odpowiednie bufory shared to ogromna ilość. Głównym celem swapu jest posiadanie miejsca, do którego można wrzucić procesy, jeśli coś się wysypie. I to już przestało działać. A co potem z tymi procesami? To już takie zadanie, w którym nie bardzo wiadomo, po co potrzebny jest swap, tym bardziej w tak dużym rozmiarze.

Jednak w nowoczesnych wersjach, tzn. w trzecich wersjach jądra, zachowanie się zmieniło. I jeśli ustawisz swap na zero, tzn. wyłączysz go, to prędzej czy później, nawet przy pozostałej pewnej ilości pamięci operacyjnej, OOM-killer przyjdzie, aby zabić najbardziej intensywnych konsumentów. Ponieważ uzna, że przy takim obciążeniu zostało nam jeszcze trochę i wyskoczymy, tzn. nie zabić proces systemowy, ale czegoś mniej ważnego. Tym mniej ważnym okaże się intensywny konsument pamięci shared, a mianowicie postmaster. I po tym będzie dobrze, jeśli nie trzeba będzie przywracać bazy.

Dlatego teraz domyślnie, o ile pamiętam, w większości dystrybucji to około 6, tzn. w jakim momencie zacząć używać swapu w zależności od tego, ile pamięci pozostało. Obecnie doradzamy ustawienie vm.swappiness = 1, ponieważ praktycznie to wyłącza, ale nie ma takich efektów, jak z niespodziewanie przybyłym OOM-killerem, który wszystko to zabija.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Co dalej? Kiedy mówimy o wydajności baz danych i stopniowo przechodzimy do dysków, wszyscy chwytają się za głowę. Prawda jest taka, że dyski są wolne, a pamięć szybka, co jest znane każdemu od dzieciństwa. Wszyscy wiedzą, że w bazach danych pojawią się problemy z wydajnością dysków.

Główny problem z wydajnością PostgreSQL związany z szczytami checkpointów nie wynika z wolnych dysków. Wynika to raczej z tego, że przepustowość pamięci i dysków nie jest zrównoważona. Mogą być one nierównoważone w różnych miejscach. PostgreSQL nie jest skonfigurowany, system operacyjny nie jest skonfigurowany, sprzęt nie jest skonfigurowany i sprzęt jest niewłaściwy. Tego problemu unika się tylko w sytuacji, gdy wszystko działa jak należy, to znaczy, że albo nie ma obciążenia, albo ustawienia i sprzęt są dobrze dobrane.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Czym to jest i jak to wygląda? Zazwyczaj ludzie, którzy pracują z PostgreSQL, wielokrotnie stawali przed tym zagadnieniem. Już wyjaśniam. Jak mówiłem, PostgreSQL okresowo wykonuje checkpointy, aby zapisać brudne strony w pamięci współdzielonej na dysku. Jeśli mamy dużą ilość pamięci współdzielonej, to checkpoint zaczyna intensywnie wpływać na dysk, ponieważ zapisuje te strony za pomocą fsync. Trafia do bufora jądra i jest zapisywany na dyski za pomocą fsync. Jeśli objętość tego procesu jest duża, możemy zaobserwować nieprzyjemny efekt, a mianowicie bardzo dużą utylizację dysków.

Tutaj mam dwa wykresy. Zaraz wyjaśnię, czym one są. To dwa skorelowane w czasie wykresy. Pierwszy wykres to utylizacja dysków. W tym momencie osiąga prawie 90%. Jeśli masz bazę danych z fizycznymi dyskami i z kontrolerem RAID z utylizacją bliską 90%, to są to złe wieści. To znaczy, że jeszcze trochę, a osiągnie 100% i operacje wejścia/wyjścia zostaną zatrzymane.

Jeśli masz macierz dyskową, to tam sytuacja jest nieco inna. Wtedy wszystko zależy od tego, jak jest skonfigurowana, co to za macierz itp.

Jednocześnie skonfigurowano tutaj wykres z wewnętrznej widoku Postgress, który pokazuje, jak odbywa się checkpoint. Zielonym kolorem wskazano, ile buforów, tych brudnych stron, w tym momencie przybyło do tego checkpointu w celu synchronizacji. I to jest najważniejsze, co tutaj należy wiedzieć. Widać, że mamy tutaj dużo stron, a w pewnym momencie napotkaliśmy na szczeliny, tzn. pisaliśmy pisaliśmy, widać, że system dyskowy jest bardzo zajęty. I nasz checkpoint wywiera silny wpływ na dysk. W idealnej sytuacji powinno to wyglądać raczej tak, tzn. mieliśmy mniej zapisów. I ustawieniami możemy to naprawić, aby tak było w przyszłości. Tzn. utylizacja jest niewielka, ale gdzieś coś zapisujemy.

Co trzeba zrobić, aby pokonać ten problem? Jeśli zatrzymało się IO pod bazą danych, to znaczy, że wszyscy użytkownicy, którzy przyszli wykonać swoje zapytania, będą czekać.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Patrząc z punktu widzenia Linuxa, jeśli wziąłeś dobry sprzęt, odpowiednio go skonfigurowałeś, poprawnie skonfigurowałeś PostgreSQL, aby rzadziej robił te checkpointy, rozprzestrzeniał je w czasie, wchodzi się w domyślne parametry Debiana. Dla większości dystrybucji Linux taki obrazek: vm.dirty_ratio=20, vm.dirty_background_ratio=10.

Co to oznacza? Od jądra 2.6 pojawił się jeden demon flushingu. Pdglush w zależności od tego, kto co używa, który zajmuje się tłem zrzucania brudnych stron z bufora jądra oraz zrzucania, gdy to konieczne, za wszelką cenę zrzucania brudnych stron, gdy backgroundowe zrzucanie już nie pomaga.

Kiedy następuje background? Kiedy 10 % całej pamięci RAM, która jest dostępna na serwerze, jest zajęta brudnymi stronami w buforze jądra, wywoływana jest specjalna funkcja zrzucania w tle. Dlaczego nazywa się to background? Przyjmuje jako parametr, ile stron zrzucić. I, powiedzmy, zrzuca N stron. A przez pewien czas ten mechanizm zasypia. A potem znowu przychodzi i zrzuca jeszcze pewną ilość stron.

To bardzo prosta historia. Tutaj zadanie jest jak z basenem, kiedy w jedna rurę wlewa się, a druga wlewa. Nasz checkpoint przyszedł i jeśli wysłał mało brudnych stron do zrzucenia, to stopniowo z bufora jądra pgflush to wszystko delikatnie się wchłonie.

Jeśli te brudne strony będą się dalej gromadzić, mogą osiągnąć 20%; wtedy system operacyjny priorytetowo zarchiwizuje to na dysk, ponieważ zasilanie może się wyłączyć, a my będziemy mieli problem. Stracimy na przykład te dane.

Gdzie tkwi haczyk? Haczyk polega na tym, że te parametry w nowoczesnym świecie 20% i 10% całkowitej pamięci RAM, którą ma maszyna, są naprawdę ogromne z punktu widzenia przepustowości jakiegokolwiek systemu dyskowego, który posiadasz.

Wyobraź sobie, że masz 128 GB pamięci RAM. 12,8 GB trafia do twojego systemu dyskowego. I niezależnie od tego, jaki masz tam cache, ani jaki masz macierz, nie poradzą sobie z tym.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Dlatego zalecamy natychmiastowe ustawienie tych wartości zgodnie z możliwościami twojego kontrolera RAID. Oto od razu podana rekomendacja dla kontrolera, który ma 512 MB cache.

Wszystko jest bardzo proste. Możesz ustawić vm.dirty_background w bajtach. Te ustawienia zastępują dwa poprzednie. Albo domyślne ratio, albo aktywowane te, które są w bajtach; zadziałają te w bajtach. Ale ponieważ jestem konsultantem DBA i pracuję z różnymi klientami, staram się zabezpieczać, więc jeśli w bajtach, to w bajtach. Nikt nie daje żadnej gwarancji, że dobry administrator nie doda pamięci serwerowi, nie zrestartuje go, a liczba pozostanie taka sama. Po prostu oszacuj te wartości, aby z gwarancją wszystko się zmieściło.

Co się stanie, jeśli nie zmieścisz się? Mam napisane, że skutecznie zatrzymuje się wszelkie flushowanie, ale w rzeczywistości to figura retoryczna. System operacyjny ma duży problem – ma dużo brudnych stron, więc skutecznie zatrzymuje się ten IO, który generują twoi klienci, tzn. gdy aplikacja wysyła zapytanie SQL do bazy danych, czeka. Każdy I/O w niej ma najniższy priorytet, ponieważ baza jest zajęta checkpointem. I kiedy ją zakończy, nie wiadomo. A gdy osiągniesz flushing, który nie jest tłem ani w tle, to oznacza, że wszystkie IO są zajęte tym. I dopóki to się nie zakończy, nic nie zrobisz.

Są jeszcze dwa istotne aspekty, które wykraczają poza ten raport. Te ustawienia powinny być zgodne z ustawieniami w postgresql.conf, tzn. ustawieniami checkpointów. A twój system dyskowy musi być odpowiednio skonfigurowany. Jeśli masz pamięć podręczną na RAID, to musi być w niej bateria. Ludzie kupują RAID z dobrą pamięcią podręczną bez baterii. Jeśli masz SSD w RAID, to powinny to być serwerowe, muszą być w nim kondensatory. Tutaj znajduje się szczegółowa lista kontrolna. Pod tym linkiem jest mój raport na temat konfigurowania wydajności dysków w PostgreSQL. Tam znajdują się wszystkie te listy kontrolne.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Co jeszcze może bardzo utrudnić życie? To dwa parametry. Są stosunkowo nowe. Domyślnie mogą być włączone w różnych aplikacjach. Mogą znacznie skomplikować życie, jeśli zostaną włączone niewłaściwie.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Są dwie stosunkowo nowe rzeczy. Pojawiły się już w trzecich rdzeniach. To sched_migration_cost w nanosekundach oraz sched_autogroup_enabled, który domyślnie jest aktywowany.

Jak one psują życie? Co to jest sched_migration_cost? Harmonogram w Linuksie może przenieść proces z jednego CPU na inny. Dla PostgreSQL, który wykonuje zapytania, migracja na inny CPU jest zupełnie niezrozumiała. Z punktu widzenia systemu operacyjnego, kiedy przełączasz okna między openoffice a terminalem, może to być dobre, ale dla bazy danych – to bardzo źle. Dlatego rozsądna polityka to ustawienie migration_cost na jakąś dużą wartość, przynajmniej kilka tysięcy nanosekund.

Co to będzie oznaczać dla scheduler? Będzie uważać, że przez ten czas ten proces wciąż jest gorący. Tzn. jeśli masz jakąś długą transakcję, która czymś długo się zajmuje, scheduler to zrozumie. Będzie uważać, że póki nie minie ten czas, migracja tego procesu nigdzie nie jest potrzebna. Jeśli proces coś robi, to nie zostanie nigdzie przeniesiony, spokojnie dokończy na tym CPU, które mu przydzielono. I rezultat jest znakomity.

Drugi punkt – to autogroup. Jest to dobra idea dla specyficznych obciążeń roboczych, które nie mają związku z nowoczesnymi bazami danych – grupowanie procesów według tego wirtualnego terminala, z którego zostały uruchomione. To wygodne dla niektórych zadań. W praktyce PostgreSQL to system wieloprocesowy z preforkiem, uruchamiany z jednego terminala. Macie blokadę pisania, punkt kontrolny i wszystkie Wasze zapytania klienckie zostaną zgrupowane w jednym harmonogramie, na jednym CPU. Będą tam czekać, aż się zwolni, aby przeszkodzić sobie i zajmować go dłużej. To historia, która jest całkowicie niepotrzebna w przypadku takiego obciążenia, dlatego należy to wyłączyć.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Mój kolega Aleksiej Lesowski przeprowadzał testy z prostym pgbench'em, gdzie zwiększał kilkukrotnie migration_cost i wyłączał autogroup. Różnica na słabym sprzęcie wyniosła prawie 10%.. Jest dyskusja na liście dyskusyjnej postgres, gdzie ludzie przedstawiają wyniki, jak podobne zmiany wpłynęły na prędkość zapytania. wpłynęły na 50%.. Takich historii jest całkiem sporo.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

I na koniec o polityce oszczędzania energii. Dobrze, że teraz Linux można używać na laptopie. I teoretycznie będzie dobrze gospodarować baterią. Ale niespodziewanie okazuje się, że na serwerze też może być tak samo.

Co więcej, jeśli wynajmujecie serwery od jakiegoś hostera, to 'życzliwi' hosterzy nie dbają o to, żebyście mieli lepszą wydajność. Ich celem jest maksymalna efektywność utylizacji sprzętu. Dlatego domyślnie mogą w systemie operacyjnym włączyć tryb oszczędzania energii dla laptopów.

Jeśli używacie na serwerze z bazą danych pod intensywnym obciążeniem tego rodzaju dobroci, to Waszym wyborem jest acpi_cpufreq + performance. Już z ondemand będą problemy.

Intel_pstate to już nieco inny sterownik. I obecnie preferowane jest to rozwiązanie, jako nowsze i lepiej działające.

I w związku z tym, governor tylko performance. Ondemand, powersave i wszystko inne – to nie dla Was.

Wyniki z explain analyze w PostgreSQL mogą się różnić o kilka rzędów wielkości, jeśli włączycie powersave, ponieważ w zasadzie CPU pod bazą będzie planowane w zupełnie nieprzewidywalny sposób.

Te rzeczy mogą być włączone domyślnie. Uważnie sprawdźcie – czy nie włączyli ich domyślnie. To może być naprawdę dużym problemem.

Tuning Linux do poprawy wydajności PostgreSQL. Ilja Kosmodiemiański

Na koniec chciałem podziękować ekipie naszego zespołu DBA PosgreSQL-Consulting, a konkretnie Maksowi Boguku i Aleksiejowi Lesowskiemu, którzy każdego dnia uczą się na błędach. Staramy się, aby dla naszych klientów wszystko działało jak najlepiej. To jak z instrukcjami bezpieczeństwa lotniczego. Wszystko jest zapisane krwią. Każda z tych nakrętek została odkryta w trakcie rozwiązywania jakiegoś problemu. Z radością dzielę się nimi z wami.

Pytania:

Dziękuję! Jeśli na przykład firma chce zaoszczędzić i umieścić bazę danych oraz logikę aplikacji na jednym serwerze, lub jeśli firma podąża za modną tendencją architektur mikroserwisowych, w których PostgreSQL działa w kontenerze. Jaka jest kwintesencja? Sysctl globalnie wpływa na całe jądro. Nie słyszałem, aby sysctl jakoś się wirtualizował, aby działał oddzielnie na kontenerze. Jest tylko cgroup, gdzie kontrola jest tylko częściowa. Jak można z tym żyć? A jeśli chcesz wydajności, to uruchom PostgreSQL na oddzielnym serwerze fizycznym i optymalizuj go?

Odpowiedzieliśmy na twoje pytanie na około trzy sposoby. Jeśli chodzi o serwer fizyczny, który można optymalizować, to zrelaksuj się, wszystko będzie działać dobrze bez tych ustawień. Jeśli obciążenie jest na tyle duże, że potrzebujesz tych ustawień, to prędzej czy później i tak uzyskasz dostęp do serwera fizycznego.

Jaki jest problem? Jeśli to wirtualna maszyna, prawdopodobnie napotkasz wiele problemów, na przykład z tym, że na większości wirtualek latencja dysku jest wystarczająco niekonsekwentna. Nawet jeśli przepustowość dysków jest dobra, jedna nieudana transakcja operacji wejścia/wyjścia, która niezbyt wpływa na średnią przepustowość, występująca w momencie checkpointa lub zapisu w WAL, spowoduje, że baza danych będzie znacznie cierpieć. Zauważysz to wcześniej, niż napotykasz te problemy.

Jeśli na tym samym serwerze będzie NGINX, wystąpi ten sam problem. Będzie walczył o współdzieloną pamięć. I nie dojdziesz do problemów opisanych tutaj.

Z drugiej strony jednak niektóre z tych parametrów będą dla Ciebie istotne. Na przykład, w sysctl ustaw dirty_ratio, aby nie było to zbyt ekstremalne – w każdym razie to pomoże. Tak czy inaczej, będziesz miał interakcję z dyskiem. Będzie ona jednak przebiegać według niewłaściwego schematu. To w zasadzie domyślne te parametry, które pokazywałem. W każdym razie lepiej je zmienić.

Z NUMA mogą być problemy. VmWare, na przykład, dobrze działa z NUMA z dokładnie przeciwnymi ustawieniami. I tutaj musisz wybierać – serwer fizyczny czy nie fizyczny.

Mam pytanie związane z Amazon AWS. Mają zdjęcia wstępnie skonfigurowane. Jeden z nich nazywa się Amazon RDS. Czy są tam jakieś niestandardowe ustawienia dla ich systemu operacyjnego?

Są tam ustawienia, ale to są inne ustawienia. Tutaj konfigurujemy system operacyjny z punktu widzenia tego, jak baza danych będzie tego używać. A tam są parametry, które określają, gdzie teraz powinniśmy iść, taki shaping. To znaczy potrzebujemy tylu zasobów, które teraz będziemy konsumować. Po tym Amazon RDS te zasoby uruchamia i tam wydajność spada. Są osobne historie, jak ludzie zaczynają się tym zajmować. Czasami nawet z dość dużym sukcesem. Ale to nie ma związku z ustawieniami OS. To jak hackowanie chmury. To inna historia.

Dlaczego Transparent huge pages nie dają efektu w porównaniu z Huge TLB?

Nie dają. Można to wyjaśnić na wiele sposobów. Ale w rzeczywistości po prostu go nie dają. Jaka jest historia PostgreSQL? Przy starcie przydziela duży kawałek pamięci współdzielonej. To, czy są transparentne, czy nie transparentne – nie ma to wcale znaczenia. Fakt, że są przydzielane na starcie, wyjaśnia wszystko. I jeśli pamięci jest bardzo dużo i trzeba przebudować segment shared_memory, wtedy Transparent huge pages będą istotne. W PostgreSQL po prostu przy starcie są przydzielane ogromnym kawałkiem i to wszystko, a dalej nic szczególnego się nie dzieje. Oczywiście można używać, ale istnieje ryzyko uzyskania uszkodzonej pamięci współdzielonej, gdy będzie ponownie przydzielać cokolwiek. PostgreSQL o tym nie wie.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster