2013-03-07 5 views
5

Mit Riak Ich möchte Daten der Reihe nach auf eine Weise anfügen, dass ich alle von Zeit zu Zeit angefügten Daten erhalten kann. Denken Sie an Protokolle, wenn ich inkrementierte Protokollzeilen auswähle und sie in riak übertrage, möchte ich irgendwann alles, was ich angehängt habe, neu erstellen.Wie fügt man Daten an einen Riak-Schlüssel in einer stark verteilten Umgebung an?

Ich dachte, dies zu tun, indem Sie einen neuen Eimer zu diesem Zweck erstellen, dann wird eine laufende Nummer bzw. Datums-Stempel definiert Schlüssel hinzufügen, und fügen Sie den Inhalt auf sie, dann die list keys API verwenden und die Daten, die ich brauche rekonstituieren. Das Problem dabei ist, dass die Listenschlüssel-API nicht effizient ist und die Produktion empfohlen wird. Was ich an diesem Ansatz mag, ist, dass die Daten keine Nebenläufigkeitsprobleme haben (keine Sperren/etc), da alle Schlüssel unabhängig sind.

Der andere Ansatz ist es, einen einzigen Schlüssel zu verwenden, öffnen Sie es und fügen Sie es an, aber Ich bin sehr besorgt durch Nebenläufigkeit/Sperren Probleme. Diese Aktion würde in einer verteilten Umgebung ausgeführt werden und wäre sicherlich eine schlechte Wahl

Frage: andere Möglichkeiten, das in Riak zu tun? Irgendein Append-Modus zu einem Schlüssel?

Antwort

10

Während das Schreiben vieler kleiner Datensätze in einen Bucket zum Schreibzeitpunkt einfach und effizient ist, zahlt es sich aus, dass es stattdessen teuer wird, wenn Sie versuchen, die Werte zu lesen, da Sie die Schlüssel wahrscheinlich nicht kennen. Wenn Sie diese Schlüssel mit einem Sekundärindex, Schlüsselfilter oder noch schlimmer durchsuchen müssen, indem Sie alle Schlüssel im Bucket durchlaufen (was eine sehr schwere Operation ist und niemals für eine Produktionsumgebung empfohlen wird), wird dies erheblich weniger effizient sein als das Abrufen der Daten nach Schlüssel und nicht skalieren.

Es gibt auch keine Append-Funktionalität in Riak, was bedeutet, dass Sie zuerst einen Datensatz lesen und dann schreiben müssen, um ihn zu aktualisieren und neue Protokolleinträge anzufügen. Abhängig davon, wie Sie Ihr Schreiben organisieren und koordinieren, kann dies, wie Sie feststellen, zu gleichzeitigen Aktualisierungen desselben Datensatzes führen, die beim Entwerfen einer Lösung berücksichtigt werden müssen.

Angenommen, die Aufzeichnungen, die Sie sammeln, z. Log-Einträge, kann als ein Satz behandelt werden, eine Technik, die ich empfehlen würde, ist Zeit-Boxen. Beim Zeitbacken aggregieren Sie Daten basierend auf einem Zeitraum. Wenn wir z.B. Angenommen, wir sammeln Protokolle für eine Gruppe von Servern (in diesem Beispiel benannter Server), können wir Datensätze mit Schlüsseln basierend auf der Server-ID und einer Datums-/Zeit-Kennung, z. der Beginn der Messperiode. Wir brauchen keinen vollständigen Zeitstempel, gerade genug, um uns die Aufzeichnung zu ermöglichen. Ein Datensatz, der Protokolleinträge für Server3 enthält, die den Zeitraum zwischen 14:15 und 14:20 Uhr am 2013/03/07 abdecken, könnte "server3_20130307_1415" genannt werden. Die folgenden 5 Minuten würden dann dementsprechend 'server3_20130307_1420' heißen. Wenn für einen Zeitraum keine Daten vorhanden sind, wird kein Datensatz erstellt.

Damit können Sie automatisch den Schlüssel für einen Datensatz für einen bestimmten Zeitraum kennen und können Datensätze abrufen, die ausschließlich auf Schlüsselzugriff basieren, was sehr gut skaliert und funktioniert. Sie müssen natürlich den Zeitraum, der von einem einzelnen Datensatz abgedeckt wird, abhängig von der Menge der von Ihnen generierten Daten anpassen, da Sie die Größe von Objekten in Riak im Allgemeinen unter 1-2 MB halten möchten. Es lohnt sich auch, Daten auf Anwendungsebene zu komprimieren, wenn jede Periode viele Daten enthalten würde, um diese empfohlene Größe zu erreichen.

Wenn Sie auf größere Datenblöcke zugreifen möchten, ohne eine potenziell große Anzahl von Datensätzen abrufen zu müssen, können Sie regelmäßig Datensätze aggregieren. Sie könnten z.B. Lesen Sie alle Aufzeichnungen über eine Stunde und schreiben Sie die aggregierten Daten in einen neuen Datensatz namens "server3_20130307_14", der den gesamten Zeitraum von 14: 00-15: 00 Uhr abdeckt. Wie Sie die Schlüssel wissen, ist dies einfach und einfach als Batch-Job zu implementieren.

Bei diesem Ansatz müssen Sie, wie bereits erwähnt, die Möglichkeit von gleichzeitigen Schreibvorgängen berücksichtigen. Der beste Weg, dies zu tun, ist meiner Meinung nach, indem ich Geschwister erlaube (setze 'allow_mult' auf 'true' und 'last_write_wins' auf 'false' für den Bucket mit Bucket-Eigenschaften [1]). Dies führt dazu, dass Riak im Falle von gleichzeitigen Aktualisierungen alle Versionen des Datensatzes beibehält, und Sie müssen stattdessen alle in der Anwendungsebene erstellten Geschwister auflösen, nachdem Sie einen Datensatz mit Geschwistern gelesen haben. Obwohl dies ein wenig Komplexität hinzufügt, wird sichergestellt, dass Sie keine Daten verlieren.

Da wir angenommen haben, dass die Protokolleinträge in diesem Fall als eine Menge behandelt werden können, können Sie die Mengen aller Geschwister über eine Vereinigungsmenge zusammenführen und dann das Objekt (mit der richtigen Vektoruhr) aktualisieren, um die Geschwister aufzulösen .

[1] http://docs.basho.com/riak/latest/references/apis/http/HTTP-Set-Bucket-Properties/

+0

danke. tolle Infos! – gextra

+0

Wie wäre es mit Hinzufügung von Append-Write-Funktionalität zu Riak? Kann nicht so schwer sein. Ich überprüfe trotzdem – senorcarbone

+2

Append-Write-Funktionalität wird schnell in einem Master-less, schließlich konsistente System ziemlich kompliziert, vor allem, wenn es ein Schlüssel-Wert-Speicher ist, der nicht davon ausgeht, dass Ihre Daten in einem bestimmten Format sind. Es gibt jedoch Arbeiten im Hinblick auf die Implementierung von CRDTs (https://github.com/basho/riak_dt), die es dem Benutzer ermöglichen, Datentypen zu konstruieren, die im Falle von Konflikten automatisch aufgelöst werden können, was die Art des Verhaltens liefern könnte Sie fordern an. –

Verwandte Themen