Notkę tą piszę w nawiązaniu do komentarzy spod poprzedniego postu. Jeden z czytelników, Cezary, pytał o sugestie dotyczące doboru sprzętu dla serwera MySQL. Chciałbym trochę rozszerzyć odpowiedzi, które w tym temacie u dzieliłem.

Serwer fizyczny to w zasadzie trzy główne zasoby – moc obliczeniowa procesora, ilość pamięci, wydajność podsystemu dyskowego. Z tych trzech dwa ostatnie, czyli ilość pamięci i wydajność I/O, są powiązane ze sobą przez system cache – czy to systemowych, czy to MySQL. Jak zapewne większość czytelników wie, zarówno system operacyjny, jak też MySQL, umożliwia przechowywanie części danych w pamięci, tak aby dostęp do nich nie wymagał dostępu do najwolniejszego (zazwyczaj) elementu serwera, czyli dysków. Im więcej danych z aktywnego zestawu mieści się w pamięci (nie wszystkie dane muszą tam trafić, ważne są tylko te dane, na których wykonywane są operacje), tym mniejsze obciążenie dysku.

Tak więc, mamy dwa zasoby – wydajność procesora i wydajność dysków (będąca także funkcją ilości pamięci w serwerze). Mamy też dwa rodzaje obciążenia, w których wąskim gardłem staje się procesor bądź dysk (z angielskiego nazywa się to “CPU bound workload” i “IO bound workload”).

Kiedy serwer MySQL jest “CPU bound”? Zazwyczaj wtedy, gdy aktywne dane mieszczą się w pamięci – wtedy jedyną barierą jest wydajność procesora. Innym przykładem mogą być zapytania, które wykonują jakiegoś rodzaju obliczenia (np. arytmetyczne), obciążające procesor. Tego typu obciążenie generują także zapytania, które nie korzystają poprawnie z indeksów i w efekcie CPU jest zmuszony do wykonywania dużej ilości niepotrzebnych porównań pomiędzy rekordami. Objawy tego typu obciążenia to znaczący wzrost obciążenia user i system obserwowany np. przy pomocy polecenia top.

MySQL staje się “IO bound” w momencie, gdy główną pracę wykonują dyski. Przykładem takiego obciążenia będą zapytania, które tworzą tabelę tymczasową na dysku. Inny przykład to sytuacja, w której aktywne dane nie mieszczą się w buforach w pamięci, przez co podsystem I/O obciążony jest przez ich odczytywanie i zapisywanie. Objawem pojawienia się tego typu obciążenia jest duże obciążenie wait na procesorze – czyli wzrost ilości czasu, jaki procesor spędza na oczekiwaniu na dane.

Gdy wybieramy sprzęt dla konkretnego serwera MySQL, obsługującego konkretne bazy danych, trzeba ustalić co jest wąskim gardłem. Do tego może się okazać konieczne wykonanie serii dokładnych testów, ale czas poświęcony na to jest niezbędny aby móc świadomie podejmować dalsze decyzje. Jeśli problemem jest brak mocy obliczeniowej procesora, to nie ma wielkiego sensu w inwestowanie w gigabajty pamięci i szybkie dyski SSD. MySQL nie zrobi z nich żadnego użytku, bo i tak trzeba czekać na procesor. Tak samo w drugą stronę, jeśli problemem jest wydajność podsystemu dyskowego, to mnożenie rdzeni nie jest rozwiązaniem – ile by ich nie było to i tak muszą czekać na dane z przeciążonych dysków twardych.

Powyższe to oczywiście dosyć uproszczony opis sytuacji. Pominąłem choćby kwestię skalowania się samego MySQL – możemy mieć luźny procesor i kartę SSD, która realizuje setki tysięcy operacji dyskowych na sekundę, ale nagromadzenie wewnętrznych locków i muteksów w MySQL jest tak duże, że fizycznie nic więcej z serwera nie wyciągniemy (a przynajmniej na jednej instancji MySQL). Mam jednak nadzieję, że wyjaśniłem dlaczego nie da się ot tak wybrać odpowiedni sprzęt, jeśli nie znamy dokładnie aplikacji i tego, jaki rodzaj obciążenia ona generuje.