2013-10-09 9 views
8

Versuchen, eine Richtlinie für Schlüssel in einem Schlüssel-Wert-Speicher zu definieren (wir verwenden Redis). Der Schlüsselraum sollte sein:Was ist eine gute Möglichkeit, Schlüssel in einem Schlüsselwertspeicher zu verwalten?

  • Shardable (können mehrere Server einführen und den Schlüsselraum zwischen ihnen verteilt)

  • Namensräume (es sollte ein Mechanismus zur „Gruppe“ Schlüssel zusammen logisch sein, B. nach Domäne 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 zu ermöglichen eine wie möglich)

  • Als kollisions wenig wie möglich (Schlüssel für zwei verschiedene Objekte vermeiden gleich)


Zwei Alternativen zu sein, die ich in Betracht gezogen haben, sind diese:

  1. Verwenden Sie Präfixe für Namespaces, getrennt durch ein 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 : drin hat?), Und möglicherweise Größe Effizienz (zu viele geschachtelte Namespaces könnten sehr lange Schlüssel erstellen).

  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 eine gute Möglichkeit wäre, einen Schlüsselraum in einem sharded Setup zu verwalten? Sollten wir eine dieser Alternativen verwenden, oder gibt es ein anderes, besseres Muster, das wir nicht berücksichtigt haben?

Vielen Dank!

Antwort

8

Die allgemein anerkannte Konvention in der Redis-Welt ist die Option 1 - d. H. Namespaces, die durch ein Doppelzeichen 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 festlegen?

Shardable - Dieser Ansatz ist shardable. Jeder Schlüssel kann in einen anderen Shard oder Shard gelangen, je nachdem, wie Sie ihn eingerichtet haben.

Namespace Namespace als eine Möglichkeit zur Vermeidung von Kollisionen 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 erfolgen.

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

  1. Einzelne Leute gehen in getrennten Hash mit Schlüssel persons:12321
  2. erstellen set für jede Gruppe von - Zum Beispiel: persons_by:department - und speichert nur die numerischen Kennungen für jede Person in diesem einstellen. Zum Beispiel [12321, 43432]. Auf diese Weise erhalten Sie die Vorteile von Redis' Integer Set

Effiziente Das oben erläuterte Verfahren ist ziemlich effizient Speicher weise. Um mehr Speicherplatz zu sparen, können Sie die Tasten auf der Anwendungsseite weiter komprimieren. Beispielsweise können Sie p:12321 statt 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 erwähnten zwei Probleme mit diesem Ansatz, und ich werde versuchen, sie

Was passiert, wenn die ID einen Doppelpunkt hat zu lösen?

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 Sonderzeichen in Ihrem Bezeichner wirklich zulassen müssen, müssten Sie einen kleinen Wrapper in Ihren Code schreiben, der die Sonderzeichen codiert. Die URL-Codierung ist dazu in der Lage.

Größe Efficiency

Kosten zu lange Schlüssel Es gibt jedoch ist es 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 den Speicher speichern möchten, können Sie einen kleinen Wrapper schreiben, der die Schlüssel unter Verwendung eines Alias ​​neu schreibt.

+0

Wunderbare Antwort. Vielen Dank, dass Sie sich die Zeit genommen und dieses Problem angesprochen haben. Ich entschuldige mich dafür, dass ich vorher nicht auf den "Bounty" -Button geklickt habe, aber dies ist das erste Mal, dass ich es benutzt habe. Vielen Dank! –