2017-02-16 3 views
0

Dies ist eine Frage für PHP/Laravel + Redis, aber ich bin sicher, dass es auf andere Sprachen/Frameworks hochgerechnet werden kann.Optimierte Möglichkeit, eine Ergebnisliste zwischenzuspeichern?

Ich arbeite an einer App, die Ergebnisse anzeigt (entweder von einer vom Benutzer initiierten Suche oder einer Kategorieliste). Standardmäßig paginieren wir 30 Ergebnisse pro Seite.

Ich benutze Redis, um alle Ergebnisse zwischenzuspeichern, aber ich habe ein paar Probleme zu optimieren. Zuerst habe ich die gesamte Ergebnismenge mit den Objekten (Produkten) zwischengespeichert, die vollständig in der Ergebnismenge gespeichert waren (also im Grunde war jede Ergebnisliste ein riesiger Cache-Eintrag von 30 Datenobjekten). Dies war in Ordnung, aber die Speichernutzung wurde erhöht, da Objekte in mehreren verschiedenen zwischengespeicherten Objekten gespeichert wurden (ein Produkt konnte sowohl in mehreren Suchergebnissen als auch in Kategorien angezeigt werden - und jedes Objekt wurde dann einzeln zwischengespeichert).

Auch das andere Problem ist, da wir unterschiedliche Paginierung bei verschiedenen Zählungen zulassen, müssen wir bei anderen Objektzählungen auch zwischenspeichern.

Also was ich als nächstes versuchte, war nur eine Liste von Objekt-IDs für jede Seite zwischenzuspeichern. Dies verringerte die Speicherauslastung erheblich, jedoch mussten wir jedes Mal, wenn eine Seite geladen wurde, die 30 Objekte durchlaufen und sie aus dem Cache abrufen und dann neu erstellen. Bei ungefähr 50 ms pro Objekt (was hoch erscheint) kann es bis zu 1,5 Sekunden zum Seitenladen betragen. Selbst wenn wir die Objekterstellung weiter optimieren, wird dem Laden/Rendern der Seite noch eine gewisse Zeit hinzugefügt.

Unser nächster Ausflug ist HTML-Caching (Cloudflare/Varnish, etc.), was uns dazu bringen wird, bestimmte Aspekte der App neu zu gestalten, was in Ordnung ist. Allerdings frage ich mich, ohne HTML-Cache ist ihre Art, dies zu optimieren (oder was ist die optimale Methode zu tun, was wir tun wollen?). Das andere Problem, das ich habe, ist, während ich weiß, dass PHP-Skripte bei jeder Anfrage ausgeführt werden. Warum können wir Objekte zwischen den Ausführungen nicht als POPO (Plain Old PHP Objects) verwalten? Es erscheint mir zu diesem Zeitpunkt albern, dass wir Objekte im Jahr 2017 immer noch serialisieren und deserialisieren. Ich hätte gerne eine Hintergrund-PHP-App, die die benötigten Objekte verwaltet und sie bei Bedarf an jedes Skript übergeben kann.

Zum Beispiel ändert sich ein Produkt nicht viel vom Laden der Seite zum Laden der Seite. Warum sollte das gleiche Produktobjekt hunderte Male pro Minute neu erstellt werden - selbst wenn es aus dem Cache stammt?

+0

Dumme Frage Warnung, aber in Ihrem zweiten Versuch, warum schleifen Sie durch die Objekte, anstatt sie alle auf einmal zu bekommen? Töne von deiner Beschreibung wie das würden dich ziemlich viel Zeit sparen. Eine andere erwähnenswerte Lösung besteht darin, die Daten in das zu transformieren, was Sie tatsächlich benötigen, und diese nur im Cache anstatt der gesamten Objekte zu speichern. Sie könnten das leicht mit z. Fraktal. –

Antwort

0

Ich hätte gerne eine Hintergrund-PHP-App, die die erforderlichen Objekte verwaltet und sie bei Bedarf an jedes Skript übergeben kann.

Sie können das nicht tun, da separate Anwendungen keinen gemeinsamen Bereich haben (sie teilen nicht einmal Speicher). Ihre Hintergrund-App müsste also die Objekte in einer Zwischenform übergeben. Ja, du hast es erraten. Serialisierung

Was Sie können tun ist einige Dienste oder der HTML-generierten Teil zu trennen, so dass sie vollständig nur mit einem bestimmten Objekt zugeordnet sind. An diesem Punkt können Sie möglicherweise eine Hintergrundanwendung haben, die Object Brokering ausführt. Ein Objekt wird gerendert, indem der Broker mit der Objekt-ID aufgerufen und nach seinem HTML gefragt wird, und der Broker kann entweder das Objekt oder das gerenderte HTML zwischenspeichern, je nachdem, was am besten ist.

Da der HTML-Code nicht serialisiert werden muss, sollte diese Methode sehr effizient sein.

Sie könnten sogar in der Lage sein, dies durch AJAX zu tun: ein Objekt ist „pre-rendered“ als AJAX-Platzhalter mit geeigneter Größe und Animation „Bitte warten“

<div class="Placeholder Product"></div> 

und dann einer Reihe von parallelen jQuery Aufrufe animiert die Objekte.

Ich tat dies (für ein Pagination Dings, gehe Figur) und bekam sehr gute Ergebnisse mit einer verrückten Animation, die als schrecklich unscharfes Suchergebnis begann, das allmählich in den Fokus kam (kein Radfahren natürlich). Dies geschah so langsam, dass der AJAX-Aufruf inzwischen aufgelöst wurde und das reale Objekt eingeblendet wurde. Die Objekte waren so ähnlich, dass Sie nur selten feststellten, dass das unfokussierte Bild und das endgültige Objekt nicht wirklich verwandt waren und der Benutzer im Durchschnitt nicht bemerke nicht, dass die Objekte, die hinter den ersten zwei oder drei liegen, noch nicht gerendert wurden - er sah die ganze Ergebnisseite sofort erscheinen und dachte, dass alle Ergebnisse da waren. Die Objekte wurden auch lokal zwischengespeichert, so dass das Paging vor und zurück den Server nicht mehr als einmal belastet hat.

Verwandte Themen