2012-04-26 11 views
7

Posiadam grę w pokera na iPhone'a z wieloma grami działającymi w tym samym czasie. Jestem w trakcie optymalizacji kodu, ponieważ zarówno ja, jak i serwer rozbiliśmy dzisiaj.1.3M zapytań/godzinę. Jak skonstruowałbyś zapytania?

Jest to konfiguracja:

Teraz mam jedną tabelę, „pasuje” (70 pól danych dla każdego wiersza konstrukcji.), Że śledzenie wszystkich aktywnych meczów. Co 7 sekund iphone się połączy, pobierze wszystkie mecze z tabeli "mecze", w której jest aktywny, i zaktualizuje interfejs użytkownika w telefonie iPhone.

To działało świetnie, aż około 1000 osób pobrało grę i zagrali. Serwer się zawiesił.

Aby zoptymalizować, wyobrażam sobie, że mogę utworzyć nową tabelę o nazwie "matches_needs_update". Ta tabela ma 2 rzędy; imię i nazwisko. "Identyfikator" jest taki sam jak mecz w tabeli "mecze". Gdy mecz jest aktualizowany, jest umieszczany w tej tabeli.

Teraz, zamiast przeszukiwać cały stół "mecze", zapytanie wystarczy sprawdzić, czy gracz ma jakieś mecze, które wymagają aktualizacji, a następnie uzyskać te mecze z tabeli "mecze".

Moje pytanie jest dwojaki:

  1. Jest to optymalne rozwiązanie?
  2. Jeśli gracz jest aktywny, powiedzmy 10 meczów, czy istnieje dobry sposób na uzyskanie tych 10 meczów z tabeli "mecze" w tym samym czasie, czy też potrzebuję pętli for wykonującej 10 zapytań, po jednym dla każdego mecz:

    "WYBIERZ * Z GESTÓW WHERE id =?"

Dzięki z góry

+6

Podczas gdy problem jest poważny, jest to jeden z najlepszych rodzajów problemów, jakie możesz mieć, jeśli myślisz o tym. Zawieszenie się ze zbyt wielu rzeczywistych użytkowników jest najlepszym rodzajem awarii. – Cyclone

+1

Rozwiązanie korzystające z powiadomień wypychanych może być lepszym sposobem na obejście problemu z wydajnością. W ten sposób nie będziesz mieć zbyt wielu nadmiarowych czeków na zmianę –

+1

To brzmi prawie tak, jakby jedna osoba mogła być aktywna w wielu meczach, a wiele osób może być aktywnych w 1 meczu? Z pewnością musisz mieć 3 stoły? – DanRedux

Odpowiedz

6

Proponuję APC ...

... jak jesteś na PHP, i zakładam, że robisz to z jednej bazy danych MySQL,

Jest łatwy w instalacji, a będzie domyślnie od PHP 6 i kolejnych.

Przechowywać ten 1 tabela w pamięci i będzie latać.

+0

Dzięki za odpowiedź. Czy muszę zaktualizować cały mój kod php, aby go obsłużyć, czy jest to tylko instalacja? Dzięki – BlackMouse

+0

APC to 2 rzeczy. Jest to pamięć podręczna opcode (buforuje kod PHP, więc ładuje się szybciej) i magazyn pamięci (tj. Klucz-wartość). Pierwsza część dzieje się automatycznie i daje zwiększenie prędkości. Ale jesteś zainteresowany drugim fragmentem. Tak więc - musisz zaktualizować swój kod. Przeczytaj stronę podręcznika, którą podłączyłem, i zacznij od apc_store, aby uzyskać ten pomysł. – HappyTimeGopher

7

Musisz wydostać się z bazy danych. Spójrz na memcache lub redis.

2

Twoja baza danych wygląda naprawdę niedużo. Tabela z 70 wierszami powinna powrócić w ciągu milisekund, a nawet setki zapytań na sekundę powinny działać bez żadnych problemów.

Kilka tradycyjnych wskaźników

  • Upewnij się połączyć połączeń. Nigdy nie powinieneś robić połączenia, gdy klient potrzebuje danych.
  • Upewnij się, że istnieje indeks "użytkownik jest w grze", aby wynik został pobrany z indeksu.
  • Jestem pewien, że masz wystarczająco dużo pamięci, aby pomieścić całą strukturę w pamięci podręcznej, a te małe tabele nie wymagają dodatkowej konfiguracji.
  • Upewnij się, że Twój schemat jest znormalizowany.Jedna tabela dla każdego użytkownika. Jeden na każdy mecz. I jeden dla każdego użytkownika w meczu.
1

Czas na cachowanie rzeczy, np. Memcache i apc.

Jeśli chodzi o zapętlenie pasujące mecze ... to jest niewłaściwy sposób, aby to osiągnąć.

W jaki sposób użytkownik jest połączony z dopasowaniem przez tabelę ze znacznikami XREF? lub czy stół meczowy ma coś podobnego do player1, player2.

Zapętlanie zapytań nie jest sposobem na poprawne indeksowanie tabel i robienie połączenia w celu wyciągnięcia wszystkich aktywnych dopasowań przez userId byłoby bardziej wydajne. Podaj liczbę użytkowników, których możesz również chcieć (jeśli nie) rozdzielić tabele dla aktywnych i nieaktywnych gier.

Jeśli jest tam 6000 aktywnych gier i 3 000 000 nieaktywnych, bardzo korzystnie jest podzielić te tabele.