Redis und das Big-Data-Problem

    im gedächtnis db

    Hallo habr Wir teilen weiterhin die technologische Küche von Retail Rocket . In dem heutigen Artikel werden wir das Problem der Auswahl einer Datenbank zum Speichern großer und häufig aktualisierter Daten diskutieren.

    Bereits in der Anfangsphase der Entwicklung der Plattform standen wir vor folgenden Aufgaben:
    • Speichern Sie die Lagerbestände der Geschäfte (d. H. Informationen zu jedem Produkt aller Geschäfte, die mit unserer Plattform verbunden sind, mit einer vollständigen Aktualisierung von 25 Millionen Artikeln alle 3 Stunden).
    • Speicherempfehlungen für jedes Produkt (ungefähr 100 Millionen Produkte enthalten 20 oder mehr empfohlene Produkte für jeden Schlüssel).
    • Sicherstellung einer gleichbleibend schnellen Lieferung dieser Daten auf Anfrage.


    Schematisch kann man sich das vorstellen:
    hadoop


    Unter den beliebten relationalen und dokumentarischen Datenbanken wählten wir MongoDb und stießen sofort auf folgende Schwierigkeiten:
    • Optimierung der Aktualisierungsgeschwindigkeit von 100K - 1M Produkten gleichzeitig.
    • Beim Schreiben von Daten ruhte MongoDb auf der Festplatte, und der Geist eines Vakuumproblems (als der Datensatz aus der Datenbank gelöscht und der Speicherplatz dafür noch belegt wurde) ließ uns über In-Memory DataBase nachdenken.


    Angesichts der ersten Schwierigkeiten haben wir uns entschlossen, die Suche nach einer Lösung für In-Memory Db fortzusetzen, und unsere Entscheidung fiel schnell auf Redis, was uns die folgenden Vorteile bringen sollte:
    • Persistenz (speichert den Status auf der Festplatte).
    • Eine breite Palette von Datentypen (Zeichenfolgen, Arrays usw.) und Befehlen für die Arbeit mit ihnen.
    • Moderne In-Memory-Datenbank, die sich im Gegensatz zu Memcached als wichtig erwies.

    Aber die reale Welt hat unsere Einstellung zu diesen Pluspunkten verändert.

    Wunder der Ausdauer


    die Magie


    Unmittelbar nach der Einführung von Redis in der Produktion stellten wir fest, dass die Geschwindigkeit, mit der Empfehlungen für Waren herausgegeben wurden, zeitweise erheblich nachließ und der Grund nicht im Code enthalten war. Nach der Analyse mehrerer Indikatoren haben wir festgestellt, dass zu dem Zeitpunkt, an dem die Festplattenaktivität auf den Redis-Servern auftritt, die Reaktionszeit unseres Dienstes zunimmt. Dies ist natürlich Redis, und genauer gesagt, wie es sich verhält, wenn es mit der Festplatte funktioniert. Für einige Zeit haben wir die Häufigkeit des Speicherns von Daten auf der Festplatte reduziert und damit dieses Problem „vergessen“.

    Die nächste Entdeckung für uns war, dass Redis nicht verfügbar ist, solange Daten von der Festplatte abgerufen werden (dies ist natürlich logisch), d. H. Wenn der Redis-Prozess plötzlich abstürzt, reagiert der Dienst nicht, bis der neu hochgeladene Dienst seinen gesamten Status von der Festplatte abruft, selbst wenn der Mangel an Daten ein viel geringeres Problem für Sie darstellt als eine unzugängliche Datenbank.

    Aufgrund der beiden oben beschriebenen Merkmale von Redis stellte sich vor uns die Frage: "Aber sollten wir seine Persistenz deaktivieren?" Darüber hinaus können wir alle darin gespeicherten Daten in einer Zeit neu laden, die mit der Zeit vergleichbar ist, in der er sie von der Festplatte abruft, und gleichzeitig reagiert Redis. Gelöst! Wir haben es uns zur Regel gemacht, keine Daten in Redis zu speichern, ohne die der Systembetrieb nicht möglich ist und die wir nicht schnell wiederherstellen können, und dann die Persistenz deaktiviert. Seitdem sind 1,5 Jahre vergangen und wir glauben, dass wir die richtige Entscheidung getroffen haben.

    Auswahl eines Treibers für Redis


    Von Anfang an war es für uns eine unangenehme Tatsache, dass Redis keinen eigenen Treiber für .Net hat. Bei inoffiziellen Fahrern hat sich herausgestellt, dass es nur einen geeigneten Fahrer gibt. Und noch schlimmer, nach einer Weile wurde es bezahlt und alle neuen Funktionen erschienen erst in der kostenpflichtigen Version.
    Es ist anzumerken, dass seit diesem Moment viel Zeit vergangen ist, und höchstwahrscheinlich hat sich in dieser Situation etwas geändert. Wir haben jedoch keine schnelle Analyse unter den kostenlosen Redis-Cluster-Support-Treibern gesehen, daher ist die Situation definitiv unvollkommen.


    Horizontale Skalierung


    horizontale Skalierung

    Nach nur sechs Monaten mit Redis mieteten wir einen Server mit der maximal zulässigen RAM-Menge im DC, und es wurde klar, dass das Scherben gleich um die Ecke war. Redis-Cluster war zu dieser Zeit kurz vor dem Verlassen, und die Treiber, die bezahlt wurden, schlugen vor, dass wir dieses Problem selbst lösen müssten.

    Es scheint uns immer noch, dass es nur eine Option gibt, um das Scherben in Redis richtig zu machen. Wenn Sie diese Methode einfach beschreiben, haben wir alle Methoden, die den Datensatzschlüssel erhalten, in den Parameter übernommen. Innerhalb jeder dieser Methoden wird ein Schlüssel gehasht und mit einem einfachen Rest der Unterteilung wird ein Server ausgewählt, auf dem der Schlüssel geschrieben / gelesen wird. Es scheint, dass eine relativ einfache Lösung, die nicht von offensichtlichen Mängeln verschont bleibt, es uns erlaubt, immer noch nicht erfolgreich über Probleme mit der horizontalen Skalierung nachzudenken.

    Sie können den Code unserer Wrapper-Implementierung für RedisClient mit Sharding-Unterstützung in unserem Repository auf GitHub sehen .

    Die Hauptaufgabe nach der Einführung von Sharding bestand darin, die Verfügbarkeit von RAM auf Redis-Servern zu überwachen. Auf den Servern sollte genügend freier Speicher verfügbar sein, damit bei einem Absturz von 1-2 Redis-Computern genügend Speicher zur Verfügung steht, um alle Daten auf die im Kampf verbleibenden Server zu übertragen und die Arbeit fortzusetzen, bis die abgestürzten Server wieder in Betrieb sind.

    Frühe Leistungsprobleme


    Da Redis nur Textdaten speichern kann, müssen Objekte vor dem Speichern serialisiert und in einem bestimmten Textformat deserialisiert werden, bevor sie ausgegeben werden. Unser Treiber serialisiert Daten standardmäßig in das JSON-Format, und wir haben festgestellt, dass der Deserialisierungsprozess viel Zeit für die Ausgabe von Empfehlungen in Anspruch nimmt. Nach einer kurzen Analyse der Serialisierer entschieden wir uns, den Standardtreiber-Serialisierer durch JIL zu ersetzen, wodurch das Problem der Serialisiererleistung vollständig beseitigt wurde.

    Abschließend


    Nachdem Sie alle obigen Punkte gelesen haben, scheint es, dass Redis eine problematische Datenbank mit einer Reihe von versteckten Risiken ist. Tatsächlich war jedoch bei Redis alles vorhersehbar. Wir haben immer verstanden, wo wir auf Probleme warten müssen, deshalb haben wir sie im Voraus gelöst. Wir setzen Redis seit 2 Jahren im Kampf ein und obwohl wir manchmal den Gedanken bekommen, "Wäre es möglich, es durch eine" reguläre Datenbank "zu ersetzen?", Glauben wir immer noch, dass wir zu Beginn unserer Reise die richtige Wahl getroffen haben.

    Unsere Checkliste "Radieschen kochen":


    • Speichern Sie nur Daten, die bei Verlust schnell wiederhergestellt werden können.
    • Verwenden Sie keine Rettich-Persistenz.
    • Deine Scherbe.
    • Verwenden Sie einen effizienten Serializer.

    Jetzt auch beliebt: