5

Ich entwerfe ein System, das große Anzahl von Benutzertransaktionen analysieren und aggregierte Kennzahlen (wie Trends und usw.) produzieren sollte. Das System sollte schnell arbeiten, robust und skalierbar sein. System ist Java-basiert (unter Linux).Echtzeit-Analyse-Prozess-System-Design

Die Daten stammen von einem System, das Protokolldateien (CSV-basiert) von Benutzertransaktionen generiert. Das System generiert jede Minute eine Datei und jede Datei enthält die Transaktionen verschiedener Benutzer (sortiert nach Zeit), jede Datei kann Tausende von Benutzern enthalten.

Eine beispielhafte Datenstruktur für eine CSV-Datei:

10: 30: 01, Benutzer 1, ...
10: 30: 01, Benutzer 1, ...
10.30.02 , Benutzer 78, ...
10: 30: 02, Benutzer 2, ...
10: 30: 03, Benutzer 1, ...
10: 30: 04, Benutzer 2, ...
. . .

Das System, das ich plane, sollte die Dateien verarbeiten und einige Analysen in Echtzeit durchführen. Er muss die Eingabe sammeln, sie an mehrere Algorithmen und andere Systeme senden und die berechneten Ergebnisse in einer Datenbank speichern. Die Datenbank enthält nicht die tatsächlichen Eingabedatensätze, sondern nur eine aggregierte Analyse auf hoher Ebene über die Transaktionen. Zum Beispiel Trends und etc.

Der erste Algorithmus, den ich verwenden möchte, erfordert für den besten Betrieb mindestens 10 Benutzerdatensätze, wenn er nach 5 Minuten keine 10 Datensätze finden kann, sollte er die verfügbaren Daten verwenden.

Ich würde gerne Storm für die Implementierung verwenden, aber ich würde es vorziehen, diese Diskussion in der Design-Ebene so viel wie möglich zu verlassen.

Eine Liste von Systemkomponenten:

  1. Eine Aufgabe, die jede Minute eingehende Dateien überwacht.

  2. Eine Aufgabe, die die Datei liest, analysiert und für andere Systemkomponenten und Algorithmen verfügbar macht.

  3. Eine Komponente zum Puffern von 10 Datensätzen für einen Benutzer (nicht länger als 5 Minuten), wenn 10 Datensätze gesammelt wurden oder 5 Minuten vergangen sind, ist es Zeit, die Daten zur weiteren Verarbeitung an den Algorithmus zu senden. Da die Anforderung ist, mindestens 10 Datensätze für den Algorithmus zu liefern, dachte ich über Storm Field Grouping (was bedeutet, dass die gleiche Aufgabe für den gleichen Benutzer aufgerufen wird) und verfolgen die Sammlung von 10 Benutzerdatensätzen innerhalb der Aufgabe, natürlich ich Planen Sie mehrere dieser Aufgaben, jeder behandelt einen Teil der Benutzer.

  4. Es gibt andere Komponenten, die an einer einzigen Transaktion arbeiten, für die ich andere Aufgaben erstellen möchte, die jede Transaktion erhalten, während sie geparst wird (parallel zu anderen Aufgaben).

Ich brauche Ihre Hilfe mit # 3.

Was ist die beste Vorgehensweise für den Entwurf einer solchen Komponente? Es ist offensichtlich, dass es die Daten für 10 Datensätze pro Benutzer pflegen muss. Eine Schlüsselwertzuordnung kann hilfreich sein. Ist es besser, die Zuordnung in der Aufgabe selbst zu verwalten oder einen verteilten Cache zu verwenden? Zum Beispiel Redis ein Schlüssel Wert speichern (ich habe es noch nie zuvor verwendet).

Danke für Ihre Hilfe

Antwort

5

Ich hatte mit Redis ziemlich viel gearbeitet. Also, ich auf dem Gedanken äußern werde redis der Verwendung

# 3 hat 3 Anforderungen

  1. Buffer pro Benutzer

  2. Puffer für 10 Aufgaben

  3. Sollten alle 5 min Ablaufen

1. Puffer P er Benutzer: Redis ist nur ein Schlüsselwertspeicher. Obwohl es eine breite Palette von datatypes unterstützt, werden immer Werte einem STRING-Schlüssel zugeordnet. Sie sollten also entscheiden, wie Sie einen Benutzer eindeutig identifizieren können, wenn Sie pro Benutzer Puffer benötigen. Weil In redis nie ein Fehler auftritt, wenn Sie einen neuen Schlüsselwert überschreiben. Eine Lösung könnte die Existenz vor dem Schreiben sein.

2. Puffer für 10 Aufgaben: Sie können offensichtlich eine queue in Redis implementieren. Aber die Beschränkung seiner Größe bleibt Ihnen überlassen. Beispiel: Verwenden Sie LPUSH und LTRIM oder Verwenden Sie LLEN, um die Länge zu überprüfen und zu entscheiden, ob Ihr Prozess ausgelöst werden soll. Der mit dieser Warteschlange verknüpfte Schlüssel sollte derjenige sein, den Sie in Teil 1 festgelegt haben.

3. Puffer läuft in 5 min ab: Dies ist eine der schwierigsten Aufgaben. In redis kann jeder Schlüssel ungeachtet des zugrunde liegenden Datentyps einen expiry haben. Aber der Ablaufprozess ist still. Sie werden bei Ablauf eines Schlüssels nicht benachrichtigt. Wenn Sie diese Eigenschaft verwenden, werden Sie Ihren Puffer stillschweigend verlieren. Man arbeitet dafür, einen Index zu haben. Bedeutet, dass der Index den Schlüsseln, die alle zu diesem Zeitstempelwert abgelaufen sein müssen, einen Zeitstempel zuordnet. Dann können Sie im Hintergrund jede Minute den Index lesen und die Taste [nach dem Lesen] manuell aus redis löschen und Ihren gewünschten Prozess mit den Pufferdaten aufrufen. Um einen solchen Index zu haben, können Sie sich Sorted Sets ansehen. Der Zeitstempel ist score und member wird die Schlüssel sein [eindeutiger Schlüssel pro Benutzer, der in Teil 1 festgelegt wurde, der einer Warteschlange zugeordnet ist], den Sie zu diesem Zeitpunkt löschen möchten. Sie können zrangebyscore tun alle eingestellten Mitglieder mit bestimmten Zeitstempel

Overall zu lesen:

Verwenden Redis Liste eine Warteschlange zu implementieren.

Verwenden Sie LLEN, um sicherzustellen, dass Sie Ihr 10-Limit nicht überschreiten.

Immer wenn Sie eine neue Liste erstellen, machen Sie einen Eintrag im Index [Sorted Set] mit Score als Current Timestamp + 5 min und Value als Listenschlüssel.

Wenn LLEN 10 erreicht, denken Sie daran zu lesen, dann entfernen Sie den Schlüssel aus dem Index [sortierte Gruppe] und aus der db [löschen Sie die Schlüssel-> Liste]. Dann triggern Sie Ihren Prozess mit Daten.

Für jede Minute, generieren aktuellen Zeitstempel, lesen Sie den Index und für jeden Schlüssel, lesen Sie Daten, dann entfernen Sie den Schlüssel aus db und lösen Sie Ihren Prozess.

Dies könnte meine Art sein, es zu implementieren. Es könnte eine andere bessere Möglichkeit, um Ihre Daten in redis

0

Für Ihre Anforderungen 1 & 2 Modell: [Apache Flume oder Kafka]

Für Ihre Anforderung # 3: [Esper Bolt innen Sturm. Um dies zu erreichen, müssen Sie in Redis die Esper Logic neu schreiben.]