Wie können Schlüssel in einem Schlüsselwertspeicher verwaltet werden?

8

Versuch, eine Richtlinie für Schlüssel in einem Schlüssel / Wert-Speicher zu definieren (wir verwenden Redis). Der Schlüsselraum sollte sein:

  • Shardable (kann mehr Server einführen und den Schlüsselraum zwischen ihnen verteilen)

  • Namespaced (es sollte einen Mechanismus geben, um Schlüssel logisch zusammen zu gruppieren, z. B. nach Domänen oder zugehörigen Konzepten)

  • Effizient (versuchen Sie, so wenig Platz wie möglich in der Datenbank für Schlüssel zu verwenden, um so viele Daten wie möglich zu ermöglichen)

  • So kollisionsfrei wie möglich (vermeiden Sie Schlüssel für zwei verschiedene Objekte, um gleich zu sein)


Zwei Alternativen, die ich in Betracht gezogen habe, sind diese:

  1. Verwenden Sie Präfixe für Namespaces, getrennt durch ein beliebiges Zeichen (wie human_resources:person:<some_id> ). Der Vorteil ist, dass es ziemlich skalierbar und leicht zu verstehen ist. Der Nachteil wären mögliche Konflikte, abhängig vom Trennzeichen (was ist, wenn id das Zeichen : enthält?) Und möglicherweise der Größeneffizienz (zu viele verschachtelte Namespaces könnten sehr lange Schlüssel erzeugen).

  2. Verwenden Sie eine Datenstruktur (wie Ordered Set oder Hash), um Namespaces zu speichern. Der Hauptnachteil hierfür wäre der Verlust der "Shardability", da die Struktur zum Speichern der Namespaces in einer einzigen Datenbank sein müsste.

Frage : Was wäre ein guter Weg, um einen Schlüsselbereich in einem Shard-Setup zu verwalten? Sollten wir eine dieser Alternativen verwenden, oder gibt es ein anderes, besseres Muster, das wir nicht berücksichtigt haben?

Vielen Dank!

    
Juan Carlos Coto 09.10.2013, 18:16
quelle

1 Antwort

8

Die allgemein akzeptierte Konvention in der Redis-Welt ist die Option 1 - d. h. Namespaces, die durch ein Zeichen wie einen Doppelpunkt getrennt sind. Das heißt, die Namespaces sind fast immer eine Ebene tief. Zum Beispiel: person:12321 anstelle von human_resources:person:12321 .

Wie funktioniert das mit den 4 Richtlinien, die Sie festgelegt haben?

Shardable - Dieser Ansatz ist shardbar. Jeder Schlüssel kann in einen anderen Shard oder einen Shard gelangen, je nachdem, wie du ihn eingerichtet hast.

Namespace Namespace als Möglichkeit, Kollisionen zu vermeiden, funktioniert mit diesem Ansatz. Namespaces als eine Möglichkeit zum Gruppieren von Schlüsseln funktioniert jedoch nicht. Im Allgemeinen ist die Verwendung von Schlüsseln zur Gruppierung von Daten eine schlechte Idee. Zum Beispiel, was passiert, wenn die Person von einer Abteilung in eine andere wechselt? Wenn Sie den Schlüssel ändern, müssen Sie alle Referenzen aktualisieren - und das wird schwierig.

Es ist am besten sicherzustellen, dass sich der Schlüssel für ein Objekt nie ändert. Die Gruppierung kann dann extern durch Erstellen eines separaten Indexes gehandhabt werden.

Nehmen wir beispielsweise an, Sie möchten Personen nach Abteilung, nach Gehaltsbereich und nach Standort gruppieren. Hier ist, wie Sie es tun würden -

  1. Einzelne Personen gehen in separaten Hash mit Schlüsseln persons:12321
  2. Erstellen Sie eine set für jede Gruppe mit - Zum Beispiel: persons_by:department - und speichern Sie nur die numerischen Bezeichner für jede Person in dieser Gruppe. Zum Beispiel [12321, 43432]. Auf diese Weise erhalten Sie die Vorteile von Redis 'Integer Set

Effizient Die oben erläuterte Methode ist ziemlich effizient im Speicher. Um mehr Speicherplatz zu sparen, können Sie die Tasten auf der Anwendungsseite weiter komprimieren. Beispielsweise können Sie p:12321 anstelle von persons:12321 speichern. Sie sollten dies nur tun, wenn Sie über Profilerstellung ermittelt haben, dass Sie solche Speichereinsparungen benötigen. In der Regel ist es die Kosten nicht wert.

Kollisionsfrei Dies hängt von Ihrer Anwendung ab. Jeder Benutzer oder jede Person sollte einen Primärschlüssel haben, der sich niemals ändert. Verwenden Sie dies in Ihrer Redis-Taste, und Sie werden keine Kollisionen haben.

Sie haben zwei Probleme mit diesem Ansatz erwähnt, und ich werde versuchen, sie anzugehen

Was ist, wenn die ID einen Doppelpunkt hat?

Es ist natürlich möglich, aber das Design Ihrer Anwendung sollte dies verhindern. Es ist am besten, Sonderzeichen in Bezeichnern nicht zuzulassen - weil sie über mehrere Systeme hinweg verwendet werden. Zum Beispiel ist der Bezeichner sehr wahrscheinlich ein Teil der URL und der Doppelpunkt ist ein reserviertes Zeichen, selbst für URLs.

Wenn Sie in Ihrem Bezeichner wirklich Sonderzeichen zulassen müssen, müssten Sie einen kleinen Wrapper in Ihren Code schreiben, der die Sonderzeichen codiert. Die URL-Kodierung ist perfekt dazu geeignet.

Größeneffizienz

Lange Tasten kosten zwar, aber es ist nicht zu viel. Im Allgemeinen sollten Sie sich über die Datengröße Ihrer Werte statt über die Schlüssel Gedanken machen. Wenn Sie glauben, dass Schlüssel zu viel Speicher verbrauchen, profilieren Sie die Datenbank mit einem Tool wie redis-rdb-tools.

Wenn Sie feststellen, dass die Schlüsselgröße ein Problem ist und Sie den Speicher speichern möchten, können Sie einen kleinen Wrapper schreiben, der die Schlüssel mit einem Alias ​​neu schreibt.

    
Sripathi Krishnan 05.11.2013, 08:24
quelle