Frage

Ich habe ein Forum geschaffen, und wir eine apc und memcache Caching-Lösung sind die Umsetzung der Datenbank einige Arbeit zu speichern.

Ich begann die Cache-Ebene mit den Tasten wie „Kategorien :: getAll“ Umsetzung, und wenn ich benutzerspezifischen Daten hätte, würde ich die Schlüssel mit Sachen wie die Benutzer-ID anhängen, so würden Sie "User::getFavoriteThreads|1471" bekommen. Wenn ein Benutzer einen neuen Favoriten Thread hinzugefügt, würde ich den Cache Schlüssel löschen, und es würde den Eintrag neu erstellen.

Allerdings, und hier kommt das Problem:

Ich wollte die Threads in einem Forum cachen. Einfach genug, "Forum :: getThreads | $ iForumId". Aber ... Mit Paginierung, würde ich dies in mehr Cache-Einträge teilen, zum Beispiel

"Forum::getThreads|$iForumId|$iLimit|$iOffset".

Welche Ordnung ist, bis jemand einen neuen Thread im Forum postet. Ich werde nun alle Schlüssel unter "Forum::getThreads|$iForumId" löschen müssen, egal, was die Grenze und Offset ist.

Was wäre ein guter Weg, um dieses Problem zu lösen? Ich würde wirklich lieber nicht Schleife durch jede mögliche Grenze und Offset, bis ich etwas finden, das nicht mehr überein.

Danke.

War es hilfreich?

Lösung

Sie möchten vielleicht auch einen Blick auf die Kosten haben, um die Cache-Daten zu speichern, in Bezug auf Ihre Mühe und CPU-Kosten, gegen wie das, was der Cache Sie kaufen.

Wenn Sie, dass 80% des Forums Ansichten finden sind auf der ersten Seite der Threads suchen, dann könnten Sie sich entscheiden, nur die Seite cachen. Das würde bedeuten, beide Cache-Lese- und Schreibvorgänge sind viel einfacher zu implment.

Ebenso mit der Liste eines Liebling Threads des Benutzers. Wenn dies ist etwas, jede Person Besuche selten dann Cache Leistung nicht zu viel verbessern könnten.

Andere Tipps

Nur ein Update: Ich entschied, dass Joshs Punkt auf Datennutzung ein sehr gutes war. Die Menschen sind unwahrscheinlich Seite sehen halten 50 ein Forum.

auf der Grundlage dieses Modell, entschied ich mich, die 90 letzten Themen in jedem Forum cachen. In der Abruffunktion überprüfen I den Grenzwert und Offset, um zu sehen, ob die angegebene Scheibe Threads innerhalb Cache ist oder nicht. Wenn es innerhalb der Cache-Grenze ist, verwende ich array_slice () den rechten Teil abrufen und zurück.

Auf diese Weise kann ich einen einzelnen Cache-Schlüssel pro Forum nutzen, und es dauert sehr wenig Aufwand löschen / aktualisieren Sie den Cache: -)

Ich mag auch darauf hinweisen, dass ich in anderen ressourcen schwere Abfragen, mit flungabunga Modell ging, die Beziehungen zwischen den Tasten zu speichern. Leider wird nicht Stack-Überlauf lassen Sie mich zwei Antworten akzeptieren.

Danke!

Ich habe es geschafft, dieses Problem zu lösen, indem die memcache Klasse mit einer benutzerdefinierten Klasse erweitert (etwa ExtendedMemcache), die eine geschützte Eigenschaft hat, die eine Hash-Tabelle von Gruppe zu Schlüsselwerte enthalten wird.

Die ExtendedMemcache->set Methode akzeptiert 3 args ($strGroup, $strKey, $strValue) Wenn Sie mit Anruf, wird die Beziehung zwischen $strGroup speichern und $strKey, in dem geschützten Objekt und gehen Sie dann auf die $strKey speichern Beziehung in $strValue memcache.

Sie können dann eine neue Methode zur ExtendedMemcache Klasse hinzufügen namens „deleteGroup“, das wird, wenn eine Zeichenfolge übergeben, findet, dass die Schlüssel zu dieser Gruppe zugeordnet ist, und jede Taste wiederum spülen.

Es wäre so etwas wie dieses: http://pastebin.com/f566e913b Ich hoffe, dass alles, was Sinn und funktioniert für Sie macht.

PS. Ich nehme an, wenn Sie in gerettet werden konnte memcache sich unter seinem eigenen Schlüssel statischen Anrufe geschütztes Eigentum nutzen wollte. Nur so ein Gedanke.

Sie versuchen, im Wesentlichen eine Ansicht cachen, die immer schwierig bekommen werden. Sie sollten stattdessen auf Cache-Daten versuchen nur, weil die Daten nur selten ändern. Verwenden Sie kein Forum-Cache, die Thread-Zeilen-Cache. Dann sollten Sie Ihren db Anruf nur eine Liste von IDs zurückgeben, die Sie bereits in Ihrem Cache. Der db Anruf wird schnell auf jede MyISAM-Tabelle werden erleichtern, und dann haben Sie kein großes beitreten zu tun, was db Speicher frisst.

Eine mögliche Lösung ist nicht, den Cache von Threads in einem Forum Paginieren, sondern die Informationen Thread gestellt, um Forum::getThreads|$iForumId. Dann in Ihrem PHP-Code nur diejenigen herausziehen Sie für diese bestimmte Seite möchten, z.

$page = 2;
$threads_per_page = 25;
$start_thread = $page * $threads_per_page;

// Pull threads from cache (assuming $cache class for memcache interface..)
$threads = $cache->get("Forum::getThreads|$iForumId");

// Only take the ones we need
for($i=$start_thread; $i<=$start_thread+$threads_per_page; $i++)
{
    // Thread display logic here...
    showThread($threads[$i]);
}

Das bedeutet, dass Sie ein bisschen mehr Arbeit zu tun haben, sie auf jeder Seite zu tun ziehen, aber jetzt nur noch über den Cache ungültig zu machen an einem Ort auf dem neuen Thread Update / Ergänzung zu kümmern.

flungabunga: Ihre Lösung ist ganz in der Nähe zu dem, was ich suche. Das einzige, was mir zu tun, dies zu halten ist, die die Beziehungen in memcache nach jeder Anfrage zu speichern und laden sie zurück.

Ich bin mir nicht sicher, wie viel von einem Performance-Hit würde dies bedeuten, aber es scheint ein wenig ineffizient. Ich werde einige Tests machen und sehen, wie es aus Pfannen. Vielen Dank für einen strukturierten Vorschlag (und einige Codes für sie zu zeigen, danke!).

Seien Sie sehr vorsichtig über diese Art von Optimierung zu tun, ohne harte Fakten, die gegen zu messen.

Die meisten Datenbanken haben mehrere Ebenen von Caches. Wenn diese richtig eingestellt sind, wird die Datenbank wahrscheinlich eine viel bessere Arbeit bei Caching tun, als Sie selbst tun können.

Als Reaktion auf flungabunga:

Eine andere Möglichkeit Gruppierung zu implementieren, ist der Gruppenname und eine Sequenznummer in die Tasten selbst zu setzen und die laufende Nummer „clear“ der Gruppe zu erhöhen. Sie speichern die aktuell gültige Sequenznummer für jede Gruppe in einem eigenen Schlüssel.

z.

get seqno_mygroup
23

get mygroup23_mykey
<mykeydata...>
get mygroup23_mykey2
<mykey2data...>

Dann auf "löschen" die Gruppe einfach:

incr seqno_mygroup

Voila:

get seqno_mygroup
24

get mygroup24_mykey
...empty

etc ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top