5

Situation:Event-Feed-Implementierung - wird es skalieren?

Ich bin derzeit ein Zuführsystem für eine soziale Website entwerfen, wobei jeder Benutzer einen Feed ihrer Freunde Aktivitäten. Ich habe zwei mögliche Methoden, um die Feeds zu generieren, und ich möchte fragen, was am besten in Bezug auf die Skalierbarkeit ist.

Ereignisse von allen Benutzern werden in einer zentralen Datenbanktabelle event_log gesammelt. Benutzer werden als Freunde in der Tabelle friends gepaart. Das RDBMS, das wir verwenden, ist MySQL.

Standardmethode: Wenn ein Benutzer seine Vorschub Seite anfordert, erzeugt das System die Zufuhr von inneren event_log mit friends verbinden. Das Ergebnis wird dann zwischengespeichert und nach 5 Minuten auf Timeout gesetzt. Die Skalierung wird durch Variieren dieses Zeitlimits erreicht.

hypothetisierten Methode: Eine Task im Hintergrund ausgeführt wird und für jedes neues, nicht verarbeitete Element in event_log, erstellt es Einträgen in der Datenbank-Tabelle user_feed dieses Ereignisses mit allen Benutzern Paarung, die Freunde mit dem Benutzer sind, initiiert das Ereignis. Eine Tabellenzeile verbindet ein Ereignis mit einem Benutzer.

Die Probleme mit der Standardmethode sind bekannt - was wäre, wenn viele Caches von Personen gleichzeitig ablaufen würden? Die Lösung skaliert auch nicht gut - die Aufgabe besteht darin, Feeds so nahe wie möglich in Echtzeit zu aktualisieren

Die hypothetische Lösung in meinen Augen scheint viel besser; Die gesamte Verarbeitung erfolgt offline, sodass kein Benutzer darauf wartet, dass eine Seite generiert wird, und keine Joins vorhanden sind, sodass Datenbanktabellen über physische Maschinen hinweg erstellt werden können. Wenn ein Benutzer jedoch 100.000 Freunde hat und 20 Ereignisse in einer Sitzung erstellt, führt dies dazu, dass 2.000.000 Zeilen in die Datenbank eingefügt werden.

Frage:

Die Frage auf zwei Punkte läuft darauf hinaus:

  • Ist das Worst-Case-Szenario oben problematisch erwähnt, dh nicht Tabellengröße einen Einfluss auf die Performance von MySQL haben und gibt es Probleme mit dieser Masseneinfügung von Daten für jedes Ereignis?
  • Gibt es noch etwas, das ich verpasst habe?
+2

wird es mischen !!! –

Antwort

1

Ich denke, dass Ihr hypothetisches System zu viele Daten generiert; Erstens scheinen die Speicher- und Indizierungsanforderungen für user_feed auf globaler Ebene exponentiell zu steigen, wenn Ihre Benutzerbasis größer und stärker vernetzt wird (beides vermutlich für ein soziales Netzwerk wünschenswert); Zweitens, wenn im Laufe einer Minute 1000 Benutzer eine neue Nachricht eingegeben haben und jeder 100 Freunde hat - dann hat Ihr Hintergrund-Thread 100 000 Einfügungen zu tun und könnte schnell zurückfallen.

Ich frage mich, ob ein Kompromiss zwischen Ihren beiden vorgeschlagenen Lösungen gefunden werden könnte, wo ein Hintergrundthread eine Tabelle last_user_feed_update aktualisiert, die eine einzelne Zeile für jeden Benutzer und einen Zeitstempel für den letzten Feedwechsel enthält.

Dann, obwohl die vollständige Join und Abfrage erforderlich wäre, um den Feed zu aktualisieren, wird eine schnelle Abfrage in die last_user_feed-Tabelle feststellen, ob eine Aktualisierung erforderlich ist oder nicht.Dies scheint die größten Probleme mit Ihrer Standardmethode zu mildern und die Probleme mit der Speichergröße zu vermeiden, aber dieser Hintergrund-Thread hat noch viel zu tun.

+0

Andererseits enthält die Tabelle 'user_feed' nur zwei Spalten 'event_log_id' und' user_id' und der Primärschlüssel befindet sich in diesen beiden Spalten. Jede Zeile hat also 8 Bytes, das sind also nur 800 KB für das von Ihnen beschriebene Szenario. Wenn es ein Problem ist, kann diese Tabelle auf einem völlig separaten Server gespeichert werden oder sogar die Tabelle auf verschiedene Server für ungerade/gerade Benutzer aufgeteilt werden. Tut mir leid, ich bin nur Devil's Advocate, aber ich bin immer noch nicht überzeugt. – SlappyTheFish

+0

Auch das Zurückfallen ist kein Problem, die Seiten werden weiterhin bedient und wenn die Daten während der Spitzenzeiten (die einmal am Tag auftreten) alt sind, kann es später aufholen. Ok, genug reden - ich werde ein paar Tests machen. – SlappyTheFish

+0

Verstehen Sie Ihre Kommentare; Ich würde auch einige Tests versuchen und sehen, wie es in der Praxis funktioniert – Elemental

0

Die Hypothesized-Methode funktioniert besser, wenn Sie die maximale Anzahl von Freunden begrenzen .. viele Websites legen eine sichere obere Grenze, einschließlich Facebook Iirc. Es begrenzt "Schluckauf", wenn Ihr 100K Freunde-Benutzer Aktivität generiert.

Ein weiteres Problem mit dem hypothetischen Modell ist, dass einige der Freunde, die Sie im Wesentlichen Cache generieren für anmelden und fast nie anmelden. Dies ist eine ziemlich häufige Situation für freie Websites, und Sie möchten vielleicht begrenzen Belastung, die diese inaktiven Benutzer kosten.

Ich habe viele Male über dieses Problem nachgedacht - es ist kein Problem, das MySQL lösen kann. Ich habe über Möglichkeiten nachgedacht, wie ich memcached verwenden könnte und jeder Benutzer schiebt, was seine letzten paar Statuselemente zu "ihrem Schlüssel" sind (und in einer Feed-Leseaktivität holen und aggregieren Sie alle Schlüssel Ihres Freundes) ... aber ich habe nicht getestet dies. Ich bin mir noch nicht sicher, ob es überhaupt Vorteile gibt.

Verwandte Themen