5

Ich habe eine Liste von Benutzern, die nur Administratoren sehen können (= wenige Lesevorgänge). In dieser Liste wird auch die Anzahl der Benutzer im Datenspeicher angezeigt. Da die Liste größer als 1000 werden konnte, war mein erster Gedanke, einen normalen count() zu vermeiden und stattdessen einen Sharded Counter zu verwenden.Wie baue ich einen flexiblen Counter mit mehr als 1000 Zeilen, aber wenig Reads in Google App Engine?

Das Problem ist jedoch, dass die Admins haben auch Zugriff auf verschiedene Suchfilter (in der GUI), wie nur männliche/weibliche Benutzer anzeigen und so weiter. Es ist wichtig, dass die Anzahl diese Filter widerspiegelt, so dass sie die Anzahl weiblicher Benutzer, männlicher Benutzer und eine Vielzahl anderer Kombinationen erhalten können.

Aus diesem Grund scheint sharded Counters und hohe Concurrency-Zähler ohne Sharding keine gute Idee, da ich für jede Kombination von Suchfiltern einen Zähler erstellen müsste.

Sollte ich einfach eine Schleife von count() Methoden erstellen, wie beschrieben here oder ist das sehr schlechte Praxis? Wie würde ich es sonst machen?

Beachten Sie, dass dieser Zähler für eine Admin-Schnittstelle und eine sehr begrenzte Anzahl von Lesevorgängen hat. Dies ist wirklich ein Fall von, wenn ich etwas Leseleistung für Flexibilität und Genauigkeit opfern möchte. Obwohl es in der Lage sein sollte, über 1000 zu wachsen, sollte es nicht größer als 10 000 werden.

Antwort

2

"Loop of counts" ist langsam, aber heutzutage können Sie es mit cursors ein bisschen besser machen. Normalerweise würde ich Denormalisierung in allen "gefilterten" Zählern empfehlen, die Sie benötigen, aber das verlangsamt das Hinzufügen und Löschen von Benutzern (und wahrscheinlich auch die demografischen Änderungen), so dass Sie Ihren eigenen Anwendungsfall mit einem sehr geringen Leseaufkommen wahrscheinlich haben kommen Sie mit der "Schleife der Zählungen" Ansatz (plus Cursor ;-).

+0

Danke für Ihre Antwort! Ja, ich bin von diesem Ansatz verleitet, wenn ich bedenke, dass ich sehr wenige Lesevorgänge haben werde und ich bin mir nicht einmal sicher, ob die Liste 1000 überschreiten wird. Wenn Sie über Cursor sprechen, meinen Sie, dass ich Cursor verwenden sollte, um die nächste Position zu bestimmen() – Aneon

2

Ich habe zwei Ansätze versucht:

1) meine eigene Aufgabe schreiben, die auf den Datenspeicher abfragt (die Abfrage ist eine Schlüsselabsteigenden Abfrage) mit einem festen Grenzwerte von Einheiten (etwa 50). Dann reiht es die nächste Task in die Warteschlange ein, um mit der Abfrage anzufangen, wo es aufgehört hat. Jede Aufgabe reiht die nächste in die Warteschlange ein und übergibt ihr zwei Parameter (wo sie zuletzt wie ein Cursor und eine laufende Summe der Anzahl von Entitäten aufgehört hat, die sie gesehen hat).

2) Dieser Ansatz ist viel einfacher - und das ist die Mapreduce-Bibliothek von Google für Appengine verwenden. Es läuft vollständig im Benutzerbereich, also müssen Sie nur die Bibliothek herunterladen und erstellen und in Ihr Projekt einbinden. Im Grunde wird es die Iteration durch alle von Ihnen spezifizierten Entitäten handhaben und Sie können einen Handler schreiben, um zu bestimmen, was mit jedem einzelnen zu tun ist (wie zB einen Zähler inkrementieren). Sehen Sie die Details hier: mapreduce.appspot.com - sie haben sogar eine Beispiel-App, die genau das tut, wonach Sie fragen. Das einzige Problem dabei ist, dass die Ergebnisse in Ihrem Browser angezeigt werden und nicht unbedingt im Datenspeicher gespeichert werden, wenn Sie dies nicht selbst tun.

+0

Der zweite hier beschriebene Ansatz, der eine MapReduce verwendet, um regelmäßig alle wichtigen Statistiken neu zu berechnen, scheint der beste Ansatz zu sein. –

+0

Oh, ich habe noch nie zuvor von MapReduce gehört, muss mich darum kümmern. Würde dieser Ansatz mir volle Genauigkeit geben oder muss er regelmäßig aktualisiert werden (wie Zähler mit hoher Parallelität ohne Sharding, der die Task-Warteschlange verwendet)? Und muss ich alle möglichen Filterkombinationen einrichten, die ich manuell zählen möchte? – Aneon

+0

Nun, wenn sich die Anzahl der Entitäten, die Sie haben, während der Kartenreduzierung ändert, werden diese Entitäten nicht gezählt. Das Map Reduce nimmt grundsätzlich einen Snapshot zu einem bestimmten Zeitpunkt auf. In werden Sie nicht in Echtzeit die Zahl der Entitäten, die Sie in einem bestimmten Moment haben, zählen.Ich benutze es, um am Ende jeden Tages Statistiken zu erstellen. – aloo