Chcę użyć bazy danych SQL w moim server.exe.
powiedzmy 1000 użytkowników online. Gracze zmienią swoje dane podczas gry. I serwer musi zapisać te aktualizacje.
Ale jak ?
myślę tam na dwa sposoby:
1) serwer zapisze w pamięci RAM w czasie wykonywania i czasami lub co godzinę serwer zapisze dane (aktualizacje) do bazy danych SQL z pamięci RAM. Ale jeśli nastąpi przerwa w dostawie prądu lub serwer się wyłączy, aktualizacje nie zostaną zapisane. oczywiście nie chcę tracić aktualizacji.
2) serwer zapisze aktualizacje w bazie danych w czasie wykonywania. ale co stanie się z prędkością? Myślałem o metodzie. pokażę Ci poniżej obraz. Czy za pomocą tej metody mogę uzyskać wystarczającą prędkość dla 1000 graczy online?
mmo
client-server
server
sql
Emre Kaya
źródło
źródło
Odpowiedzi:
Większość MMO (lub projektów wykorzystujących podobną architekturę), nad którymi pracowałem lub wiem o użyciu pierwszej metody: serwery gier działają głównie z pamięcią RAM na komputerach z procesami serwerowymi i tylko okresowo serializują odpowiednie dane gry do bazy danych SQL do archiwizacji (jeśli w ogóle jest używana).
Problemy, które zauważysz w związku z awarią zasilania, są prawidłowe, ale mniej prawdopodobne niż problemy, takie jak awarie procesu (niezawodność czasu działania jest ogólnie jedną z rzeczy, za które zapłacisz centrum danych). Ale nadal. Łagodzisz te problemy, na przykład dostrajając interwał zapisywania (więc awaria kosztuje najwyżej kilka minut postępu), rozprowadzając kolejki zapisywania na wielu komputerach, agresywnie określając ilość danych, które należy zapisać, i wdrażając zapis restartu kolejki.
Ogólnie mówiąc, używanie samego serwera SQL jako pamięci głównej będzie nieprzyjemnie wolne (i uciążliwe). Nie widzę wystarczająco dużo szczegółów w twojej propozycji, aby móc z całą pewnością stwierdzić, czy zadziałałoby tylko dla około 1000 graczy - prawdopodobnie byłoby dobrze. Ale nie wierzę, że można sprawić, by była agresywnie skalowalna.
Co więcej, to nie rozwiązuje problemu. Awaria zasilania podczas procesu składowania nadal spowoduje utratę lub uszkodzenie danych, chyba że wykonasz pracę w celu wdrożenia tego samego rodzaju kolejki składowania, którą można zrestartować (co nawet wtedy, gdy tylko poważnie zmniejsza prawdopodobieństwo katastrofalnej utraty danych, nie zapobiega temu) .
Poleciłbym ci pierwsze podejście.
źródło
1000 graczy może, ale nie musi stanowić problemu. Zależy to od częstotliwości aktualizacji bazy danych. Istnieje jednak proste rozwiązanie: umieść bazę danych na własnym serwerze.
Rzuciłem okiem na to, jak działa system baz danych w grze, którą ludzie nazywają MMO-Lite - której nie ujawnię - ale mogę powiedzieć, że konsekwentnie ma ponad 1000 graczy, oto streszczenie:
Korzystanie z bazy danych opartej na dokumentach okazuje się być dobrym pomysłem na wydajność w tym przypadku. Jest dobry do uzyskiwania dostępu do danych, nawet jeśli jest zły do wykonywania połączeń i agregacji ... ale nie zrobią tego z danymi, które się tam znajdują.
Z drugiej strony, kiedy muszą zrobić coś takiego, jak zmienić obiekt innym obiektem dla wszystkich, potrzeba uruchomienia skryptu w tle, który przechodzi znak po znaku i aktualizuje je jeden po drugim, zajmuje to zauważalny czas.
Dane postaci istnieją zarówno na kliencie, jak i na serwerze, a system został zaprojektowany w taki sposób, aby synchronizować je, wykonując te same operacje po obu stronach.
Teraz, gdy gracz dokonuje transakcji z systemem - na przykład wymienia przedmiot na inny za pośrednictwem NPC lub podobnego - ma to następujące etapy:
Uwagi :
Transakcje między graczami są obsługiwane w podobny sposób, z dodatkowymi zasadami, aby zapobiec oszustwom innych graczy, oraz dodatkową identyfikowalność w przypadku konieczności cofnięcia transakcji. Słyszałem, że istnieją specjalne dzienniki wszystkich transakcji, które są przechowywane przez pewien czas (aby rozwiązać problemy, gdy ktoś narzeka), nie wiem więcej o tym, jak ta część działa.
Czasami coś idzie nie tak, ma to dwa możliwe skutki:
W obu przypadkach klient jest świadomy błędu i zarejestruje go wraz ze wszystkim, co robił gracz. Logowanie po stronie klienta odbywa się cały czas. Następnie po wylogowaniu, jeśli wystąpił błąd, klient wysyła dzienniki na serwer.
Ta gra nie wykorzystuje tradycyjnego codziennego lub cotygodniowego przestoju konserwacyjnego, jaki ma większość gier MMORPG. Ta planowa konserwacja jest często używana do resetowania liczników, timerów, uruchamiania procedur bazy danych. Są również okazją do zamiany wersji serwera na aktualizację.
źródło
x:10,y:10,z:10
Dox:11,y:11,z:11
, czy należy to natychmiast zapisać w bazie danych? co jeśli gracz będzie kontynuował bieg, oznacza to, że zapisujemy jego aktualną pozycję co 1 sekundę lub mniej, a jeśli są tysiące graczy, to miliony zapytań do DB co sekundę. Czy tak to działa?Oba podejścia są stosowane w MMORPG. Przechowywanie wszystkiego w pamięci i okresowe sprawdzanie kierowania go na dysk wydaje się być najpopularniejszą opcją, przynajmniej w przypadku starszych gier. Ma tę zaletę, że jest dość łatwa do wdrożenia i skalowania dość dobrze, ale zapewnienie niezawodności zależy wyłącznie od dewelopera. Bazy danych SQL zapewniają właściwości ACID, które ułatwiają niezawodność, ale ogólnie są bardziej skomplikowane w zakresie prawidłowej implementacji i mogą mieć problemy ze skalowaniem.
EVE Online jest przykładem MMO, w którym wszystko jest przechowywane w bazie danych SQL. Myślę, że osiągnął szczyt około 60 000 jednoczesnych użytkowników i przez lata musiał poświęcić serwerom bazy danych drogi sprzęt, aby nadążyć za obciążeniem. Jednak EVE przechowuje o wiele więcej danych na użytkownika niż większość MMORPG i ma o wiele częstsze i zróżnicowane transakcje. Właściwości ACID bazy danych pozwalają na utrzymanie całej ogromnej i skomplikowanej bazy danych w spójnym stanie.
Rozważmy na przykład przypadek, gdy ktoś daje przedmiot innemu graczowi. Baza danych EVE gwarantuje, że nawet w przypadku awarii lub awarii zasilania przedmiot trafi do ekwipunku tylko jednego gracza. Oznacza to, że transakcja w bazie danych, która usuwa przedmiot z ekwipunku jednego gracza i dodaje go do ekwipunku innego gracza, jest atomowa. Transakcja jest w pełni zakończona lub w ogóle się nie dzieje. Nie możesz skończyć w stanie, w którym przedmiot nie istnieje w ekwipunku żadnego z graczy ani w obu.
MMORPG, który przechowuje dane gracza w pamięci i okresowo kontroluje, musi sam zaimplementować tę atomowość. Jednym ze sposobów, aby to zrobić, byłby punkt kontrolny danych każdego gracza w tym samym czasie, zapewniając, że nowy punkt kontrolny jest w pełni przypisany do dysku, zanim zostanie uznany za najnowszy punkt kontrolny. Gra musiałaby również dopilnować, aby dane gracza nie mogły się zmienić podczas kontroli. Przy dużej liczbie aktywnych graczy wyzwanie staje się tym wszystkim bez powodowania opóźnienia wystarczająco długo, aby gracze to zauważyli.
Nie lekceważ, jak ważna jest spójność. Gdy rozwijasz swoją grę, będzie się ona często zawieszać. Nie musisz śledzić, dlaczego przedmioty znikają i / lub powielają się, nie wtedy, gdy problemem jest niezwiązany błąd, który powoduje awarię gry w złym momencie. Co więcej, gdy gra zostanie uruchomiona, zawiesi się znacznie bardziej, niż się spodziewasz. Twój serwer, który działał idealnie podczas testowania, nagle ujawni liczne błędy pod pełnym obciążeniem, a gracze robią rzeczy, których się nie spodziewałeś.
Zauważ, że większość MMORPG używa baz danych SQL do informacji związanych z kontem, nawet jeśli nie do rzeczywistych danych gry. Jeszcze ważniejsze niż utrzymanie stanu gry w spójnym stanie jest utrzymanie stanu fakturowania. Najgorszym przypadkiem uszkodzenia bazy danych gier jest konieczność przywracania bazy danych z codziennej kopii zapasowej. Najgorszym przypadkiem uszkodzenia bazy danych kont jest to, że bankrutujesz z powodu wszystkich obciążeń zwrotnych.
Do swojego projektu prawdopodobnie możesz pójść w obie strony. Posiadanie 1000 równoczesnych użytkowników prawdopodobnie nie przekroczy limitów, jakie może obecnie obsługiwać serwer SQL na zwykłym komputerze PC, ale wiele będzie zależeć od charakteru transakcji. Jeśli znasz SQL i projektowanie relacyjnych baz danych, może to działać dla Ciebie. Będziesz chciał zminimalizować transakcje w jak największym stopniu, dla czegoś takiego jak bieżące punkty życia gracza możesz chcieć tylko okresowo zapisywać je w bazie danych, ponieważ takie statystyki niekoniecznie muszą być spójne. (W grze PvP mogą jednak ...) W ogóle nie przechowują takich rzeczy jak HP potworów w bazie danych, w większości gier tylko dane dotyczące graczy są trwałe.
Z drugiej strony, jeśli nie jesteś kreatorem SQL, przechowywanie wszystkich danych w pamięci może być znacznie prostsze, aby zapewnić niezawodne działanie. Bazy danych SQL ułatwiają spójność i niezawodność, ale nie są automatyczne. Źle zaprojektowana baza danych może słabo działać i prowadzić do niespójności. Transakcje nie będą atomowe, chyba że je zrobisz. Jeśli nie użyjesz sparametryzowanych instrukcji religijnie, otworzysz się na ataki typu SQL injection.
źródło
Różne gry przechowują różne rzeczy na różne sposoby. Często firmy gier tworzą jakiś sposób, aby to zrobić, a większość ich gier używa tego samego. Oczywiście różne studia często używają różnych sposobów. SQL jest z pewnością używany w grach, np. CCP (EVE) ma (lub przynajmniej miał) sieć serwerów SQL, nie jestem pewien, jak teraz to robią. Inni używają tylko wielu plików.
Może zacznij od stworzenia agnostycznego „mechanizmu brokera danych” do obsługi różnych transakcji danych w grze? Ponieważ i tak właśnie testujesz, stwórz mechanizm, który pozwoli ci nie przejmować się zbytnio pamięcią masową z punktu widzenia samej gry. To znaczy, skoncentruj się na tym, jak z aplikacji hosta zamierzasz sobie z tym poradzić.
Osobiście uważam, że byłoby wielkim atutem, gdybyś mógł zmienić rzeczywisty sklep bez konieczności przepisywania gry i samego brokera. Po prostu przełącz się na inny moduł z tym samym interfejsem, z którym broker może rozmawiać.
Samo przechowywanie danych prawdopodobnie nie będzie stanowić problemu. Skuteczne przesyłanie danych do / z tego sklepu między hostem a wszystkimi klientami może być trudniejsze. Czy wysyłam cały zestaw danych odtwarzacza, czy też dzielę go na części, jaką ziarnistość wybieram na partycje itp. Który z nich jest bardziej zasobochłonny w jakiej sytuacji itp.
Jednym z formatów przesyłania danych może być XML. W ten sposób możesz łatwiej być dynamicznym w tym, jak możesz go podzielić. Jeden znak vs. wiele znaków lub jeden element vs. zbiór elementów itp. Możesz wtedy „przechowywać” XML jako XML (w SQL) i / lub zlecić SQLowi jego dystrybucję w bardziej transakcyjny sposób z XML, do jak chcesz, aby dane były faktycznie przechowywane.
Innym sposobem jest system binarny, który jest bardziej wydajny pod względem wysyłki, ale może wiązać się z większymi kosztami w innych sytuacjach.
Przy 1000 klientów możesz zacząć od łatwego przechowywania 10 MB na klienta i używać tylko 10 GB efektywnej pamięci RAM + dodać trochę systemowej administracyjnej pamięci RAM do zarządzania tymi danymi, powiedzmy kolejną GB lub dwie. Możesz zachować to w pamięci RAM na hoście już w strukturze danych, gotowe do użycia. I ładuj / zapisuj dynamicznie, w zależności od tego, kto jest online, na różnych częstotliwościach w zależności od aktywności itp.
Możesz nawet przechowywać informacje o każdym kliencie w osobnym pliku i tak dalej.
źródło
Trzymaj graczy * online * w pamięci RAM i wypychaj ich do bazy danych (SQLite? MySQL?), Gdy się wylogują. jeśli martwisz się opóźnieniem we / wy podczas wylogowywania, daj każdemu wylogowaniu swój własny wątek, nie rób tego w głównym wątku / grze (w rzeczywistości mam dedykowany wątek dla każdego gracza online, dzięki temu kod sieci jest o wiele łatwiejszy niż zastosowanie podejścia async network io)
źródło