2012-06-06 13 views
10

Ich habe eine Website mit 500k Benutzer (auf SQL Server 2008 ausgeführt). Ich möchte jetzt Aktivitätsströme von Benutzern und ihren Freunden hinzufügen. Nach dem Testen einiger Dinge auf SQL Server wird offensichtlich, dass RDMS keine gute Wahl für diese Art von Feature ist. Es ist langsam (auch wenn ich meine Daten stark de-normalisierte). Nachdem ich mir andere NoSQL-Lösungen angesehen habe, habe ich mir gedacht, dass ich MongoDB dafür verwenden kann. Ich werde folgende Datenstruktur basierend auf activitystrea.ms json specifications for activity stream Also meine Frage ist: Was wäre das beste Schema-Design für Activity-Stream in MongoDB (mit diesen vielen Benutzern können Sie ziemlich genau sagen, dass es sehr schwer sein wird auf schreibt, daher meine Wahl von MongoDB - es hat große "writes" Leistung. Ich habe über 3 Arten von Strukturen gedacht, bitte sagen Sie mir, ob dies sinnvoll ist oder ich sollte andere Schemamuster verwenden.MongoDB Datenbank Schemadesign

1 - Speichern Sie jeweils Aktivität mit allen Freunden/Anhänger in diesem Muster:

 

    { 
    _id:'activ123', 
    actor:{ 
      id:person1 
      }, 
    verb:'follow', 
    object:{ 
      objecttype:'person', 
      id:'person2' 
      }, 
    updatedon:Date(), 
    consumers:[ 
      person3, person4, person5, person6, ... so on 
      ] 

    } 

2 - Zweiter Entwurf: Collectio n Name- activity_stream_fanout

 

    { 
    _id:'activ_fanout_123', 
    personId:person3, 
    activities:[ 
    { 
    _id:'activ123', 
    actor:{ 
      id:person1 
      }, 
    verb:'follow', 
    object:{ 
      objecttype:'person', 
      id:'person2' 
      }, 
    updatedon:Date(), 
    } 

    ],[ 
    //activity feed 2 
    ] 

    } 


3 - Dieser Ansatz die Aktivität Elemente in einer Sammlung zu speichern wäre, und die Verbraucher in einem anderen. In Aktivitäten, haben Sie vielleicht ein Dokument wie:

 

    { _id: "123", 
     actor: { person: "UserABC" }, 
     verb: "follow", 
     object: { person: "someone_else" }, 
     updatedOn: Date(...) 

    } 

Und dann, für Anhänger, würde ich die folgenden „Benachrichtigungen“ Dokumente haben:

 

    { activityId: "123", consumer: "someguy", updatedOn: Date(...) } 
    { activityId: "123", consumer: "otherguy", updatedOn: Date(...) } 
    { activityId: "123", consumer: "thirdguy", updatedOn: Date(...) } 

Ihre Antworten sehr geschätzt werden.

Antwort

20

I mit folgender Struktur gehen würde:

  1. Verwenden Sie eine Sammlung für alle Aktionen, die passiert, Actions

  2. eine weitere Sammlung verwenden für, wer wen folgt, Subscribers

  3. Verwenden Sie eine dritte Sammlung, Newsfeed für einen bestimmten Benutzer n ews feed, Artikel sind aus der Actions Sammlung aufgefächert.

Die Newsfeed Kollektion wird von einem Arbeitsprozess aufgefüllt werden, die asynchron neue Actions verarbeitet. Daher werden Nachrichtenfeeds nicht in Echtzeit ausgefüllt. Ich stimme Geert-Jan darin nicht zu, dass Echtzeit wichtig ist; Ich glaube, die meisten Benutzer interessieren sich nicht einmal für eine Minute Verzögerung in meisten (nicht alle) Anwendungen (für Echtzeit, würde ich eine völlig andere Architektur wählen).

Wenn Sie eine sehr große Anzahl von consumers haben, kann der Fan-out eine Weile dauern, stimmt. Auf der anderen Seite wird es nicht mit sehr großen Follower-Zählern funktionieren, die Konsumenten direkt in das Objekt zu bringen, und es werden übergroße Objekte erzeugt, die viel Indexraum beanspruchen.

Am wichtigsten ist jedoch die Fan-out-Design ist viel flexibler und ermöglicht Relevanz Scoring, Filtern, usw. Ich habe gerade vor kurzem einen Blog-Post über news feed schema design with MongoDB geschrieben, in dem ich einen Teil dieser Flexibilität näher erläutern.

Apropos Flexibilität, ich wäre vorsichtig mit dieser activitystrea.ms spec. Es scheint als eine Spezifikation für Interop zwischen verschiedenen Anbietern sinnvoll zu sein, aber ich würde all diese ausführlichen Informationen nicht in meiner Datenbank speichern, solange Sie nicht beabsichtigen, Aktivitäten aus verschiedenen Anwendungen zu aggregieren.

+0

große Vorschläge. Mit Realtime meinte ich nicht Subsecond, ich meinte nur Realtime so schnell, dass Sie nicht viel von "Batching" mehrerer Benutzeraktivitäten in Szenario 2 vom OP bekommen würden. Andererseits bin ich nicht vertraut mit dem Begriff "Fanout" (auf den sich die zweite Option des OP bezieht, und Sie erwähnen das auch), so dass ich die Absichten von 2 möglicherweise nicht vollständig verstanden habe. .. Btw: Gehen, um diesen Blogpost zu lesen, immer gut, architektonische Beiträge auf MongoDB Schema Design zu sehen –

+0

groß zu lesen, habe ich einen Kommentar auf Ihrem Blog mit einer verwandten Frage, die Sie lesen möchten. Danke –

+1

Jungs, vielen Dank für die Vorschläge. Ich markiere @mnemosyn Beitrag als Antwort, da es Sinn macht. Ich werde deinen Blog lesen und sehen, wo es mich hinführt. Nochmals vielen Dank ein Protokoll für alle Ihre Vorschläge. –

1

Ich glaube, Sie an Ihrem Zugriffsmuster aussehen sollte: Welche Anfragen sind Sie wahrscheinlich die meisten dieser Daten durchzuführen, usw.

mir die Use-Case, das schnellste sein muss in der Lage sein ein schieben bestimmte Aktivität an die "Wand" (in fb Bedingungen) von jedem der "Aktivität Verbraucher" und tun es sofort, wenn die Aktivität kommt.

Von diesem Standpunkt (ich habe nicht viel darüber nachgedacht) würde ich gehen Sie mit 1, da 2. scheint Aktivitäten für einen bestimmten Benutzer zu Batch vor der Verarbeitung? Dadurch wird der 'sofortige' Bedarf an Updates nicht erfüllt. Außerdem sehe ich den Vorteil von 3. über 1 für diesen Anwendungsfall nicht.

Einige Verbesserungen auf 1? Fragen Sie sich, ob Sie wirklich die Flexibilität benötigen, für jede Aktivität eine Reihe von Konsumenten zu definieren. Ist es wirklich notwendig, dies auf dieser feinkörnigen Skala zu spezifizieren? statt dessen würde ein Hinweis auf die "Freunde" des "Schauspielers" nicht ausreichen? (Dies würde auf lange Sicht viel Platz beanspruchen, da ich feststelle, dass das Verbraucher-Array der Hauptteil der gesamten Nachricht für jede Aktivität ist, wenn die Verbraucher typischerweise in den Hunderten (?) Liegen.

Je nachdem, wie Sie Echtzeit-Benachrichtigungen für diese Activity-Streams implementieren möchten, kann es sich lohnen, Pusher - http://pusher.com/ und ähnliche Lösungen zu betrachten.

hth