MongoDB-Schema-Design - Echtzeit-Chat
Fange ich ein Projekt, von dem ich glaube, dass Sie besonders gut geeignet, um MongoDB aufgrund der Geschwindigkeit und Skalierbarkeit, die es gewährt.
Dem Modul bin ich derzeit daran interessiert ist, zu tun, Echtzeit-chat. Wenn ich dies in einem traditionellen RDBMS-ich würde es teilen, in:
- Kanal (Ein Kanal hat viele Benutzer)
- Benutzer (Ein Benutzer hat einen Kanal aber viele Nachrichten)
- Nachricht (Eine Nachricht eines Benutzers)
Den Zweck dieser use-case ist, würde ich gerne davon ausgehen, dass es in der Regel 5 Kanäle gleichzeitig aktiv, mit jeweils maximal 5 Nachrichten pro Sekunde.
Spezifische Abfragen, die müssen schnell sein:
- Abrufen neuer Nachrichten (basierend auf einem Lesezeichen, Zeitstempel vielleicht, oder einem inkrementierenden Zähler?)
- Post eine Nachricht an einen Kanal
- Überprüfen, die ein Benutzer kann die post in einem Kanal
Bedenkt, dass das Dokument limit mit MongoDB von 4mb, wie würden Sie gehen über das entwerfen des Schemas? Was würde deins Aussehen? Gibt es irgendwelche Fallstricke, die ich achten sollten?
InformationsquelleAutor der Frage Nick | 2010-05-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich verwendet RedisNGINX & PHP-FPM für mein chat-Projekt. Nicht super elegant, aber es funktioniert der trick. Es gibt ein paar Stücke, um das puzzle.
Es ist ein sehr einfaches PHP-Skript erhält, dass die client-Befehle und setzt Sie in eine große LISTE. Es wird auch überprüft, alle Zimmer Listen und die Benutzer private LISTE, um zu sehen, ob es Nachrichten, die Sie liefern müssen. Dies ist eine Abfrage durch einen client geschrieben in jQuery & es ist getan, alle paar Sekunden.
Es ist ein Kommandozeilen-PHP-Skript, das funktioniert server-Seite in einer endlos-Schleife, die 20 mal pro Sekunde, die überprüft diese Liste, und verarbeitet diese Befehle. Das Skript behandelt, wer in welchem Zimmer und Berechtigungen in den scripts-Speicher ist diese Information nicht gespeichert in Redis.
Redis hat eine LISTE für jedes Zimmer & eine LISTE für jeden Nutzer, der arbeitet wie ein eigenes queue. Es hat auch mehrere Zähler für jeden Raum der Benutzer ist. Wenn der Benutzer Zähler weniger als die Gesamtzahl der Nachrichten in den Raum, dann ruft er den Unterschied aus und sendet es an den Benutzer.
Habe ich noch nicht in der Lage, stress-test dieser Lösung, aber zumindest von meiner basic-benchmarking, könnte es wohl so behandeln viele Tausende von Nachrichten pro Sekunde. Es gibt auch die Möglichkeit zum Anschluss dieser über etwas wie Node.js um die Leistung zu erhöhen. Redis ist auch fällig und hat einige interessante features wie Pub/Subscribe-Befehle, die von Interesse sein könnten, wäre das möglicherweise entfernen Sie die polling auf server-Seite möglich.
Ich sah in Kometen-basierte Lösungen, aber viele von Ihnen waren kompliziert, schlecht dokumentiert oder würde von mir verlangen, zu lernen, eine völlig neue Sprache(z.B. Steg->Java -, APE->C),etc... Auch die Lieferung und die gehen über Proxys kann manchmal ein Problem mit dem Kometen. So dass ist, warum ich habe fest mit polling.
Ich glaube, Sie können tun, etwas ähnliches mit MongoDB. Eine Sammlung pro Zimmer, eine Kollektion pro user & dann eine Sammlung, die unterhält Zähler. Du musst noch schreiben, eine back-end-daemon oder ein Skript zu behandeln manging wo diese Nachrichten gehen. Sie können auch mithilfe von MongoDB ist die "limited collections", die hält die Dokumente sortiert & auch löscht automatisch alte Nachrichten, aber das könnte kompliziert werden, in die Aufrechterhaltung der richtigen Leistungsindikatoren.
InformationsquelleAutor der Antwort Klinky
Warum mongo für ein messaging-system? Egal wie schnell der statische Speicher ist (und mongo ist sehr schnell), ob mongo oder db, zu imitieren, eine message queue mit Ihr zu haben, um mit irgendeiner Art von polling, das ist nicht sehr skalierbar und effizient. Gewährt, du bist nicht etwas zu tun, schrecklich Intensive, aber warum nicht einfach das richtige Werkzeug für den richtigen job? Ein messaging-system wie Kaninchen oder ActiveMQ.
Wenn Sie verwenden müssen mongo (vielleicht wollen Sie nur zu spielen, um mit es, und dieses Projekt ist eine gute Möglichkeit, das zu tun?) Ich denke, Sie haben eine Sammlung für den Benutzer (jeder Benutzer hat ein Objekt eine Liste der Warteschlangen, die Anwender hört). Für Nachrichten, Sie könnten eine Sammlung für jede Warteschlange, aber dann würden Sie haben, um Abfragen für jede Warteschlange, der Sie interessiert sich für Nachrichten. Besser wäre es, einen einzigen Sammlung wie eine Schlange, wie es einfach in mongo zu tun, "in" - Abfragen auf einer einzigen Sammlung, so wäre es leicht, Dinge zu tun wie "erhalten Sie alle Nachrichten, die neuer als X in Warteschlangen, wo die Warteschlange.Namen in Liste [a,b,c]".
Könnten Sie auch erwägen Sie, Ihre Sammlung wie ein mongo capped-collection, die nur bedeutet, dass Sie sagen, mongo, wenn Sie der Sammlung, Ihre Sammlung sollte nur halten Sie X Anzahl der bytes, oder X Anzahl der Elemente. Hinzufügen von zusätzlichen Elemente First-In-First-Out-Verhalten, das ist ziemlich ideal für eine message-queue. Aber wieder, es ist nicht wirklich ein messaging-system.
InformationsquelleAutor der Antwort Steve B.
1) ape-project.org
2) http://code.google.com/p/redis/
3) nachdem Sie durch all dies - Sie können die stumm-Daten in mongodb für die Datenerfassung und speichern auf konsistente Daten (Benutzer, Kanäle) als auch
InformationsquelleAutor der Antwort Toby