Wyjaśniam, w jaki sposób zachowanie pamięci podręcznej zapytań mysql w nowoczesnych środowiskach hostingowych, dlaczego MySQL 8.0 zlikwidował wewnętrzny cache zapytań i jak mogę stać się zauważalnie szybszy dzięki Redis lub Memcached. Pokażę ci jasne dźwignie dla Buforowanie zapytań, walidacja pamięci podręcznej, monitorowanie i sprzęt, dzięki którym strony internetowe częściej dostarczają dane z pamięci podręcznej, a bazy danych działają mniej.
Punkty centralne
- MySQL 8.0Usunięto wewnętrzną pamięć podręczną zapytań, przejęto zewnętrzne pamięci podręczne.
- W pamięciSzybki odczyt danych z pamięci RAM.
- UnieważnienieTTL, zdarzenia i wersjonowanie nieaktualnych danych.
- MonitoringDostrajanie współczynnika trafień, opóźnień i kontroli eksmisji.
- 300%Prawidłowe buforowanie zmniejsza obciążenie i zwiększa wydajność.
Krótkie wyjaśnienie zachowania pamięci podręcznej zapytań w hostingu
Kiedy przychodzą żądania, najpierw sprawdzam, czy wynik jest już w pliku Schowek jest zlokalizowany. Jeśli tam jest, odpowiadam bez dostępu do bazy danych i oszczędzam opóźnienia i czas procesora na Serwer bazy danych. Jeśli brakuje wpisu, tworzę wynik, zapisuję go w pamięci podręcznej i dostarczam tak, aby następne trafienie było szybsze i aby Czas ładowania strony zmniejsza się. W ten sposób zmniejszam liczbę identycznych zapytań i zmniejszam obciążenie serwera w przypadku powtarzających się dostępów do Popularna zawartość. W konfiguracjach hostingu z wieloma podobnymi żądaniami (strona startowa, listy produktów, struktury menu), zachowanie pamięci podręcznej zapytań przynosi znaczące korzyści. Przyspieszenie.
Od MySQL Query Cache do Redis/Memcached: nowoczesny sposób
Stara pamięć podręczna zapytań MySQL spowalniała wiele operacji zapisu, więc MySQL 8.0 usunął tę funkcję. Funkcja. Zamiast tego polegam na Redis lub Memcached, ponieważ pozwalają mi one korzystać z pamięci podręcznych niezależnie od Baza danych i może używać kluczy granularnych, TTL i strategii eksmisji. To znacznie zmniejsza obciążenie MySQL, ponieważ żądania odczytu trafiają do Pamięć podręczna w pamięci, podczas gdy MySQL koncentruje się na rzeczywistych transakcjach. Celowo utrzymuję małe klucze pamięci podręcznej, wersjonuję je po wprowadzeniu zmian, a tym samym zapewniam wysoki poziom bezpieczeństwa. Współczynnik trafień. Podejście to zapewnia spójne reakcje przy wysokim wykorzystaniu i skalowaniu na wielu płaszczyznach. Pracownik lub pojemniki.
Dlaczego tak naprawdę usunięto wewnętrzną pamięć podręczną zapytań? Blokował on wysoce zrównoleglone systemy poprzez globalne blokady, często unieważniał kompletne obszary tabel po wprowadzeniu zmian i powodował duży narzut administracyjny przy mieszanych obciążeniach odczytu/zapisu. Rezultat: im więcej dostępów do zapisu, tym mniejsza korzyść - aż do hamulca sieciowego. Nowoczesne pamięci podręczne są zatem zlokalizowane poza MySQL, używają izolowanych TTL na klucz, umożliwiają skalowanie poziome i mogą być wdrażane niezależnie. Sam MySQL nadal korzysta z puli buforów InnoDB, dobrych indeksów i przygotowanych instrukcji - ale buforowanie wyników pozostaje zadaniem poziomu aplikacji.
Zrozumienie poziomów pamięci podręcznej: w pamięci, baza danych, aplikacja
Rozróżniam trzy poziomy, aby Buforowanie cache związany z aplikacją (Redis/Memcached), cache związany z bazą danych (np. pula buforów) oraz cache HTTP/reverse proxy. W pobliżu aplikacji cache'uję kompletne wyniki zapytań lub renderowane strony. Fragmenty, który oferuje największą elastyczność. W pobliżu bazy danych korzystam ze zoptymalizowanych indeksów i InnoDB Buffer Pool, który przechowuje często odczytywane strony w folderze RAM trzyma. Na poziomie HTTP minimalizuję dynamiczne wywołania, gdy zawartość jest naprawdę statyczny są. Oferuję szybki przegląd taktyk w kompakcie Przewodnik po strategiach buforowania, co ułatwia odpowiednie wykorzystanie w zależności od scenariusza aplikacji.
Porównanie wzorców buforowania
Wybieram wzór w zależności od ryzyka, częstotliwości zmian i potrzeby spójności:
- Cache-Aside (leniwe ładowanie): Aplikacja sprawdza cache, ładuje z DB przy braku, zapisuje do cache. Proste, elastyczne, o niskim sprzężeniu - ale podatne na stemplowanie po wygaśnięciu TTL.
- Do odczytuWarstwa pamięci podręcznej ładuje się automatycznie ze źródła danych. Jednolite zachowanie, ale dodatkowa złożoność w warstwie pośredniej.
- Zapis bezpośredniPrzy każdym zapisie dane są najpierw przenoszone do pamięci podręcznej, a następnie do bazy danych. Bardzo spójne, ale ścieżka zapisu jest dłuższa.
- Write-BehindPamięć podręczna akceptuje operacje zapisu i przepływa asynchronicznie do bazy danych. Szybki, ale trudny w przypadku awarii; używać tylko z wyraźnymi gwarancjami.
- Stale-While-RevalidateWygasłe wpisy mogą zostać na chwilę zwrócone jako „stare“, podczas gdy zadanie w tle wypełnia nowe wpisy. Idealne rozwiązanie w przypadku szczytów obciążenia.
Walidacja pamięci podręcznej bez błędów danych
Zaplanowałem unieważnianie pamięci podręcznej w taki sposób, aby bieżące dane zawsze miały priorytet, a Prędkość pozostaje. Ustawiłem czas życia (TTL) na tyle krótki, aby zmiany były widoczne szybko, ale na tyle długi, aby Wskaźnik trafień pozostaje wysoki. Podczas operacji zapisu, usuwam określone klucze (write-through/write-behind) lub zwiększam wartość Wersja w przestrzeni nazw klucza, aby kolejne dostępy pobierały świeży zestaw danych. W przypadku wrażliwych treści (ceny, akcje, konta) używam krótszych formatów TTL lub natychmiastowe unieważnienie po aktualizacji. Zapobiega to nieaktualnym odpowiedziom i utrzymuje spójność danych w rozproszonych centrach danych. Systemy.
Zapobieganie "cache stampede": stale-while-revalidate, blokady i jitter
Aby uniknąć problemu „dogpile problem“, używam połączonych mechanizmów: a Soft TTL, co pozwala na kilka sekund „nieświeżości“, podczas gdy pracownik pojedynczego lotu aktualizuje obiekt; krótkie Mutex (np. przez Redis SET NX + TTL), dzięki czemu przeładowywany jest tylko jeden proces; oraz Jitter do TTL (losowe odchylenie), aby tysiące kluczy nie wygasły w tym samym czasie. W przypadku błędów w oryginalnym źródle zezwalam na stale-if-error i chronić bazę danych przed lawinami.
Rozmiar, TTL i eksmisja: odpowiednie śruby regulacyjne
Wybieram rozmiar pamięci podręcznej, aby dopasować go do ilości danych, co jest warte zachodu. RAM kłamać. Zbyt małe wartości zwiększają liczbę chybień, zbyt duże marnują pamięć, więc stale mierzę i reaguję na Szczyty obciążenia. W przypadku eksmisji wolę używać LRU, jeśli wzorce dostępu są cykliczne, i przełączać się na LFU w przypadku wyraźnych wzorców dostępu. Długoterminowi faworyci. Utrzymuję zróżnicowane TTL: statyczna nawigacja dłużej, dynamiczna dostępność produktu krótszy. Poniższa tabela przedstawia typowe wartości początkowe, które następnie udoskonalam za pomocą monitorowania i dostosowuję do rzeczywistych wartości. Użyj dostosuj.
| Parametry | Cel | wartość początkowa | Mierzona zmienna |
|---|---|---|---|
| Rozmiar pamięci podręcznej | Budżet pamięci RAM dla pamięci podręcznej zapytań lub fragmentów | 5-15% pamięci RAM serwera | Eksmisje/minutę, wykorzystanie pamięci RAM |
| TTL statyczne | Menu, strony kategorii, częste listy | 300-1800 sekund | Współczynnik trafień, potrzeba aktualności |
| Dynamika TTL | Ceny, zapasy, personalizacja | 10-120 sekund | Współczynnik błędów, korekty |
| Eksmisja | LRU/LFU/FIFO na wzorzec dostępu | LRU w standardzie | Współczynnik nieodebranych połączeń, powtarzające się dostępy |
| Kluczowy schemat | Wersjonowanie nieaktualnych danych | user:v1:queryhash | Brakujące trafienie po wdrożeniu |
Biorę również pod uwagę rozkłady wielkości obiektów i górne limity. Na przykład kompresuję pojedyncze obiekty powyżej 512 KB lub dzielę je na strony (stronicowanie), aby eksmisje nie wypierały całych megabajtowych bloków. Różne pamięci podręczne (np. „gorące“ i „zimne“) o oddzielnych rozmiarach zapobiegają wypieraniu przez kilka dużych obiektów wielu małych, często odczytywanych wpisów.
Projekt klucza i normalizacja
Dobre klucze określają współczynnik trafień i zdolność unieważniania. Normalizuję parametry zapytań (sortowanie, wielkie/małe litery, wartości domyślne), konwertuję listy do porządku kanonicznego i haszuję długie parametry do pliku Skrót zapytania, dzięki czemu klucze pozostają krótkie. Czysto oddzielam fasety w kluczu: site:v3:en-EN:category:42:page:2:filter:abc123. Personalizacja, klient, waluta, ustawienia regionalne i kategoria urządzenia należą w widoczny sposób do przestrzeni nazw. Określam parametry liczbowe (np. zaokrąglam filtry cen do znaczących przedziałów), aby uniknąć duplikatów. Negatywne pamięci podręczne (np. „brak trafienia“) z bardzo krótkim TTL redukują dostęp do bazy danych dla powtarzających się trafień. Panna-Szukaj.
Prawidłowy wybór serializacji i kompresji
Wybieram formaty w zależności od interfejsu i budżetu procesora: JSON jest uniwersalny i czytelny, MessagePack lub Protobuf oszczędność pamięci RAM/przepustowości. Dla dużych obiektów używam LZ4 lub Snappy do szybkiej kompresji; Gzip tylko wtedy, gdy maksymalny rozmiar jest ważniejszy niż procesor. Jeden Próg (np. od 4 do 8 KB) zapobiega niepotrzebnej kompresji małych danych. Zwracam uwagę na stabilne schematy: jeśli dodaję pola, zwiększam wartość Kluczowa wersja, aby stare parsery nie ulegały uszkodzeniu.
Redis kontra memcached: Różnice w działaniu
Memcached Dzięki prostej architekturze, wielowątkowości i Płyty dla wydajnej alokacji. Jest to pierwszy wybór dla bardzo prostych wyników klucz/wartość z bardzo wysokim QPS bez potrzeby trwałości. Redis oferuje struktury danych (hashe, zestawy, posortowane zestawy), precyzyjną kontrolę TTL, replikację i możliwość tworzenia klastrów. Redis jest idealny do list, tablic wyników, liczników i pub/sub. Jako czysta pamięć podręczna wyników, dezaktywuję trwałość (lub ustawiam rzadkie migawki), aby zaoszczędzić I / O. Używam Rurociąg oraz MGET, aby zmniejszyć liczbę podróży w obie strony i wybrać politykę eksmisji pasującą do wzorca dostępu (allkeys-lfu dla czystych, stałych klawiszy skrótu, volatile-lru dla ścisłego wykorzystania TTL). Dystrybuuję klucze skrótu za pośrednictwem shardingu/klastrów lub celowo replikuję je kilka razy, aby złagodzić wąskie gardła.
Monitorowanie i dostrajanie podczas pracy
Obserwuję Wskaźnik trafień, opóźnienia na operację w pamięci podręcznej i współczynnik eksmisji w celu rozpoznania wąskich gardeł. Jeśli opóźnienie wzrasta, sprawdzam ścieżki sieciowe, nasycenie procesora i wydajność pamięci podręcznej. serializacja obiektów. Zmniejszam duże obiekty, kompresując je lub dzieląc na mniejsze w celu Pamięć aby lepiej go wykorzystać. Jeśli współczynnik trafień spada, identyfikuję brakujące klawisze i dostosowuję TTL lub Kluczowe schematy na. Dostrajanie pozostaje cyklem pomiarów, stawiania hipotez, dostosowywania, a następnie Pomiar.
Konkretne kluczowe liczby pomagają analizować przyczyny: keyspace_hits/misses, evicted_keys, odzyskany (Memcached), used_memory oraz RSS-odchylenia dla fragmentacji, opóźnienia P99 na polecenie, stopy błędów sieciowych i Slowlog-wpisy. Zwracam uwagę na ciągłe, nieskokowe eksmisje, równomiernie rozłożone rozmiary obiektów i odsetek „nieświeżych serwerów“. Jeśli miss→db→set występuje częściej niż planowano, albo TTL nie jest prawidłowe, albo klucze są zbyt zróżnicowane (brak normalizacji).
Bezpieczeństwo i wysoka dostępność
Nigdy nie ujawniam publicznie serwerów pamięci podręcznej, ale wiążę je z wewnętrznymi interfejsami/VPC, aktywuję ACL i jeśli to możliwe TLS. Ściśle oddzielam środowiska produkcyjne, przejściowe i testowe, aby żadne klucze nie kolidowały i żadne dane nie migrowały. Blokuję krytyczne operacje (FLUSH*) poprzez autoryzacje. Dla Przełączanie awaryjne Używam replikacji i, w zależności od technologii, automatycznego przełączania (np. watchdog/sentinel/klaster). Jako czysta pamięć podręczna wyników, trwałość jest używana tylko oszczędnie lub wcale - jeśli pamięć podręczna zawiedzie, aplikacja może być tylko wolniejsza, ale poprawna. Ograniczam polecenia, które skanują całe przestrzenie kluczy i planuję kopie zapasowe tylko tam, gdzie używana jest również pamięć podręczna. Źródło prawdy jest (co rzadko się zdarza).
WordPress i e-commerce: typowe wzorce i pułapki
W przypadku WordPressa buforuję struktury menu, wyniki zapytań z WP_Query i ważne Widgety, podczas gdy wykluczam spersonalizowane części. Upewniam się, że wtyczki nie blokują każdego żądania. Obejście, ustawiając sesje lub stale zmieniając pliki cookie. W przypadku systemów sklepowych buforuję strony kategorii, listy bestsellerów i filtruję wyniki za pomocą krótkich plików cookie. TTL, podczas gdy koszyki zakupowe i strony kont pozostają dynamiczne. Ci, którzy polegają na starej pamięci podręcznej zapytań, często pogarszają Wydajność; Wyjaśniam tutaj, dlaczego tak jest: WordPress Query Cache. W ten sposób utrzymuję równowagę między szybkością i poprawnością Personalizacja.
Różnię się także skrytkami w odpowiednich miejscach: Waluta, Język, Lokalizacja oraz Grupa klientów wpływają na ceny, dostępność i zawartość. Oddzielam personalizację od reszty: strona pochodzi z pamięci podręcznej, tylko małe bloki (np. liczba koszyków) są dynamicznie przeładowywane. W przypadku wysoce zmiennych filtrów (faset) normalizuję sekwencję i tworzę klucze strony (page=1,2,...) zamiast generować ogromne, mylące klucze. I upewniam się, że odpowiedzi „Brak wyniku“ są buforowane przez krótki czas, aby ograniczyć skanowanie bazy danych.
Planowanie wydajności i model kosztów
Z góry wykonuję przybliżone obliczenia: średni rozmiar obiektu × oczekiwana liczba kluczy + narzut (10-30%) daje Baza RAM. Przykład: 80 000 obiektów à 6 KB plus 25% narzutu ≈ 600 MB. Planuję bufory pod kątem wzrostu (np. 30-50%). Po stronie przepustowości szacuję współczynnik odczytu/zapisu, celWskaźnik trafień (70-95%) i wynikające z tego zmniejszenie obciążenia bazy danych. Jeśli 60% poprzednich odczytów z bazy danych jest obsługiwanych z pamięci podręcznej, zmniejsza się nie tylko obciążenie procesora i IOPS, ale często także obciążenie bazy danych. Replikacja-Opóźnienia. Wyceniam scenariusze: Droższa pamięć RAM, oszczędność rdzeni DB - zazwyczaj inwestycja w pamięć RAM znacznie wygrywa, ponieważ zapewnia bardziej spójne czasy odpowiedzi.
Pula buforowa InnoDB, plan zapytań i indeksy razem
Nie optymalizuję w izolacji, ale patrzę na pamięć podręczną, Pula buforowa, plan zapytań i indeksy jako pakiet. Dobrze zwymiarowana pula buforów zwiększa liczbę trafień InnoDB, zmniejsza liczbę operacji we/wy i wzmacnia każdą z nich. Schowek o tym. Sprawdzam powolne zapytania, tworzę brakujące indeksy i utrzymuję świeże statystyki, aby optymalizator uzyskiwał najlepsze wyniki. Plan wybiera. Więcej szczegółowych informacji można znaleźć tutaj Optymalizacja puli buforów, którego używam równolegle z buforowaniem. To przekłada się na szybkość: mniej operacji we/wy, więcej trafień w pamięci RAM i bardziej wydajne buforowanie. Zapytania.
W praktyce oznacza to, że wymiaruję pulę buforów tak, aby „gorące“ strony danych mieściły się w niej bez głodzenia systemu operacyjnego. Profile zapytań ujawniają, czy pełne skanowanie tabel, nieoptymalne JOIN lub brakujące indeksy pokrycia osłabiają pamięć podręczną. Sprawdzam, czy SELECT, które są zbyt szerokie (niepotrzebne kolumny) generują duże obiekty pamięci podręcznej i odchudzam je. Jeśli zapytania znacznie się różnią, normalizuję parametry w aplikacji lub redukuję je do kilku wariantów wielokrotnego użytku.
Prawidłowe korzystanie z zasobów sprzętowych
Zarezerwowałem wystarczającą ilość pamięci RAM dla Redis/Memcached i InnoDB Bufor aby dyski twarde prawie się nie blokowały. Zwracam uwagę na rdzenie procesora, aby aplikacja i serwer pamięci podręcznej mogły działać jednocześnie. praca może. Dyski SSD NVMe zmniejszają opóźnienia szczątkowe, jeśli brak pamięci podręcznej stanie się problemem. Pamięć zaczyna działać. Opóźnienie sieciowe pozostaje ważne, dlatego umieszczam serwery pamięci podręcznej w pobliżu App lub na tym samym hoście. Decyzje te często pozwalają zaoszczędzić koszty hostingu w euro, ponieważ przy mniejszej liczbie rdzeni i niższej Obciążenie osiągnąć ten sam czas reakcji.
Zwracam również uwagę na topologie NUMA i gniazd, w razie potrzeby przypinam procesy do rdzeni i używam krótkich ścieżek sieciowych (lub gniazd uniksowych na tym samym hoście). W przypadku konfiguracji kontenerowych planuję „gwarantowane“ zasoby, aby pamięć podręczna nie była dławiona i zapewniała zapas na szczytowe obciążenia. Jeśli hot keys są nieuniknione, rozkładam ruch na wiele replik lub kieruję go do najbardziej lokalnej pamięci podręcznej, aby uniknąć opóźnień międzystrefowych.
Wdrożenie, testy i rozgrzewanie pamięci podręcznej
Testuję zmiany buforowania za pomocą profili obciążenia, które odzwierciedlają rzeczywiste dane użytkowania. W produkcji wdrażam je etapami (Canary), obserwuję współczynnik trafień, opóźnienia i obciążenie bazy danych, a dopiero potem zwiększam TTL. W przypadku wdrożeń zwiększam Kluczowa wersja i rozgrzać najważniejsze n-klawiszy (strona główna, bestsellery, ważne kategorie). Zadania w tle wypełniają strony listy i szczegółów w sposób ukierunkowany, tak aby pierwsi użytkownicy nie ponosili kosztów rozgrzewki. Symuluję eksmisje (środowisko testowe) i obciążam gorące ścieżki, aby zweryfikować ochronę stampede i jitter.
Plan krok po kroku dla lepszej wydajności hostingu
Zaczynam od inwentaryzacji: powoli Zapytania, pliki dziennika, współczynnik trafień, eksmisje i profile CPU/RAM. Następnie definiuję klucze pamięci podręcznej dla najważniejszych stron i tworzę TTL które równoważą terminowość i szybkość. Włączam zapisywanie lub unieważnianie oparte na zdarzeniach dla zmian, tak aby Spójność pozostaje. Następnie ponownie mierzę, zwiększam lub zmniejszam TTL, dostosowuję rozmiar pamięci podręcznej i usuwam Wartości odstające z dużymi obiektami. Na koniec wyostrzam pulę buforów, indeksy i plany, aż dostarczanie stron stanie się zauważalne. płyn biegnie.
Krótkie podsumowanie
Zastąpiłem starą pamięć podręczną zapytań MySQL Redis lub Memcached, świadomie kontrolować klucze, TTL i eksmisje oraz utrzymywać niezawodność danych z wyraźnym unieważnieniem. W zależności od aplikacji, osiągam 200-300% Prędkość, zwłaszcza, gdy napływa wiele identycznych żądań. Monitorowanie kieruje moimi decyzjami: Jeśli współczynnik trafień spada lub opóźnienie wzrasta, dostosowuję rozmiar, TTL i czas oczekiwania. klucz na. W połączeniu z silną pulą buforów InnoDB i czystymi indeksami, platforma skaluje się lepiej i jest bardzo responsywna. szybki. Jeśli zrozumiesz zachowanie pamięci podręcznej zapytań mysql jako kompletnego systemu, zmniejszysz obciążenie serwera, obniżysz koszty w euro i zapewnisz użytkownikom wyraźny efekt. Doświadczenie użytkownika.


