Czy narzut związany z częstym unieważnianiem pamięci podręcznej zapytań jest kiedykolwiek tego wart?

22

Obecnie pracuję nad bazą danych MySQL, w której widzimy dużą liczbę unieważnień z pamięci podręcznej zapytań, głównie z powodu dużej liczby instrukcji INSERT, DELETE i UPDATE, które są wykonywane na wielu tabelach.

Próbuję ustalić, czy w ogóle istnieje korzyść z umożliwienia użycia pamięci podręcznej zapytań dla instrukcji SELECT uruchamianych z tymi tabelami. Ponieważ są one unieważniane tak szybko, wydaje mi się, że najlepszą rzeczą byłoby po prostu użycie SQL_NO_CACHE na instrukcjach SELECT z tymi tabelami.

Czy koszty związane z częstymi unieważnieniami są tego warte?

Edycja: na żądanie użytkownika @RolandoMySQLDBA poniżej, oto informacje o MyISAM i INNODB.

InnoDB

  • Rozmiar danych: 177,414 GB
  • Rozmiar indeksu: 114,792 GB
  • Rozmiar stołu: 292,205 GB

MyISAM

  • Rozmiar danych: 379,762 GB
  • Rozmiar indeksu: 80,681 GB
  • Rozmiar stołu: 460.443 GB

Dodatkowe informacje:

  • Wersja: 5.0.85
  • query_cache_limit: 1048576
  • query_cache_min_res_unit: 4096
  • query_cache_size: 104857600
  • query_cache_type: ON
  • query_cache_wlock_invalidate: OFF
  • innodb_buffer_pool_size: 8841592832
  • 24 GB pamięci RAM
Craig Sefton
źródło
2
dom.as/tech/query-cache-tuner całkiem ładnie podsumowuje
Laurynas Biveinis
Hehe, bardzo wnikliwy.
Craig Sefton,

Odpowiedzi:

16

Należy po prostu wyłączyć pamięć podręczną zapytań za pomocą

[mysqld]
query_cache_size = 0

a następnie uruchom ponownie mysql. Dlaczego miałbym to sugerować?

Pamięć podręczna zapytań zawsze będzie trafiać w InnoDB. Byłoby miło, gdyby MVCC InnoDB zezwalał na obsługę zapytań z pamięci podręcznej zapytań, jeśli modyfikacje nie wpływają na powtarzalne odczyty dla innych transakcji. Niestety InnoDB po prostu tego nie robi. Najwyraźniej masz wiele zapytań, które zostają unieważnione dość szybko i prawdopodobnie nie są ponownie używane.

W przypadku InnoDB w MySQL 4.0 pamięć podręczna zapytań została wyłączona dla transakcji. W MySQL 4.1+ InnoDB odtwarza ruch policjanta, gdy pozwala na dostęp do pamięci podręcznej zapytań dla poszczególnych tabel.

Z perspektywy twojego pytania powiedziałbym, że uzasadnienie usunięcia bufora zapytań nie jest tak dużym obciążeniem, ale tym, w jaki sposób InnoDB nim zarządza.

Więcej informacji na temat interakcji InnoDB z pamięcią podręczną zapytań znajduje się na stronach 213–215 książki „High Performance MySQL (Second Edition)” .

Jeśli wszystkie lub większość twoich danych to MyISAM, możesz skorzystać z oryginalnego pomysłu użycia SQL_NO_CACHE.

Jeśli masz połączenie InnoDB i MyISAM, będziesz musiał znaleźć odpowiednią równowagę dla swojej aplikacji na podstawie tego, jak wysokie są Twoje błędy w pamięci podręcznej. W rzeczywistości strony 209-210 tej samej książki wskazują przyczyny braków w pamięci podręcznej:

  • Kwerenda nie może być buforowana, ponieważ zawiera niedeterministyczną konstrukcję (taką jak CURRENT_DATE) lub ponieważ jej zestaw wyników jest zbyt duży, aby ją zapisać. Oba typy nieusuwalnych zapytań zwiększają zmienną statusu Qcache_not_cached.
  • Serwer nigdy wcześniej nie widział zapytania, więc nigdy nie miał szansy na buforowanie jego wyniku.
  • Wynik zapytania był wcześniej buforowany, ale serwer go usunął. Może się to zdarzyć, ponieważ nie ma wystarczającej ilości pamięci, aby ją zachować, ponieważ ktoś poinstruował serwer, aby ją usunąć lub ponieważ została unieważniona

a podstawowymi przyczynami dużych braków pamięci podręcznej z kilkoma nieczytelnymi zapytaniami mogą być:

  • Pamięć podręczna zapytań nie jest jeszcze ciepła. Oznacza to, że serwer nie miał okazji zapełnić pamięci podręcznej zestawami wyników.
  • Serwer widzi zapytania, których wcześniej nie widział. Jeśli nie masz wielu powtarzających się zapytań, może się to zdarzyć nawet po rozgrzaniu pamięci podręcznej.
  • Istnieje wiele unieważnień pamięci podręcznej.

AKTUALIZACJA 2012-09-06 10:10 EDT

Szukając najnowszych zaktualizowanych informacji, query_cache_limitustawiłeś 1048576 (1M). Ogranicza to każdy wynik ustawiony na 1M. Jeśli odzyskasz coś większego, po prostu nie będzie on buforowany. Chociaż query_cache_sizeustawiłeś 104857600 (100M), pozwala to tylko na 100 buforowanych wyników ustawionych w idealnym świecie. Jeśli wykonasz setki zapytań, fragmentacja nastąpi dość szybko. Masz również 4096 (4K) jako zestaw wyników minimalnego rozmiaru. Niestety, mysql nie ma wewnętrznego mechanizmu defragmentacji pamięci podręcznej zapytań.

Jeśli musisz mieć pamięć podręczną zapytań i masz dużo pamięci RAM, możesz wykonać następujące czynności:

SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;

w celu wyczyszczenia pamięci podręcznej zapytań. Tracisz wszystkie wyniki z pamięci podręcznej, więc uruchom te linie poza godzinami szczytu.

Przypisałbym również następujące:

  • query_cache_size = 1G
  • query_cache_limit = 8M

To pozostawia 23G pamięci RAM. Chciałbym podnieść następujące kwestie:

  • innodb_buffer_pool_size = 12G
  • key_buffer_size = 4G

To pozostawia 7G. Powinno to być odpowiednie dla połączeń OS i DB.

Należy pamiętać, że bufor buforowy buforuje tylko strony indeksowe MyISAM, natomiast pula buforów InnoDB buforuje dane i indeksy.

Jeszcze jedno zalecenie: uaktualnij do MySQL 5.5, abyś mógł skonfigurować InnoDB dla wielu procesorów i wielu wątków dla odczytu / zapisu we / wy.

Zobacz moje wcześniejsze posty na temat używania MySQL 5.5 w połączeniu z dostępem do wielu procesorów dla InnoDB

AKTUALIZACJA 2012-09-06 14:56 EDT

Moja metoda czyszczenia pamięci podręcznej zapytań jest dość ekstremalna, ponieważ łączy buforowane dane i tworzy zupełnie inny segment pamięci RAM. Jak zauważyłeś w swoim komentarzu FLUSH QUERY CACHE(jak sugerowałeś), a nawet RESET QUERY CACHEbyłoby lepiej. Dla wyjaśnienia, kiedy powiedziałem „brak mechanizmu wewnętrznego”, miałem na myśli dokładnie to. Defragmentacja jest konieczna i musi zostać wykonana ręcznie. Musiałby to być crontabbed .

Jeśli wykonujesz DML (INSERT, UPDATE, DELETE) częściej na InnoDB niż na MyISAM, powiedziałbym, że całkowicie usuwam pamięć podręczną zapytań, co powiedziałem na początku.

RolandoMySQLDBA
źródło
Dzięki za odpowiedzi. Mam tę książkę i intensywnie z niej korzystam; doskonale zdaję sobie sprawę z powodów, dla których zarysowałeś brak pamięci podręcznej, ale jak wspomniałem, już zidentyfikowaliśmy unieważnienie pamięci podręcznej jako kluczowy problem ze względu na silną korelację między Com_select a Qcache_inserts. Aha, a baza danych zawiera mieszankę INNODB i MyISAM.
Craig Sefton,
Zaktualizowano o dodatkowe informacje, o które prosiłeś. Dzięki.
Craig Sefton,
Dzięki za odpowiedź, czekam na resztę. Jedną z rzeczy, które zidentyfikowaliśmy, było to, że około 18% zapytań nie było buforowanych, więc zdecydowanie doceń porady dotyczące ustawień. Niestety pudełko nie jest dedykowane, ale twoje rekomendacje powinny pomóc. Fragmentacja jest również zdecydowanie problemem. Nadal jestem bardzo zaniepokojony liczbą obserwowanych unieważnień (w przeciwieństwie do zapytań, które w ogóle nie są buforowane), więc nadal nie jestem pewien, czy koszty ogólne są tego warte. Naprawdę doceniam twój wgląd, dziękuję bardzo.
Craig Sefton,
Jeśli chodzi o komentarz na temat „mysql nie ma wewnętrznego mechanizmu defragmentacji pamięci podręcznej zapytań”, czy nie możesz wykonać polecenia, FLUSH QUERY CACHEaby go zdefragmentować? Zobacz: dev.mysql.com/doc/refman/5.0/en/flush.html
Craig Sefton
Zaktualizowałem moją odpowiedź ...
RolandoMySQLDBA
3

ZŁE: rozmiar_pamięci_cache = 1G

Czemu? Ze względu na to, jak długo potrwa kolor. Oznacza to, że gdy nastąpi zapis, cały 1 GB zostanie przeskanowany w celu znalezienia odniesień do zmodyfikowanej tabeli. Im większa QC, tym wolniej. Zalecam rozmiar nie większy niż 50 mln, chyba że Twoje dane rzadko się zmieniają.

Kontrola jakości jest narzutem zarówno dla MyISAM, jak i InnoDB. Wyciąga globalny Mutex i usuwa go zbyt wcześnie. Ten muteks jest jednym z powodów, dla których MySQL nie może efektywnie wykorzystywać więcej niż około 8 rdzeni.

SQL_NO_CACHE nie zauważyłem aż po mutex jest zablokowany! Jedynym zastosowaniem tej flagi jest analiza porównawcza.

Często lepiej jest przekazać pamięć RAM innej pamięci podręcznej.

Rick James
źródło
2

Mogę wymyślić idealny przypadek, a my dokładnie go przetestowaliśmy i uruchomiliśmy w produkcji ... Nazywam to strategią grupowania „szybkich pasów” :

Jeśli wykonujesz dzielenie odczytu i zapisu za pomocą proxy, takiego jak MaxScale, lub Twoja aplikacja jest w stanie, możesz wysłać część odczytów dla tych rzadko unieważnionych tabel tylko do urządzeń podrzędnych z włączoną pamięcią podręczną zapytań, a resztę do innych urządzeń podrzędnych z tym wyłączony.

Robimy to i w rezultacie obsługujemy połączenia 4M na minutę do klastra podczas naszych testów obciążenia (nie benchmark ... prawdziwa okazja). Aplikacja czeka na master_pos_wait () na pewne rzeczy, więc jest dławiona przez wątek replikacji i chociaż widzieliśmy, że ma status oczekiwania na unieważnienie Qcache przy bardzo dużej przepustowości, te poziomy przepustowości są wyższe niż nawet klaster zdolny do bez Qcache.

Działa to, ponieważ rzadko w pamięci podręcznej zapytań na tych komputerach rzadko można coś unieważnić (zapytania te dotyczą tylko rzadko aktualizowanych tabel). Te pola to nasz „szybki pas”. W przypadku pozostałych zapytań wykonywanych przez aplikację nie muszą one konkurować z Qcache, ponieważ przechodzą do skrzynek bez włączonej obsługi.

Christopher McGowan
źródło