Hi,
folgende Sache:
Wenn man Rohstoffe abbaut, Gebäude baut und / oder Einheiten produziert, wie aktualisiert ihr das ganze? möglichst sehr abfragegering der Datenbank enstprechend versteht sich. Ich hab hier folgende Möglichkeiten:
1) Wenn der User sich einloggt oder von Seite zu Seite springt werden alle Daten die sich auf ihn beziehen aktualisiert. Mal davon abgesehen, dass die Daten der anderen nicht ständig aktuell sind, wird die Datenbank nicht sehr beansprucht.
2) Einen Cronjob erzeugen der jede Minute alles aktualisiert bzw alle Daten der User aktualisiert. Vorteil: Daten aller User sind aktuell. Nachteil: Zu viele unnötige Abfragen und die Daten werden nur im Minutentakt aktualisiert.
Wer weitere Vorschläge hat darf diese natürlich gerne miteinbringen. Ich suche derzeit nach der geschicktesten Lösung und es wäre eine große Hilfe mal eure Vorschläge zu hören.
Aktualisieren der daten
gepostet vor 18 Jahre, 3 Monate von pHoEnIx-sTyLe
gepostet vor 18 Jahre, 3 Monate von Kapsonfire
ignore_user_abort();
set_time_limit(600);
$x = 0;
while($x < 1)
{
//aktionen
flush();
sleep(1);
}
weiss nit wie sich das auf dem server auswirkt sollte aber an sich gehen
und das mit nem cronjob alle 10 minuten aufrufen
gepostet vor 18 Jahre, 3 Monate von exe
Das funktioniert aber auch nur, solange die Datenbank nicht zu groß ist. Wenn du da mal 10000 Objekte drinne hast, die aktualisiert werden müssen, geht dir der Server in die Knie bzw. die Datenbanktabelle ist durch die permanenten Updates quasi dauergelockt.
Ich gehe da folgendermaßen vor. Es gibt einmal Daten wie z.B. Rohstoffgutschriften, die permanent aktualisiert werden müssen. Wird nun ein Gebäude, welches Rohstoffe abbaut, aus der Datenbank geholt, werden die Rohstoffe gutgeschrieben, allerdings nur in dem Resultset das aus der Datenbank geholt wurde. Wird ein Gebäude in der Datenbank aktualisiert werden die mittlerweile produzierten Rohstoffe gleich mit in die Datenbank rausgeschrieben. Damit spar ich mir jegliche zusätzliche Updates der Datenbanktabelle.
Daneben gibt es noch Daten, wie z.B. die Fertigstellung eines Gebäudes, die nur einmal in der Datenbank eingetragen werden müssen. Dafür gibts einen Eventhandler der eine Liste aller dieser Ereignisse nach Zeit sortiert hat. Ist ein Ereignis abgelaufen wird der fertige Stand, also z.B. das fertige Gebäude, in der Datenbank eingetragen ..
Ich gehe da folgendermaßen vor. Es gibt einmal Daten wie z.B. Rohstoffgutschriften, die permanent aktualisiert werden müssen. Wird nun ein Gebäude, welches Rohstoffe abbaut, aus der Datenbank geholt, werden die Rohstoffe gutgeschrieben, allerdings nur in dem Resultset das aus der Datenbank geholt wurde. Wird ein Gebäude in der Datenbank aktualisiert werden die mittlerweile produzierten Rohstoffe gleich mit in die Datenbank rausgeschrieben. Damit spar ich mir jegliche zusätzliche Updates der Datenbanktabelle.
Daneben gibt es noch Daten, wie z.B. die Fertigstellung eines Gebäudes, die nur einmal in der Datenbank eingetragen werden müssen. Dafür gibts einen Eventhandler der eine Liste aller dieser Ereignisse nach Zeit sortiert hat. Ist ein Ereignis abgelaufen wird der fertige Stand, also z.B. das fertige Gebäude, in der Datenbank eingetragen ..
gepostet vor 18 Jahre, 3 Monate von Itchy
Wie in einem anderen Thread mal geschrieben, sind 10.000 Objekte ein Klacks für ein anständiges DBMS. Performanceüberlegungen kann man bei 1.000.000 und mehr Objekten anstellen, bei 10.000 besteht da noch keine Notwendigkeit.
Muß man halt ordentlich überlegen, wie die Objektzahl skaliert.
Muß man halt ordentlich überlegen, wie die Objektzahl skaliert.
gepostet vor 18 Jahre, 3 Monate von meisterjoda
da mein spiel tickbasiert ist, werden alle 5 minuten die ganzen aktualisierungsaktionen ausgeführt. und wenn man sich die mühe gibt seine scripte einigermaßen geschwindigkeitsoptimiert zu schreiben, dann geht das auch ganz gut. wenn das spiel jetzt mal in eine größere dimension (letzte runde waren es nur etwa 100 aktive) wächst, werde ich evt. die jobs auf mehrere einzelne crons verteilen, die zu unterschiedlichen zeiten ausgeführt werden...
gepostet vor 18 Jahre, 3 Monate von pHoEnIx-sTyLe
erstmal danke für die feedbacks.
bei mir läuft das in folgender weise:
alle bauvorgänge sind in einer tabelle. ob einheiten, gebäude, upgrades oder einheiten die stationiert oder abgezogen werden. damit man einen generellen überblick hat. das ganze wird über eine datei aktualisiert und wird derzeit nur wenn derjenige eingeloggt ist.
Ich will das ganze möglichst bestens und datenbankschonend aktualisieren damit das ganze auch stabil bleibt wenn die user mal steigen.
bei mir läuft das in folgender weise:
alle bauvorgänge sind in einer tabelle. ob einheiten, gebäude, upgrades oder einheiten die stationiert oder abgezogen werden. damit man einen generellen überblick hat. das ganze wird über eine datei aktualisiert und wird derzeit nur wenn derjenige eingeloggt ist.
Ich will das ganze möglichst bestens und datenbankschonend aktualisieren damit das ganze auch stabil bleibt wenn die user mal steigen.
gepostet vor 18 Jahre, 3 Monate von exe
Original von Itchy
Wie in einem anderen Thread mal geschrieben, sind 10.000 Objekte ein Klacks für ein anständiges DBMS. Performanceüberlegungen kann man bei 1.000.000 und mehr Objekten anstellen, bei 10.000 besteht da noch keine Notwendigkeit.
Ich meinte mit dem Skalierungsproblem nicht einen Select über 10.000 Zeilen. Dass das kein Thema ist weiss ich auch, hab ja erst neulich selber einen Test mit einer Tabelle mit 54 Millionen Einträgen gemacht (funktioniert 1A).
Das Problem dass ich meine ist folgendes: du willst 10.000 Zeilen aktualisieren, was bedeutet, dass du für jede Zeile eine UPDATE Abfrage absetzen musst. Bei einem Update wird die Tabelle oder mindestens die Zeile (je nach Storage Engine bei MySQL) gelockt. D.h. wenn du das Prozedere alle paar Sekunden machst hast du mehrere tausend Locks pro Sekunde auf deiner Tabelle. Und wenn dein Server dann noch ein bisschen Last abkriegt ist der Ofen aus.
Langer Rede kurzer Sinn: die Methode skaliert nicht wirklich und schon gar nicht unter Last. Da sehe ich meine Methode als sinnvoller an, da damit keine zusätzliche Belastung auf die Datenbank kommt. Alternativ könnte man in der Datenbank auch einen Trigger schreiben der bei einem SELECT auf die entsprechenden Tabellen die Daten automatisch aktualisiert bevor das Resultset an das Script ausgeliefert wird. Ich denke das wäre auch die sinnvollste Aufgabe da sowas eine klassische Datenbanksystemarbeit ist mit der man seine Scripts nicht unnötig befassen muss.
gepostet vor 18 Jahre, 3 Monate von Drezil
ich aktualisiere on demand - also wenn die infos benötigt werden.
ressourcenberechnung ist bei mir eh ein kompliziertes thema, dessen problemen ich erst vor kurzem herr geworden bin, wie auch in meinem gn-blog zu lesen war.
vorteile dieser methode:
nachteile:
ich fahre gut mit meinem jetzigen system und werde es auch nicht ändern.
Bei einem Update wird die Tabelle oder mindestens die Zeile (je nach Storage Engine bei MySQL) gelockt.
sicher? ich kann mich irren, aber ich denke, wenn man vorher manuell nen lock setzt (auf die tabelle oder zeile) um transaktionssicherheit zu gewährleisten wäre das nochmalige "per-default-locking" unnötiger overhead.
wenn ich nen wie angesprochenes "großes" update mache, dann hau ich da eh am anfang des scriptes nen "lock table x write"..
aber wie gesagt sind nur vermutungen.
ressourcenberechnung ist bei mir eh ein kompliziertes thema, dessen problemen ich erst vor kurzem herr geworden bin, wie auch in meinem gn-blog zu lesen war.
vorteile dieser methode:
- keine "echten" peaks wie bei ticks, demnach auch keine probs mit zu langen tick-laufzeiten
- unnötige aktualisierungen werden vermieden
- gleichmäßige lastverteilung (atm keine probs auf nem 733MHz w2k-server mit 384mb sdram133 bei 50-150 aktiven usern)
nachteile:
- wenn lange nicht aktualisiert wurde kommt es zu einer kurzen hohon last. kamm man durch crons in der nacht/alternative aktualisierungstrigger abfedern.
- zu stosszeiten läuft es konstant gut oder auch schlecht. es gibt keine "zeitpuffer" zwischen ticks.
ich fahre gut mit meinem jetzigen system und werde es auch nicht ändern.
Bei einem Update wird die Tabelle oder mindestens die Zeile (je nach Storage Engine bei MySQL) gelockt.
sicher? ich kann mich irren, aber ich denke, wenn man vorher manuell nen lock setzt (auf die tabelle oder zeile) um transaktionssicherheit zu gewährleisten wäre das nochmalige "per-default-locking" unnötiger overhead.
wenn ich nen wie angesprochenes "großes" update mache, dann hau ich da eh am anfang des scriptes nen "lock table x write"..
aber wie gesagt sind nur vermutungen.
gepostet vor 18 Jahre, 3 Monate von exe
Wenn du manuell einen Lock machst, dann dürfte der Standardlock wegfallen. Macht natürlich Sinn, wenn man 10.000 Datensätze am Stück aktualisiert, einfach einen generellen Lock für diese Zeit zu machen, da das dann schneller ist als ein seperater Lock bei jedem Update. Ändert aber auch nichts an der Grundproblematik, dass es eine Menge Overhead durch Locks ist der nicht sein muss.