it-swarm.dev

O wydajności baz danych jednowątkowych i wielowątkowych

H2 to jednowątkowa baza danych o dobrej reputacji pod względem wydajności. Inne bazy danych są wielowątkowe.

Moje pytanie brzmi: kiedy baza danych z wieloma wątkami staje się bardziej interesująca niż baza z jednym wątkiem? Ilu użytkowników? Ile procesów? Co jest wyzwalaczem? Czy ktoś ma doświadczenie do podzielenia się?

Podsumowanie

  • Zwykłym wąskim gardłem jest dostęp do dysku
  • Dyski SSD są szybkie, ale delikatne (procedura awarii jest koniecznością)
  • Jedno długie zapytanie w systemie z jednym wątkiem zablokuje wszystkie pozostałe
  • Konfiguracja systemu wielowątkowego może być trudna
  • Wielowątkowe bazy danych są korzystne nawet w systemach jednordzeniowych
59

Oto moja opinia:

Zwykle wąskim gardłem (lub najwolniejszą częścią) systemu DB jest dysk. Procesor przyspiesza tylko podczas operacji arytmetycznych, przetwarzania lub innych zadań wykonywanych przez procesor. Przy odpowiedniej architekturze wielowątkowość może pomóc zrównoważyć obciążenie zapytania do procesora zamiast wykonywać wolne operacje odczytu/zapisu na dysku. Są przypadki, w których szybsze jest obliczenie wartości za pomocą cykli procesora niż utworzenie kolumny obliczeniowej (która została wcześniej zapisana na dysku) i odczytanie tej kolumny z dysku.

W niektórych RDBMS istnieje tymczasowa baza danych (tempdb), która jest używana przez wszystkie bazy danych w tej instancji do sortowania, mieszania, zmiennych tymczasowych itp. ... Wielowątkowość i dzielenie tych plików tempdb można wykorzystać do poprawy przepustowości tempdb , poprawiając w ten sposób ogólną wydajność serwera.

Używając wielowątkowości (równoległości), zestaw wyników zapytania można podzielić na różne rdzenie serwera, zamiast używać jednego rdzenia. Ta funkcja nie zawsze poprawia wydajność, ale zdarzają się przypadki, w których tak się dzieje, dlatego funkcja jest dostępna.

Wątki dostępne dla DB są wykorzystywane do wielu celów: odczytywania/zapisywania na dysk, połączeń użytkownika, zadań w tle, blokowania/blokowania, we/wy sieci itp. ... W zależności od architektury systemu operacyjnego wątki są prewencyjnie podawane do procesora i są zarządzany za pomocą oczekiwania i kolejek. Jeśli procesor może dość szybko zniszczyć te wątki, czasy oczekiwania będą krótkie. Wielowątkowy DB będzie szybszy niż jednowątkowy DB, ponieważ w jednowątkowym DB wystąpi narzut związany z recyklingiem tylko jednego wątku, zamiast posiadania innych bieżników łatwo dostępnych.

Skalowalność staje się również problemem, ponieważ do zarządzania i wykonywania skalowanego systemu DB wymagana będzie większa liczba wątków.

31
StanleyJohns

Jeśli mogę powiedzieć o MySQL, że InnoDB, jego transakcyjny silnik (zgodny z ACID), jest rzeczywiście wielowątkowy. Jest jednak tak wielowątkowy, jak TY JESTEŚ KONFIGUROWANY !!! Nawet natychmiast po wyjęciu z pudełka InnoDB działa świetnie w środowisku jednego procesora, biorąc pod uwagę jego ustawienia domyślne. Aby skorzystać z możliwości wielowątkowości InnoDB, należy pamiętać o aktywowaniu wielu opcji.

innodb_thread_concurrency ustawia górną granicę liczby współbieżnych wątków, które InnoDB może utrzymywać otwarte. Najlepsza zaokrąglona liczba do ustawienia to (2 x liczba procesorów) + liczba dysków. [~ # ~] aktualizacja [~ # ~] : Jak dowiedziałem się z pierwszej ręki podczas konferencji w Nowym Jorku w Percona, powinieneś ustawić tę wartość na 0, aby ostrzec InnoDB Storage Engine, aby znaleźć najlepszą liczbę wątków dla środowiska, w którym działa.

innodb_concurrency_tickets ustawia liczbę wątków, które mogą bezkarnie ominąć sprawdzanie współbieżności. Po osiągnięciu tego limitu sprawdzanie współbieżności wątków ponownie staje się normą.

innodb_commit_concurrency ustawia liczbę równoczesnych transakcji, które można zatwierdzić. Ponieważ wartością domyślną jest 0, brak ustawienia tej opcji umożliwia jednoczesne zatwierdzenie dowolnej liczby transakcji.

innodb_thread_sleep_delay ustawia liczbę milisekund, w których wątek InnoDB może być uśpiony przed ponownym wprowadzeniem kolejki InnoDB. Domyślnie jest to 10000 (10 sekund).

innodb_read_io_threads i innodb_write_io_threads (oba od czasu MySQL 5.1.38) przydzielają określoną liczbę wątków do odczytu i zapisu. Domyślnie jest to 4, a maksymalna to 64.

innodb_replication_delay nakłada opóźnienie wątku na urządzenie podrzędne, osiągnięto innodb_thread_concurrency.

innodb_read_ahead_threshold pozwala na liniowe odczyty ustawionej liczby zakresów (64 strony [strona = 16K]) przed przejściem na odczyt asynchroniczny.

Czas uciekłby mi, gdybym wymienił więcej opcji. Możesz o nich przeczytać w Dokumentacja MySQL .

Większość ludzi nie zdaje sobie sprawy z tych funkcji i jest całkiem zadowolona z tego, że InnoDB robi tylko transakcje zgodne z ACID. Jeśli poprawisz którąś z tych opcji, zrobisz to na własne ryzyko.

Grałem z MySQL 5.5 Multiple Buffer Pool Instances (162 GB w 9 instancjach puli buforów) i próbowałem w ten sposób automatycznie partycjonować dane w pamięci. Niektórzy eksperci twierdzą, że powinno to zapewnić 50% poprawę wydajności. Dostałem mnóstwo blokad wątków, które sprawiły, że InnoDB zaczęło się czołgać. Przełączyłem się na 1 bufor (162 GB) i wszystko znów było dobrze na świecie. Sądzę, że potrzebujesz ekspertów Percona, aby to ustawić. Jutro będę na konferencji Percona MySQL w Nowym Jorku i zapytam o to, czy nadarzy się okazja.

Podsumowując, InnoDB zachowuje się dobrze na serwerze z wieloma procesorami, biorąc pod uwagę jego domyślne ustawienia dla operacji wielowątkowych. Poprawianie ich wymaga wielkiej staranności, wielkiej cierpliwości, świetnej dokumentacji i wspaniałej kawy (lub Red Bulla, Jolta itp.).

Dzień dobry, dobry wieczór i dobranoc !!!

AKTUALIZACJA 27.05.2011 20:11

Wróciłem z Percona MySQL Conference in New York w czwartek. Co za konferencja. Wiele się nauczyłem, ale dostałem odpowiedź, na którą się przyjrzę, dotyczącą InnoDB. Zostałem poinformowany przez Ronald Bradford , że ustawienie innodb_thread_concurrency na 0 pozwoli InnoDB wybrać najlepszy sposób postępowania wewnętrznie z współbieżnością wątków. Będę eksperymentować z tym dalej w MySQL 5.5.

AKTUALIZACJA 2011-06-01 11:20

Jeśli chodzi o jedno długie zapytanie, InnoDB jest zgodny z ACID i działa bardzo dobrze, używając MultiVersion Concurrency Control . Transakcje powinny być w stanie przenosić poziomy izolacji (domyślnie powtarzalne odczyty), które zapobiegają blokowaniu dostępu do danych innym osobom.

Jeśli chodzi o systemy wielordzeniowe, InnoDB przeszedł długą drogę. W przeszłości InnoDB nie działało dobrze w środowisku wielordzeniowym. Pamiętam, że musiałem uruchamiać wiele instancji mysql na jednym serwerze, aby uzyskać wiele rdzeni do dystrybucji wielu procesów mysqld na procesory. Nie jest to już konieczne, dzięki Perconie, a później MySQL (eh, Oracle, mówiąc, że wciąż mnie to wymiotuje), ponieważ rozwinęli InnoDB w bardziej dojrzały silnik pamięci masowej, który może uzyskiwać dostęp do rdzeni w prosty sposób bez konieczności dostrajania. Obecna instancja InnoDB może dziś dobrze działać na serwerze z jednym rdzeniem.

49
RolandoMySQLDBA

Gdy tylko pojawi się wielu współbieżnych użytkowników lub procesów, a nawet pojedynczy proces z dostępem do wielowątkowej bazy danych, posiadanie bazy danych obsługującej wątkowanie stanie się potencjalnie interesujące.

H2 jest bezpieczny dla wątków, ale serializuje wszystkie żądania do bazy danych, co może stać się potencjalnym problemem z wydajnością w scenariuszu dużego obciążenia. To, czy tak naprawdę jest w przypadku konkretnego projektu, zależy od kombinacji wymagań dotyczących wydajności, liczby wątków/użytkowników/procesów uzyskujących dostęp do bazy danych, częstotliwości zapytań wykonywanych przez te wątki oraz średniej i najgorszej wydajności twojego zapytania.

Na przykład, jeśli wymagania dotyczące wydajności mają mieć odpowiedź w ciągu sekundy, nie ma więcej niż 10 równoczesnych użytkowników wykonujących pojedyncze zapytanie, którego wykonanie zajmuje 0,05 sekundy, jednowątkowa baza danych nadal pozwala osiągnąć te cele (choć wielowątkowy prawdopodobnie już dawałby zauważalny wzrost wydajności). Biorąc pod uwagę ten sam scenariusz z jednym potencjalnym zapytaniem o najgorszej wydajności trwającej pół sekundy, serializacja dostępu do bazy danych nie pozwoli już na osiągnięcie celów wydajnościowych.

Jeśli obecnie używasz H2 w swoim projekcie, radzę ci uruchomić profiler na bazie kodu w scenariuszu ładowania (po prostu uruchom x liczby wątków uderzających w twój kod jednocześnie przy użyciu typowych przypadków użycia). To da ci rzeczywiste wskaźniki dotyczące wydajności i wąskich gardeł w twojej bazie kodu, zamiast tylko teorii. Jeśli pokazuje to, że twoje żądania spędzają dużą część czasu na czekaniu na dostęp do bazy danych, czas przejść do bazy danych z wątkami.

11
Luke Hutteman

Z tego, co mogę powiedzieć, „jednowątkowy” jest trochę błędny dla H2. Chodzi o to, że serializuje wszystkie transakcje (tzn. Robi je pojedynczo).

Kluczowym pytaniem dotyczącym tego, czy jest to „w porządku” dla Twojej aplikacji, nie jest „Ilu użytkowników?” lub nawet „Ile procesów?”, ale „Jak długo potrwają moje transakcje?”

Jeśli wszystkie Twoje transakcje są w drugiej sekundzie, może to być w porządku, jeśli niektóre zajmą kilka godzin, może to nie być w porządku, ponieważ wszystkie inne oczekujące transakcje będą czekać na ich zakończenie. Decyzja o tym, czy jest to „w porządku”, czy nie, będzie zależeć od twoich własnych wymagań wydajnościowych - tj. Jak długo będzie akceptowalny czas oczekiwania na moich użytkowników uderzających w bazę danych z transakcjami.

--EDYTOWAĆ

Wygląda na to, że H2 tak naprawdę nie serializuje transakcji - tylko DML. Innymi słowy, wiele krótkich aktualizacji w ramach jednej długiej transakcji nie blokuje innych aktualizacji . Jeśli jednak nie używasz eksperymentalna funkcja MVCC , blokowanie tabeli oznacza, że ​​ma to podobny efekt w praktyce. Istnieje również eksperymentalna funkcja „wielowątkowy” , ale nie można jej używać jednocześnie z MVCC

Cytując fragmenty ze strony PostgreSQL ... Pamiętaj, że absolutnie nie mam pojęcia o zaletach tych argumentów - po prostu nie pasowały do ​​komentarza.

Od programisty FAQ („Dlaczego wątki nie są używane ...”):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

Wątki nie są obecnie używane zamiast wielu procesów dla backendów, ponieważ: (...)

  • Błąd w jednym backendie może uszkodzić inne backendy, jeśli są one wątkami w ramach jednego procesu
  • Poprawa prędkości za pomocą wątków jest niewielka w porównaniu do pozostałego czasu uruchamiania zaplecza.
  • Udostępnianie wykonywalnych mapowań tylko do odczytu i stosowanie buforów współdzielonych oznacza, że ​​procesy, takie jak wątki, są bardzo wydajne pod względem pamięci
  • Regularne tworzenie i niszczenie procesów pomaga chronić przed fragmentacją pamięci, co może być trudne do zarządzania w procesach długotrwałych

Z listy rzeczy do zrobienia („Funkcje, których nie chcemy”):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Wszystkie backendy działające jako wątki w jednym procesie (niepotrzebne)

Eliminuje to ochronę procesu uzyskaną z bieżącej konfiguracji. Tworzenie wątków ma zwykle taki sam narzut jak tworzenie procesów we współczesnych systemach, więc nie jest rozsądne stosowanie modelu czysto wątkowego, a MySQL i DB2 wykazały, że wątki wprowadzają tyle problemów, ile rozwiązują. (...)

Więc znowu ... Absolutnie nie mam pojęcia o zaletach powyższych. To było po prostu zbyt długie, aby zmieścić się w komentarzu.

5