Wysoka wydajność MySQL dla wielu SELECTs / INSERTs / UPDATEs / DELETEs

9

Tworzę moduł, w którym każdy użytkownik często zapisuje tabelę na 10 do 300 sekund.

Po upływie czasu rekord zostanie usunięty. Chodzi o to, że będzie wielu użytkowników, a rekordy będą się bardzo często zmieniać - jak wpłynie to na wydajność aplikacji dla tej tabeli, ponieważ rekordy będą się zmieniać bardzo często i zastanawiam się, czy mysql jest w porządku? Podobnie jak indeksy przychodzą i odchodzą, dane zmieniają się dla tej konkretnej tabeli jak 200 razy / sekundę. Może wybieram złe rozwiązanie dla tego rodzaju pracy. Jakieś sugestie ?

Dziękuję Ci!

Aivaras
źródło
2
Czy próbowałeś przechowywać dane w memcache, a następnie czyścisz je w jednej transakcji co kilka sekund?
3
„dane zmieniają się jak 200 razy / sekundę dla tej konkretnej tabeli”. Myślę, że linia określa, że ​​dane powinny być przechowywane w pamięci, a okres, przez jaki musi trwać, jest niewielki, więc prawdopodobnie nie powinien przejść na dysk?
Indeksy przychodzą i odchodzą? Nie mogę wymyślić żadnego powodu, dla którego trzeba często tworzyć i upuszczać indeksy.
Barry Brown

Odpowiedzi:

3

Jedną z rzeczy, które należy wziąć pod uwagę, jest sposób, w jaki MySQL używa buforów dla swoich głównych silników pamięci: InnoDB i MyISAM .

To, co leży w pamięci podręcznej, różni się znacznie między tymi silnikami pamięci.

InnoDB buforuje zarówno dane, jak i strony indeksowe. Są one ładowane do puli buforów InnoDB, której rozmiar jest określony przez innodb_buffer_pool_size .

MyISAM buforuje tylko strony indeksowe i są one ładowane do Key Cache (Key Buffer), który jest sortowany według key_buffer_size .

Musisz użyć pliku information_schema.tables, aby zająć rozmiary danych i indeksów na dysku w celu prawidłowego rozmiaru puli buforów InnoDB i bufora kluczy MyISAM .

W zależności od tego, ile masz danych i ile czasu na to pozwolisz, możesz ogrzać pamięć podręczną w następujący sposób:

Dla każdego stołu TableT

  • Przejdź do każdego indeksu NDX
  • dla każdego indeksu NDX
    • uruchom WYBIERZ każdą kolumnę w NDX, przynajmniej jedną kolumnę nie zindeksowaną w TableT z TableT

W ten sposób gwarantujesz, że każda strona danych i indeksu zostanie przeczytana co najmniej raz. Usiądą w skrytce. Ta koncepcja jest praktykowana, częściowo i zasadniczo, przez Perconę . Percona wbudowała tę koncepcję w mk-slave-prefetch . To, co robi ten program, to

  • odczyt przekaźników loguje się do slave'a przed przetwarzaniem w nim SQL-a
  • pobierz instrukcję SQL z dziennika przekazywania i przekonwertuj ją na WYBÓR, korzystając z klauzul WHERE, GROUP BY i ORDER BY jako przewodnika wyboru indeksów
  • wykonaj instrukcję SELECT, która pochodzi z przekonwertowanego SQL

To zmusza slave do posiadania 99,99% danych potrzebnych przez slave do szybkiego przetwarzania SQL. To sprawia, że ​​niewolnik jest przygotowany na wypadek, gdybyś ręcznie przeszedł w tryb failover do niewolnika i wypromował go do mistrza, KTÓRYCH DACHÓW SĄ TYLKO O TYM SAMYM JAKU MASTER, OD KTÓREGO NIE SPADŁEŚ.

WNIOSEK

Nic nie przebije gotowych, chętnych i zdolnych do użycia pamięci podręcznych w środowisku intensywnych WSTAWEK, AKTUALIZACJI i USUŃ.

Spróbuj !!!

CAVEAT

Wraz z narodzinami produktów takich jak memcached, niektórzy z nich uniknęli konieczności odpowiedniego strojenia MySQL. To prawda, że ​​wiele witryn korzysta ze zwiększenia pobierania danych dzięki kontrolowaniu zachowania danych w pamięci podręcznej, co programiści szybko zauważyli dzięki memcached. Wiele innych witryn, po prostu zmieniając silniki pamięci masowej lub poprawnie konfigurując MySQL, uzyskało te same korzyści w zakresie wydajności. Przed rezygnacją z bazy danych i ścisłym użyciem jej jako repozytorium, najlepiej wykorzystaj bazę danych. Postępuj zgodnie z należytą starannością, a możesz być mile zaskoczony, co MySQL zrobi dla Ciebie.

RolandoMySQLDBA
źródło
5

Jeśli to złe rozwiązanie, zależy od wielu rzeczy. Czy te dane muszą być trwałe? W przeciwnym razie może lepiej działać rozwiązanie, które po prostu utrzymuje te dane w pamięci.

„Wielu użytkowników” tak naprawdę nikomu nie pomaga. MySQL najprawdopodobniej będzie w porządku, jeśli „dużo” oznaczałoby kilkaset. (Chociaż w zależności od tego, co jeszcze musi obsługiwać baza danych. Najprawdopodobniej kilka tysięcy powinno również działać.)

W końcu nie ma to większego znaczenia, jeśli zapiszesz te rekordy, aby je zatrzymać lub usuniesz po kilku sekundach lub minutach. Usunięcie powoduje tylko wykonanie dwóch operacji z jednej. A MySQL z pewnością poradzi sobie z bardzo dużą ilością tworzenia i usuwania rekordów. Upewnij się, że używasz prostego indeksu, aby ponownie znaleźć te rekordy do usunięcia.

Ale bez faktycznych liczb i niektórych informacji o sprzęcie używanym przez serwer bazy danych nie można odpowiedzieć z dużą precyzją.

Najlepszą rzeczą byłoby napisanie małej aplikacji, która po prostu symuluje obciążenie, które według ciebie uzyskasz, bez wykonywania prawdziwego przetwarzania, po prostu upuść wiele rekordów na serwerze, usuń je, w tym samym tempie uruchom niektóre zapytania, takie jak reszta twojego programu wygeneruje. Spójrz na swój serwer i sprawdź, czy to wpływa na to w jakikolwiek sposób.

Nie jestem pewien, ale dla MySQL są ustawione opcje, które pozwoliłyby mu całkowicie buforować tabelę w pamięci. I tak dzieje się w wielu sytuacjach i najprawdopodobniej nie będziesz musiał wiele zmieniać. Ale jeśli mówisz o naprawdę bardzo dużej liczbie użytkowników i rekordów, możesz dostosować kilka parametrów, aby zoptymalizować buforowanie dla twoich specjalnych potrzeb.

Thorsten Müller
źródło
4
+1 za sugerowanie rozwiązania, które utrzymuje dane w pamięci.
3

Oto szalony pomysł. Wymaga to założeń i nie zawsze zalecanych praktyk (takich jak aktualizacja klucza) - otrzymam wiele negatywnych sugestii, ale proszę bardzo ...

Zakładając, że masz bardzo dużą liczbę wierszy i dużą liczbę operacji usuwania, możesz zwiększyć wydajność usuwania, tworząc 2 partycje na stole. Partycje różnią się pierwszą cyfrą klucza. Przykład:

Wartość klucza 1123234441 dotyczy aktywnych wierszy, a wartość klucza: 9123234441 dotyczy nieaktywnych wierszy (pierwsza cyfra w tym przykładzie jest używana następująco: 1 = aktywna, 9 = nieaktywna).

Teraz, gdy użytkownik usuwa wiersz, nie usuwasz go fizycznie, aktualizujesz klucz (Ouch!), To automatycznie przenosi wiersz na nieaktywną partycję wierszy.

Oczywiście musisz ograniczyć wybrane opcje do odczytu danych tylko z aktywnej partycji. Fajne jest to, że upuszczanie nieaktywnej partycji wierszy jest niezwykle szybkie.

Jak powiedziałem wcześniej, działa to, jeśli masz tylko 1 stół. Nie testowałem tego, więc jest to tylko podejście teoretyczne, ale doświadczyłem szybkości opuszczania partycji i jest to niesamowicie szybkie.

Aby ulepszyć zaznaczenia, użyj właściwego indeksowania i popraw wstawień, aby zminimalizować rozmiar wiersza i liczbę indeksów (to stwierdzenie jest bardzo ogólne ...)

Więcej informacji można znaleźć na stronie: http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html Mam nadzieję, że to pomoże.

Bez szans
źródło
2
Nie jestem pewien, czy ma to sens w przypadku tego konkretnego problemu (wydaje mi się, że mysql wszystko buforuje i najprawdopodobniej te rekordy nigdy nie zobaczą dysku). Ale +1 za wskazanie interesującej techniki optymalizacji, której do tej pory nie znałem.