mmofacts.com

Optimale Datenspeicherung (Caching?)

gepostet vor 16 Jahre, 1 Monat von _Jan_

Hi!

Ich stehe zZ. vor dem Problem in welcher Weise ich Daten am besten abspeichere.Es geht darum, Feldinformationen zu einer Karte ähnlich googleMaps auszulesen. Die Gesamtzahl der zur Verfügung stehenden Informationen liegt bei einigen Tausenden Einträgen.

Zur Lage: Die Daten werden nur einmal pro 30 Minuten aktualisiert, daher ist es wohl überflüssig sie jedes mal direkt neu aus der mySQL Datenbank zu holen.. zur Zeit arbeitet das Script so, das jedes noch nicht mit Informationen gefüllte Feld im Sichtbereich des Nutzers sich einzeln die nötigen Informationen aus einem PHP-Script zieht. Zur Zeit füllt sich die Karte noch mit Zufallsmaterial, doch jetzt möchte ich gerne auf feste Datenbestände zugreifen. Die einfachste aber wohl auch schlechteste Möglichkeit wäre wohl für jedes Bild eine neue SQL-Anfrage abzusenden. Dies würde bei jedem Kartenverschieben knapp 5-8 SQL Anfragen erzeugen. Der nächste Schritt wäre alle benötigten SQL-Anfragen zu einer einzigen zusammenzufassen.

Doch da die Daten nur alle 30 Minuten aktualisiert werden, müsste es doch sicherlich auch eine Möglichkeit zum Cachen geben? Das Script bekommt als Eingabe lediglich x und Y- Koordinate und gibt die Information zum Bild aus. Ist es möglich da einfach zu Cachen? Die mir bekannten Lösungen wären der MySQL Cache(ab 4.0), das ganze als XML zu speichern(bringt aber nicht viel, oder?), der Einsatz von (zB. ADOdb). Welche ist die beste Möglichkeit (wie schwer umzusetzen?), gibt es vielleicht noch bessere Möglichkeiten?

Danke & grüße

Jan

Ich habe leider noch nie mit Caching gearbeitet.

gepostet vor 16 Jahre, 1 Monat von _Jan_

danke :)

aber:

"If the data you need to cache is small and you do infrequent updates, MySQL's query caching should work for you. If not, use memcached."

Dementsprechend sollte doch der MySQL Cache genügen, oder? (Updates nur alle 30 min, sehr kleine Datenbestände die von Änderungen betroffen sind)

gepostet vor 16 Jahre, 1 Monat von Klaus

Ja der Query Cache ist schon was feines. Ein eigener Cache wäre sinnvoll, wenn du z.B. die Daten noch verarbeitest und dann speicherst, z.B. als fertiges HTML.

gepostet vor 16 Jahre, 1 Monat von _Jan_

Lohnt es sich dazu noch PHPAccelerator o.ä einzusetzen?

gepostet vor 16 Jahre, 1 Monat von Kampfhoernchen

Definitiv!

gepostet vor 16 Jahre, 1 Monat von Fornax

Meiner Erfahrung nach lohnt sich der eAccelerator immer; auch bzgl Caching. Wobei ich denke, dass der MySQL-Cache auch reichen sollte, solange MySQL und PHP auf einem physikalischem System laufen (sprich beim Clustern würde ich mir Gedanken machen und nicht nur den MySQL-Cache benutzen).

Was du aber auf jeden Fall machen solltest, ist in JS ein Cache. Wenn man auf der Karte zurückscrollt dass er nicht alles wieder laden muss ;)

gepostet vor 16 Jahre von HSINC

als tipp, wenn es wirre probleme mit dem eacc gibt (scriptabstürtze, etc ) nimm nen anderen cache (zb apc), ist deutlich einfacher als zu versuchen die probleme zu lösen ^^

und wenn du kein memcache nutzen willst, kannst du auch shared mem nehmen http://de.php.net/manual/de/book.shmop.php

und der mysql querycache ist nur sinnvoll wenn du sehr viele selects über die selben unveränderten daten machst. inwiefern andere selectsatements den cache beeinflussen weiss ich grad nicht genau, denke aber was drüber gelesen zu haben. nunja musst du selber mal schauen

gepostet vor 16 Jahre von exe

In der Situation wäre es auch eine Idee die Informationen einfach alle 30 Minuten in eine Datei im Dateisystem des Webservers zu schreiben. Wenn die Informationen pro Feld immer gleich groß sind könntest du die Karte einfach als Bitmap speichern.

Vorteil: sehr schneller Zugriff auf einzelne Feldinformationen, konstante Zugriffsgeschwindigkeit unabhängig von der Kartengröße und, wenn die Karte in den RAM passt, landet sie sowieso im Dateisystempuffer, womit du im Endeffekt mit RAM-Geschwindigkeit auf deine Spielkarte zugreifst. Schneller gehts dann eigentlich nicht mehr.

Nachteil: du musst einmal alle 30 Minuten deine komplette Spielarte auf Festplatte dumpen. Je nachdem wie groß die Karte wird könnte das problematisch werden.

gepostet vor 16 Jahre von knalli

Könnte man da nicht uU auch ein on demand caching nutzen? Also ein TTL für jedes Objekt, was durch den "Client-Zugriff" aktualisiert wird. Kartenausschnitte, die selten/gar nicht genutzt werden, werden nicht gelesen/geschrieben.

gepostet vor 16 Jahre von _Jan_

Original von Fornax

Was du aber auf jeden Fall machen solltest, ist in JS ein Cache. Wenn man auf der Karte zurückscrollt dass er nicht alles wieder laden muss ;)

Ehrlich gesagt lösche ich zZ. wieder jedes Bild das nicht im Sichtbereich ist. Das Spiel soll ja auch auf schwächeren Rechnern laufen... meinst du das auch schwache Maschinen das schaffen?

@HSINC

und der mysql querycache ist nur sinnvoll wenn du sehr viele selects über die selben unveränderten daten machst.

Änderungen am Abgefragten Datenbestand gibt es nur alle 30 Minuten - fällt also in die Kategorie.

@exe

Nachteil: du musst einmal alle 30 Minuten deine komplette Spielarte auf Festplatte dumpen. Je nachdem wie groß die Karte wird könnte das problematisch werden.

Kannst du das mit der Bitmap nochmal erleutern? Die Größe(px) des Feldes ist immer gleich, der Datenbestand nicht. Soll quasi eine einzelne Bitmap aus den anderen zusammengesetz werden? Dann müsste doch immer die ganze bmp an den Client übertragen werden, richtig? Über die Texturen werden allerdings noch divs gelegt, kann es da Probleme geben?

Mit dem Gedanken die Daten alle 30 Minuten als XML Doc an den Client zu übergeben habe ich auch schon gespielt. Dadurch würde quasi der ganze MySQL-Serveraufwand für die Karte wegfallen. Die vom User übergebenen Aktionen würden ja genauso auf ihre Richtigkeit gecheckt werden wie als wenn sie mit den Kartendaten direkt vom Server übertragen worden wären - der Nachteil dabei wäre aber nunmal das der User stetig die neue XML Datei bekommen müsste. Ließe sich das realisieren ohne dass der User etwas davon merkt? Dazu halt die Kartengröße die du schon als Problematisch angesprochen hast. Man müsste halt sehen wieviele kb/mb da zusammenkommen. Bei Daten im Bereich von einigen hundert kb wäre das ganze in Zeiten von DSL ja kein großes Problem.

@knalli

Könnte man da nicht uU auch ein on demand caching nutzen? Also ein TTL für jedes Objekt, was durch den "Client-Zugriff" aktualisiert wird. Kartenausschnitte, die selten/gar nicht genutzt werden, werden nicht gelesen/geschrieben.

Ist das nicht beim MySQL Cache der Fall? Soweit ich weiß, wird der Cache sofort neu geschrieben wenn eine Änderung eintritt. Der Client ansich aktualisiert nicht, die Änderungen die dieser vornimmt werden in einer anderen Tabelle gespeichert und dann alle 30 Min abgearbeitet. Ausschnitte die nicht genutzt werden werden also weder gelesen noch beschrieben. Eine TTL ist dann doch auch überflüssig..

Danke an alle :)

gepostet vor 16 Jahre von knalli

Ich meinte auf Ebene der Bitmaps; also eine Kombination der Vorschläge. Und klar, die TTLs sind dann doppelt vorhanden, aber mit gleichen Werten (bei dir, jetzt, in diesem Kontext).

gepostet vor 16 Jahre von Fornax

Original von _Jan_

Original von Fornax

Was du aber auf jeden Fall machen solltest, ist in JS ein Cache. Wenn man auf der Karte zurückscrollt dass er nicht alles wieder laden muss ;)

Ehrlich gesagt lösche ich zZ. wieder jedes Bild das nicht im Sichtbereich ist. Das Spiel soll ja auch auf schwächeren Rechnern laufen... meinst du das auch schwache Maschinen das schaffen?

Kommt drauf an, wie und was der Client nachfragt. Wenn du nur eine JSON-Abfrage machst und beim Client danach die Karte baust ist das meiner Meinung nach kein Problem.

Sähe dann z.B. so aus: [[{"validUntil":#timestamp#,"type":1,"bla":"blubb"}, ...], [..., ...]] /* [x1[y1,y2],x2[y1,y2]]*/

Den Timestamp würde ich nutzen wegen den 30 Minuten. Man könnte dann "per Hand" auch alle 5 Minuten das Array durchgehen und erstmal alle löschen die ehh abgelaufen sind, und je nach Speicherverbrauch alle löschen die weiter weg sind als x Felder, die nahen bleiben.

Wenn der Client Bilder bekommt wie z.B. bei Google Maps hast du recht bzgl. Speicherverbrauch, das könnte uU viel werden. Da würde ich dann nur die angrenzenden Felder lassen, bzw. sogar schon die noch nicht geladenen Angrenzenden nachladen. Dort ebenfalls einen timestamp bzgl der Aktualität.

gepostet vor 16 Jahre von Tron

Hi,

der Thread ist ja nun schon was älter, aber ich vermiss hier offensichtliche Alternativen. Angenommen die Karte besteht aus Segmenten, die berechnet werden müssen, und weiterhin angenommen, es wird kein aktives (intelligentes) Caching benötigt, sondern ein gewisses definiertes Alter der Daten ist akzeptabel:

Wäre die performanteste Lösung nicht, reine Verweise in der Datenbank zu speichern, die Binärdaten in ihren bevorzugten Lebensraum, das Filesystem zu stecken, und einen handelsüblichen Squid oder Varnish davorzuhängen?

Der scheinbare "Nachteil" die Kartensegmente auf die Festplatte zu schreiben sehe ich nicht, außer es wird die legendäre Mysql-Ae verwendet, die Daten statt auf der Fesplatte im Aether speichert. An sich ist es gemeinhin keine artgerechte Haltung einer DB sie mit großen Binärblobs zu füttern. ;)

Gruß,

Stefan

gepostet vor 16 Jahre von _Jan_

Ich würde mich auch über jeden weiteren Post freuen. Da ich zur Zeit der einzige bin der Zugriff auf das System hat bin ich noch nicht am optimieren. Ich habe bisher lediglich die Planung etwas angepasst und das optimieren kommt erst wenn der Rest steht - also ich bin für alle Tips Tricks und Hinweise dankbar.

Auf diese Diskussion antworten