Pare pytań odnośnie mysql
Sniper Elite
21.03.2014
Witam.
Chcę przenieść swój "stary cod" z zapisu nvault na mysql. Jako że pierwszy raz będę to robił mam kilka pytań:
- jak najlepiej zabierać się za zapis (aby jak najszybciej wczytywał dane po zmianie mapy)?
- czy ilość zmiennych do pobrania z bazy ma wpływ na szybkość jej wczytania?
Edited by Sniper Elite, 21.03.2014 20:55.
GwynBleidD
22.03.2014
Następna rzecz: zapis danych, tutaj również nie można przesadzić z ilością zapytań, a przy zmianie mapy znów mamy ich mnóstwo. Dlatego zamiast zapisywać dane w client_disconnect, stwórz string który wypełnisz początkiem zapytania (INSERT INTO .... VALUES), w client_disconnect dodaj do tego stringa dane o konkretnym graczu, a w plugin_end dodaj końcówkę zapytania (ON DUPLICATE KEY UPDATE...) i je wykonaj. Obciążenie serwera spada w tym momencie znacznie.
Grunt to podzielić sobie zadanie na 3 etapy i wykonywać je w tej kolejności:
- Projekt bazy danych - należy go wykonać w taki sposób, aby można było przy zapisie użyć jednego zapytania INSERT INTO ... ON DUPLICATE KEY UPDATE zamiast dwóch oddzielnych INSERT oraz UPDATE i do tego SELECT żeby sprawdzić którego należy użyć
- Zapis do bazy danych - dobrze jest go wykonać przed odczytem. Uwagi napisałem już wyżej.
- Odczyt z bazy danych - to idzie na końcu, tutaj musimy umiejętnie użyć cache'owania, bo ludzie mają dziwne pomysły i wystarczy kilka osób które będą na zmianę wchodzić na serwer i z niego wychodzić, żeby ten serwer wywalić (przy amxbans wystarczy jedna taka osoba i serwer się po chwili wykłada)
Sniper Elite
23.03.2014
Ciekawie opisane, dzięki
A zapis np. w najnowszym diablo 5.9l lub CodMod v3 lud Diablo Core Darka jak się sprawdza przy 32 graczach?
GwynBleidD
23.03.2014
Sądzę, że nie bardzo... Jeśli masz dobre połączenie z serwerem MySQL i szybko on odpowiada to może się sprawdzić, ale jeśli połączenie jest słabe (np SQL jest we Francji, a HLDS w Polsce) to będzie kiepsko...
Sniper Elite
23.03.2014
Hosting to unixstorm, więc wszystko ładnie śmiga. Jedyny minus to to że zwykły hosting, vps zakupie dopiero w wakacje.
Spróbuję zrobić na razie coś na podobe coda darka. Mam na serwerze rozgrzewkę, więc powinno się w trakcie jej załadować. Bo tym sposobem który opisałeś będzie ciężko, jeszcze tak programować nie umiem.
GwynBleidD
23.03.2014
Kiedyś może pokuszę się o uniwersalny moduł zapisu danych do SQL i pliku, w którym miejsce zapisu będzie się wybierało bez udziału pluginu i będzie się on już zajmował optymalnym rozplanowywaniem wykonywania zapytań w przypadku użycia SQL. Ale to na pewno będzie dalej niż bliżej, bo priorytetem dla mnie jest kilka innych rzeczy.
Sniper Elite
23.03.2014
Czyli proponujesz zrobić tak:
- zapisywać dane ze statystykami expem i poziomem do pliku tekstowego i powiedzmy co 60 sek. sprawdzać czy gracz dalej gra na serwerze, jeżeli nie to zaktualizować jego wpis w bazie a ten z pliku tekstowego wyczyścić.
- to samo z odczytem. Po zmianie mapy większość graczy będzie z poprzedniej mapy, więc odczytanie danych też nie powinno być problemem. Jeżeli go tam nie ma odczytać dane z tabeli, ew. utworzyć nowy wpis.
- nie używać client_disconnect oraz plugin_end bo wtedy zapytanie wywoływane jest wszystkim graczom (zmiana mapy) a to laguje.
Jest funkcja która zwraca ilość wpisów w takim pliku tekstowym?
Edited by Sniper Elite, 23.03.2014 22:41.
GwynBleidD
23.03.2014
Przed zmianą mapy zapisujesz dane użytkownika w jakimś pliku, po zmianie po 60 sekundach czyścisz plik. Wygodnie jest sobie utworzyć folder w data i w osobnych plikach trzymać dla każdego gracza dane, pliki nazywając ID gracza (nick, steamid czy ip w zależności od tego po czym sprawdzasz) + czas utworzenia pliku (wtedy wiesz kiedy go usunąć) i odpowiednio sprawdzać, czy plik istnieje gdy gracz wchodzi na serwer.
Sniper Elite
25.03.2014
Nie było mnie troszkę.
Przeszukałem forum, ale nie znalazłem nic o dokładnym opisie mysql w amxx. Chodzi mi głównie to takie zwroty jak "INSERT INTO" lub "ON DUPLICATE KEY".
Jest gdzieś to wyjaśnione?
Seba 26.03.2014
Najlepiej się za to zabrać w client_authorized, ale... 32 zapytania do pobrania danych dla wszystkich graczy tuż po zmianie mapy na pełnym 32 slotowym serwerze prawie na 100% skończy się crashem.
Tiru riru paczka zwiru, a amxbans dziala na tysiacach serwerow wlasnie w ten sposob.
GwynBleidD
26.03.2014
Tiru riru paczka zwiru, a amxbans dziala na tysiacach serwerow wlasnie w ten sposob.
I wiele serwerów z amxbans właśnie dlatego przy zmianie mapy crashuje. Wystarczy, żeby połączenie z bazą danych było wątpliwej jakości.
Seba 27.03.2014
Tiru riru paczka zwiru, a amxbans dziala na tysiacach serwerow wlasnie w ten sposob.
I wiele serwerów z amxbans właśnie dlatego przy zmianie mapy crashuje. Wystarczy, żeby połączenie z bazą danych było wątpliwej jakości.
Ale jak juz komus radzisz to rob to rzetelnie, 100% to oznacza za kazdym razem
GwynBleidD
27.03.2014
Dlatego napisałem "prawie na 100%". Jestem nastawiony na pisanie pluginów, które mają działać w każdej sytuacji, a nie tylko na moim dobrze skonfigurowanym serwerze który ma dobre połączenie z bazą danych (a i w takiej sytuacji na 32 slotowym serwerze crashe się zdarzają). Bo nawet jak piszę plugin dla siebie, to moje warunki też mogą się zmienić i nie będę miał bazy danych w dobrej lokalizacji względem serwera.Ale jak juz komus radzisz to rob to rzetelnie, 100% to oznacza za kazdym razemTiru riru paczka zwiru, a amxbans dziala na tysiacach serwerow wlasnie w ten sposob.
I wiele serwerów z amxbans właśnie dlatego przy zmianie mapy crashuje. Wystarczy, żeby połączenie z bazą danych było wątpliwej jakości.
sebul
27.03.2014
Jakby nie patrzeć "prawie 100%", to też "trochę" za dużo. Oczywiście masz rację pisząc, że nie jest to dobrze zrobione, ale też nie przesadzajmy, że to nie działa. Co prawda może sam nie miałem nigdy 32 slotowego serwera, ale widziałem jak działają takie serwery z amxbansem (nawet starszym niż gm amxbans).
Sniper Elite
27.03.2014
Panowie odbiegamy od tematu
Powiedzmy że będę chciał zapisywać poziom gracza do pliku (w config/lvl.ini). Taki mały przykład:
"Sniper Elite" "13" "14440" "statystyka1" "statystyka2"...
"sebul" "15" "18888" "statystyka1" "statystyka2"...
"Seba" "11" "10000" "statystyka1" "statystyka2"...
Da się później z tego pliku odwołać do określonego nicku? Sprawdzić czy dany nick w nim widnieje?
Chciałem zrobić tak, że po wbiciu na serwer i odczytaniu lvl z bazy będzie on zapisywany w takim pliku i aktualizowany gdy dostaniemy expa.
Następnie taskiem będę sprawdzać czy gracz na serwerze jeszcze jest, jeżeli nie zapisze dane do bazy a wpis usunę.
Jeżeli takie operacje są możliwe poproszę o jakiś poradnik z dokładnym opisem jak takie zapisywanie do pliku działa (zapis wartości, sprawdzanie czy w dokumencie istnieje dana wartość (nick), usuwanie wpisów z tego pliku oraz może ilość graczy zapisanych w tym pliku).
Jeżeli nie to pomysł GwynBleidD też jest spoko:
Zapisywać dane możesz w zmiennej, tworzysz zmienną globalną o takiej długości, aby pomieściła zapytanie zapisujące 32 graczy na raz, wypełniasz ją początkiem zapytania insert, gdy gracz wyjdzie z serwera (client_disconnect) dopisujesz do zmiennej dane gracza do zapisania. Co jakiś czas (np 60 sekund), gdy dopiszesz już 32 graczy i w plugin_end dopisujesz do zapytania jego koniec, wykonujesz je, czyścisz zmienną i wpisujesz znów początek. Z tym wyjątkiem, że w plugin_end nie używasz ThreadQuery, ale metody "blokującej" (przy plugin_end tego "blokowania" nie widać, a ThreadQuery może powodować błędy)
Przed zmianą mapy zapisujesz dane użytkownika w jakimś pliku, po zmianie po 60 sekundach czyścisz plik. Wygodnie jest sobie utworzyć folder w data i w osobnych plikach trzymać dla każdego gracza dane, pliki nazywając ID gracza (nick, steamid czy ip w zależności od tego po czym sprawdzasz) + czas utworzenia pliku (wtedy wiesz kiedy go usunąć) i odpowiednio sprawdzać, czy plik istnieje gdy gracz wchodzi na serwer.
tylko ciut skomplikowany. Nie mam pomysłu jak ta duża zmienna globalna miałaby wyglądać.
Edited by Sniper Elite, 27.03.2014 12:25.