S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage
Speicher-Korridor von St-Pete

Hallo zusammen! Ich bin Mons Anderson, Plattformarchitekt Mail.ru Cloud Lösungen, und ich erzähle, wie wir unseren S3-Speicher aufgebaut haben, wie er funktioniert, welche Lösungen erfolgreich waren und welche wir ändern würden, wenn wir ein ähnliches Projekt heute von Grund auf neu starten würden.

Dieser Artikel basiert auf einem Vortrag bei @Databases Meetup von Mail.ru Cloud Solutions & Tarantool. In diesem Artikel werden wir besprechen:

  • wie das Mail.ru-Lager aufgebaut war, auf dessen Fundament wir das S3-Lager aufgebaut haben;
  • was wir hinzugefügt haben, um Mail.ru Cloud Storage zu entwickeln;
  • wie das objektbasierte Speicher-Modell funktioniert und welche Schritte unternommen wurden, um es produktionsreif zu machen;
  • über die Weiterentwicklungen des Live-Systems: Failover und Skalierung;
  • wie wir Sharding und Resharding umgesetzt haben;
  • sowie die Arbeit mit SSL-Zertifikaten.

Wenn Sie nicht lesen möchten, können Sie sehen Sie sich an,.

Wie das Mail.ru-Lager aufgebaut war, auf dessen Fundament wir das S3-Lager aufgebaut haben,

Die Entwicklung unseres S3 begann auf der Grundlage des Mail.ru Cloud-Lagers, daher ist es zunächst wichtig zu erklären, wie es strukturiert ist und was es kann.

Der Cloud-Speicher von Mail.ru besteht aus Servern mit Festplatten. Im Durchschnitt verfügt ein moderner Storage-Server über 36 Festplatten mit jeweils 12–14 Terabyte. Früher waren die Festplatten kleiner, aber im Laufe von drei Jahren hat sich die Speicherkapazität erheblich erhöht, und heute sind es fast 500 Terabyte unstrukturierte Daten.

Festplatten von verschiedenen Servern des Speichers werden in sogenannten „Pairs“ zusammengefasst. Ein Paar ist eine Einheit zum Speichern von Dateien. Im Grunde genommen handelt es sich dabei um eine Festplatte, die in einen bestimmten Abschnitt an einem spezifischen Pfad eingebunden ist, wo Dateien gespeichert werden, die durch Hashes identifiziert werden.

Der Begriff Paar ist historisch bedingt und hat bis heute Bestand, obwohl es heutzutage nicht mehr zwingend nur zwei Festplatten in einem Paar gibt. Es können auch drei Festplatten sein, und es sind verschiedene hybride Speichermöglichkeiten denkbar, zum Beispiel 3/2.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Paare (pair) sind Einheiten zum Speichern von Objekten.

Alle Paare werden in PairDB gespeichert – einer Anwendung auf Basis von Tarantool. Alle Datenbanken in unserem Speicher, beginnend mit den allerersten, basieren auf Tarantool; andere Datenbanken verwenden wir nicht.

PairDB speichert alle Paare, deren Zustände, verfügbaren Speicherplatz, Ausfallmöglichkeiten und letzte Fehler. Es kann auch automatisch nach Paaren suchen, deren Zustand aktualisieren und überprüfen, ob sie funktionieren oder nicht. Das heißt, PairDB ist eine umfassende Übersicht über den Zustand aller Festplatten in unserem System.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Pair DB: Datenbank mit dem Zustand der Paare

In den Paaren werden Dateien gespeichert, und um zu wissen, welche Datei sich in welchem Paar befindet, ist eine weitere Datenbank – FileDB – erforderlich. Diese speichert die Zuordnung: welche Datei befindet sich in welchem Paar, sowie eine kleine Menge notwendiger Attribute.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud StorageFile DB: Ort, an dem die Datei gespeichert ist

Ein weiteres wichtiges Glied ist der Service Nylon, ein Router für die Arbeit mit Datenbanken. Er ist der einzige Einstiegspunkt und ermöglicht die Nutzung einer einheitlichen Schnittstelle sowohl für PairDB als auch für FileDB. Dies ist ein stateless-Service, der die Anfragen ausbalanciert, versteht, zu welchem Shard von FileDB gegangen werden muss, und weiß, welche Paare aktiv sind und welche nicht.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Nylon: Router für die Arbeit mit Datenbanken

Um Inhalte im Speicher abzulegen, benötigen wir einen Service – Streamer. Dieser bietet zwei HTTP-Methoden: die PUT-Methode, um Inhalte in den Speicher hochzuladen, und die GET-Methode, um sie abzurufen. HTTP ist ein recht populäres und praktisches Protokoll zur Datenübertragung.

Wenn wir auf Streamer zugreifen, kontaktiert dieser über Nylon PairDB, um herauszufinden, auf welches Pair die Datei hochgeladen werden kann und überträgt die Daten anschließend über WebDAV an dieses Pair.

Im Grunde genommen ist jeder Storage-Server eine Kombination aus Nginx und Festplatten, die auf definierte Pfade gemountet sind. Wir können mit Streamer eine Datei in den Speicher hochladen, sie löschen, umbenennen oder ihre Integrität prüfen. Dies bietet eine praktische Schnittstelle für die Interaktion auf niedrigster Ebene mit dem Speicher.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Streamer: der Zugriffspunkt zum Speicher

Was wir hinzugefügt haben, um das S3-Speicherangebot zu verbessern

Wir haben also die grundlegende Speicherinfrastruktur betrachtet, als wir uns darauf vorbereiteten, das S3-Speichersystem zu starten. Mit der PUT-Methode konnten wir beliebige Inhalte speichern und erhielten als Identifikator dieser Daten einen Hash. Mit diesem Identifizierer konnte man später die Originaldatei wieder abrufen. Doch das reicht nicht aus, um S3 vollständig zu implementieren. Im S3-Protokoll gibt es neben der Speicherung von Objekten auch:

  • Speicherung von Metadaten – zusätzlichen Eigenschaften von Objekten;
  • Organisation des Zugriffs auf Objekte über HTTP;
  • Gruppierung von Objekten in Sammlungen – Buckets;
  • HTTP-S3-Endpunkt. S3 organisiert Daten in bestimmten Strukturen – Buckets, von denen jeder einen Eingangspunkt für die Speicherung von Dateien bietet.

Für die Umsetzung dieser Logik war ein separater Dienst erforderlich. Zudem möchte man gleich die Architektur für das zukünftige Wachstum des Dienstes mit linearer Skalierbarkeit vorsehen.

Die ersten Komponenten

Ein Daemon, der die S3-API implementiert. Dies ist die standardisierte S3-API von Amazon, die XML für Metadaten unterstützt und es ermöglicht, Inhalte direkt zu übertragen. Wir mussten nichts Neues erfinden, alles ist dokumentiert und beschrieben.

Vor dem Dienst haben wir Nginx installiert. Diesen haben wir für die SSL-Terminierung, Lastenverteilung und einige Logik mit Lua (Metriken, Protokollierung und Tracing) verwendet.

Für die Speicherung der S3-Metadaten haben wir ebenfalls Tarantool gewählt. In der ersten Version hat der S3-Daemon auf diese Datenbank zugegriffen, während der Inhalt in einem großen Speicher über Streamer gespeichert wurde.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage
Nginx + S3-API + Metadaten

Objekt-basierte Speicherung

Schauen wir uns an, wie S3 funktioniert. Der Benutzer kann einen Bucket erstellen – eine Sammlung von Objekten. Der Bucket wird durch den Hostnamen adressiert und ist ein Subdomain des Dienstes. Innerhalb des Buckets kann der Benutzer Objekte erstellen. Der Identifikator des Objekts ist die URL. Der Inhalt des Objekts ist ein Blob, ein Array von Binärdaten, das wir im Speicher aufbewahren werden. Das Objekt hat zudem Attribute: den Namen – die eben genannte URL, ACL (Zugriffssteuerungsliste), sowie andere zusätzliche oder benutzerdefinierte Attribute – all dies wird in den Metadaten gespeichert.

Das normalisierte Schema dieser Daten könnte folgendermaßen aussehen: Es gibt Projekte, die Bucket besitzen, diese Buckets haben Objekte, und diese Objekte können zusammengesetzt sein. Da es eine Möglichkeit gibt, Objekte in Teilen zu laden, gibt es dafür zwei Hilfstabellen: uploads und chunks. Zudem haben die Projekte Zugangsdaten und eine Abrechnung.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage
Datenmodell

Da wir einen B2B-Service mit kostenpflichtigem Zugang erstellt haben, benötigte dieses Schema eine Abrechnung.
Den Abrechnungsdienst haben wir ebenfalls mit Tarantool implementiert.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Überarbeitungen des S3-Speichers: Schritte zur Produktionsbereitschaft

Wir haben bereits ein funktionierendes Modell entwickelt, das genutzt werden kann: Objekte und Metadaten wurden gespeichert, jedoch fehlten einige Punkte für den Produktionsstart.

Zunächst das System der Ratenbegrenzungen. Wenn der Dienst ohne dieses gestartet wird, könnten wir bei hoher Last einen bestimmten Teil des Systems unvorhersehbar überlasten. Die Ratenbegrenzung sollte so funktionieren: Jeder S3-Anfrage kommt an einem speziellen Host an, dieser Host ist der Identifikator des Buckets, und der Bucket gehört einem bestimmten Kunden. Wir müssen eine Funktion für den Bucket definieren, die es ermöglicht, die Ratenbegrenzung zu berechnen.

Darüber hinaus muss das Ratenlimit-System leistungsstark genug sein, um die Last zu bewältigen, die auf S3 einwirkt.

Hier haben wir erneut Tarantool verwendet. Die Ratenlimits bestehen aus einem Cluster von 21 Instanzen, die in Gruppen aufgeteilt, über drei physische Knoten verteilt und zu einem großen topologischen Cluster zusammengeschlossen sind. Konfigurationsänderungen werden automatisch verbreitet: Ratenlimits, Standardwerte und Konfiguration werden festgelegt. Jeder Bucket wird strikt von einer einzigen Instanz bedient. Wenn ein bestimmter Bucket eine Anfrage erhält, wird die Instanz berechnet, die für diesen Bucket zuständig ist. Innerhalb dieses Knotens erfolgt die Berechnung des aktuellen Anfragevolumens anhand eines Algorithmus, der dem Token-Bucket ähnlich ist. Anschließend entscheidet das Ratenlimit-System auf Grundlage der aktuellen Last und der für den spezifischen Bucket festgelegten Eigenschaften, ob die Anfrage ausgeführt werden kann oder nicht. Die Überprüfung der Limits erfolgt zu Beginn der Ausführung der S3-Anfrage, um alle anderen Systemelemente vor übermäßiger Last zu schützen.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Auch unter Last ist es ziemlich schwierig, ohne Caching auszukommen. In S3 wird von mehrfachen Zugriffen auf dieselben Objekte ausgegangen, was es zu einem heißen Speicherplatz macht. Normalerweise wird der Zugriff auf eine einzelne Datei über die komplette Kette abgewickelt: Streamer, FileDB, PairDB, Storage. Bei mehrfachen Zugriffen auf eine Datei optimieren wir den Zugriff auf diesen Inhalt mithilfe eines lokalen Caches.

Das Caching ist mehrschichtig und wird durch nginx, lokale SSDs und RAM-Laufwerke realisiert. Wir haben hier Tarantool nicht verwendet, weil es bequemer ist, Objekte aus dem Dateisystem bereitzustellen; so können wir Caching-Tiering durchführen. Zudem haben wir große Objekte mit einer maximalen Größe von 32 Gigabyte, während in Tarantool nur kleine Objekte gecacht werden können.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Dieses erste System, mit dem wir gestartet sind, hatte eine gewählte Kapazität, die für die Forschung und das Verständnis des Produkts ausreichte, um festzustellen, dass es funktionieren wird.

Überarbeitungen des Betriebssystems: Failover und Skalierung

Das System war bereits im Einsatz, aber zu Beginn haben wir etwas übersehen – wir hätten Failover und Skalierung hinzufügen müssen.

Unser S3-Daemon hat die Metadaten über das Tarantool-Protokoll abgerufen. An die Stelle der ursprünglichen Datenbank haben wir Tarantool gesetzt, das als Proxy-Router für die Anfragen nach den Metadaten fungierte. Aus Sicht der Anwendung, die die API implementiert, hat sich nichts geändert – sie hat weiterhin über das Tarantool-Protokoll auf die Datenbank zugegriffen, aber der Router konnte aktives Failover gewährleisten. Das heißt, wir konnten die Verfügbarkeit des Knotens überwachen, Pausen bei Umschaltungen und Ausfällen einlegen usw. Dabei haben wir die Anwendung selbst nicht modifiziert.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Mehr erfahren, wie wir das Sharding umgesetzt haben

Die nächste Herausforderung, die angegangen werden musste, war das Sharding. Das System wuchs, die Anzahl der Objekte nahm zu und es war notwendig, Möglichkeiten für weiteres Wachstum zu schaffen.

Lassen Sie uns zum Datenschema zurückkehren: Es gibt Projekte, es gibt Buckets, Kredite und Abrechnung. Dies sind Objekte, die mit großer Wahrscheinlichkeit in absehbarer Zeit weder in Volumen noch in Anfragen über einen einzelnen Instanz hinauswachsen werden. Daher macht es keinen Sinn, sie zu sharden, und wir haben sie in eine separate Instanz ausgegliedert, die ungeshardet bleibt. Dies ermöglicht ein konsistenteres Management der Projekte und Buckets, da es einen einheitlichen, ungeshardeten Punkt gibt.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Im Schema gibt es auch Objekte, die linear wachsen – zuerst waren es Hunderttausende, jetzt wird ihre Anzahl in Milliarden gemessen. Solche Objekte und ihre Teile mussten in einen sharden Cluster verschoben werden.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Wir haben das Schema aufgeteilt, aber die Objekte müssen mit den Buckets arbeiten: Ein Objekt gehört immer zu einem bestimmten Bucket, und zudem arbeitet die ACL auf dem Bucket. Daher halten wir für jedes Shard mit Objekten eine Schattenkopie jedes Buckets. Darüber hinaus müssen wir bei der Modifikation von Objekten und der Ausführung von Anfragen das Volumen für die Abrechnung berücksichtigen, weshalb in jedem Shard Abrechnungscounter vorhanden sind.

Außerdem haben wir einige weitere Tabellen und Komponenten hinzugefügt:

  • Ein Container zum Löschen alter Projekte, die entfernt oder eingefroren werden;
  • Eine Warteschlange für Hintergrundaufgaben, das heißt, der Hauptspeicher kann Hintergrundaufgaben ausführen, die im Cluster erledigt werden müssen;
  • Unterstützung des Lebenszyklus — ein Mechanismus, der es ermöglicht, mit Objekten zu arbeiten und deren Lebenszyklus zu verwalten.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Da wir einen Teil der Daten auf Shards verteilt haben, benötigten wir einen Shard-Proxy. Man könnte den Router für diese Rolle wiederverwenden, aber ein separater Shard-Proxy, der nur für die Datenverteilung verantwortlich ist, ermöglicht es, die Daten vollständig über den Router abzurufen, ohne sich um das Sharding kümmern zu müssen.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Ich werde separat erläutern, warum wir keine fertige Lösung gewählt haben, sondern eine benutzerdefinierte Shard-Funktion entwickeln wollten.

Schauen wir uns an, wie sie aufgebaut ist. Wir haben 256 verfügbare Shards. Für jeden Bucket weisen wir einen Bereich mit einer konsistenten Funktion zu. Es ist einfach—genauso wie man mit einer konsistenten Funktion die Zugehörigkeit zu einem Shard bestimmt, legt man den Start-Shard fest und weist einen Bereich zu:

f(bucket, shards) = subset

Das bedeutet, wenn wir einen Bucket betrachten, können wir sagen, dass er und seine Daten immer auf einer bestimmten Teilmenge aller Shards liegen werden. Dies reduziert den Einfluss eines Buckets auf andere und vereinfacht die Arbeit mit Map-Reduce-Anfragen, wenn wir zum Beispiel eine Auflistung der Bucket-Objekte erstellen müssen. Dazu müssen wir alle Shards abfragen, auf denen diese Objekte gespeichert sind. Wenn die Objekte auf allen Shards liegen würden, würde jede Auflistung das gesamte System beeinträchtigen, während hier nur eine spezifische Teilmenge betroffen ist.

Weiterhin gehört jedes Objekt zu einem bestimmten Bucket, weshalb wir, wenn wir auf ein Objekt zugreifen, es anhand seines Namens in einem spezifischen Bucket anfordern. Das bedeutet, wir können die Funktion für das Objekt nicht aus dem gesamten verfügbaren Bereich der Shards, sondern nur aus der Teilmenge seines Buckets definieren:

f(object, subset) = shard

Wir nehmen ein spezifisches Objekt und übergeben dessen Teilmenge als Argumente an die Funktion, nicht alle Shards – und erhalten den spezifischen Shard.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Also, Sharding ist implementiert, und es gibt einen Sharding-Proxy. Als nächstes muss der Router zusammen mit der Metadatenbank auf den Sharding-Proxy zugreifen. Zum Beispiel, um Schattenkopien zu erstellen – wenn wir einen Bucket erstellen, muss der Hauptspeicher einen Vertreter dieses Buckets auf allen Shards anlegen, wo er vorhanden sein soll.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Wie wir Resharding implementiert haben

Das größte Problem beim Sharding ist das Resharding. Es war uns wichtig, dies ohne Downtime zu realisieren, da das System bereits in Produktion war. Ich werde zeigen, wie wir das Problem anhand einer ähnlichen Aufgabe mit einer Live-Datenmigration von einem Projekt zu einem anderen gelöst haben.

Im Folgenden sehen Sie das Schema unseres Clusters, das nach der Implementierung von Sharding entstanden ist. Wir haben nginx, S3 API, einen Router, eine Primary-Datenbank mit Projekten, einen Sharding-Proxy und die Shards selbst.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Ich habe oben erwähnt, dass es zu einem bestimmten Zeitpunkt im Projekt eine produktbezogene Aufgabe gab: 'Ein zusätzliches Speichergerät, Icebox, zu starten – ähnlich wie Hotbox, aber für kalte Daten'. Im Grunde handelt es sich um dasselbe Speichergerät, jedoch unter einer anderen URL und ohne Caches.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Icebox wurde seltener verwendet als Hotbox, weshalb es lange ohne jegliches Sharding auskam. Am Ende haben wir beschlossen, es aufzugeben und Hotbox und Icebox zu einem einzigen Service zusammenzuführen, indem wir einfach die Speicherkategorien getrennt haben.

Die Buckets in den Speichern überschritten sich nicht, sie konnten leicht zusammengeführt und verschoben werden. Da die Kunden jedoch sowohl den einen als auch den anderen Speicher nutzten, musste das Problem der Downtime gelöst werden. Wir konnten nicht einfach ausschalten und kopieren. Daher haben wir die Migration in mehreren Phasen durchgeführt.

Zunächst haben wir die Primärspeicher synchronisiert. Wir hatten Tarantool und konnten beim Erstellen eines Objekts Folgendes tun:

  • Eine Anfrage zur Erstellung eines Buckets, zum Beispiel in Hotbox, erreicht die Datenbank;
  • Tarantool prüft in einer anderen Datenbank (in diesem Fall in Icebox), dass es keinen solchen Bucket gibt;
  • Wenn der Bucket existiert, teilt die Datenbank mit, dass er nicht erstellt werden kann, und er wurde als bestehend synchronisiert.
    S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage
    Synchronisierung der Buckets

In dem Speicher, der alle Daten aufnehmen sollte, wurde für Projekte und Buckets ein Attribut eingeführt, das angibt, wo dieses Objekt gespeichert ist. Es konnte lokal, also in Hotbox, oder in Icebox gespeichert werden — dann gibt es im neuen Speicher keine Daten davon, oder es könnte sich im Migrationsstatus befinden.

Wenn ein Projekt oder Bucket das Attribut Migrating hatte, wurde während der Migration die Anfrage zunächst im neuen Speicher ausgeführt, in dem die Daten sein sollten, und falls sie dort nicht vorhanden waren, wurden die Anfragen an den alternativen Speicher umgeleitet.

Anschließend haben wir den Traffic umgeschaltet. Da die API sowohl Icebox- als auch Hotbox-Anfragen bedienen konnte, konnten wir den Traffic ohne Ausfallzeit umschalten, indem wir einfach die Hosts verschoben und entsprechende Einträge in Nginx hinzugefügt haben.

Nachdem der Traffic umgeleitet war, konnte Nginx und die API von Icebox entfernt werden.
Dann haben wir Icebox Nginx und S3 API entfernt — und alles lief wie gewohnt:

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Anschließend haben wir einen Hintergrundprozess zur Migration gestartet, der innerhalb der Datenbank arbeitet — der nacheinander alle Projekte und deren Buckets durchläuft, das Attribut Migrating setzt, die Daten überträgt und nach Abschluss der Übertragung das Attribut Local setzt.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Nach der Datenmigration benötigen wir den alten Speicher nicht mehr und entfernen die verbleibenden Teile des alten Systems sowie die Unterstützung des Migrationsstatus aus dem Code.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Der Re-Sharding vom alten Speicher auf den shardierten wurde nach denselben Prinzipien durchgeführt:

  • Alle Buckets wurden als Nicht-shardiertmarkiert. Alle Anfragen an sie gingen an den ursprünglichen, nicht-shardierten Speicher.
  • Neue Buckets wurden direkt im Status Shardiert.
  • erstellt. Einzelne Buckets wurden ausgewählt, der Status wurde auf Migrating gesetzt und die Daten wurden verschoben.

Anfragen wurden dabei nach folgendem Prinzip bearbeitet:

  • Zuerst im neuen lesen, dann im alten.
  • Nur im neuen erstellen.
  • Zweiphasen-Update: falls im neuen nicht vorhanden, werden die Daten vom alten in den neuen überführt, danach wird aktualisiert.

Arbeiten mit SSL-Zertifikaten

Für das Frontend verwenden wir Nginx. In unserem Fall handelt es sich nicht um ein gewöhnliches Nginx, sondern um OpenResty, Nginx mit LuaJIT-Unterstützung.

Ein weiterer Teil des Systems betrifft die Arbeit mit SSL-Zertifikaten. Im S3-Speicher können Sie eine eigene Domain für den Zugriff auf einen bestimmten Bucket einrichten, einfach durch CNAME. Aber ohne HTTPS geht es heutzutage nicht: eine eigene Domain setzt ein eigenes SSL-Zertifikat voraus.

Wie bereits erwähnt, ist Nginx für das Load Balancing und die Termination von SSL verantwortlich. In unserem Fall handelt es sich nicht um ein gewöhnliches Nginx, sondern um OpenResty, Nginx mit Unterstützung für LuaJIT.

Dies hat es uns ermöglicht, unseren Nginx relativ einfach beizubringen, beliebige Zertifikate bereitzustellen. Dabei war es notwendig, die Zertifikate dynamisch bereitzustellen (ohne sie in der Konfigurationsdatei festlegen zu müssen). Wir haben das Modul ssl_certificate_by_lua, verwendet, das es erlaubt, das Zertifikat während des TLS-Handshakes direkt aus einer beliebigen Quelle zu lesen. Als Zertifikatsspeicher haben wir Tarantool gewählt: dies ermöglicht eine externe Verwaltung der Zertifikate und bietet extrem schnelle Zugriffszeiten.

Außerdem wurde ein separater Daemon implementiert, dessen Aufgabe es ist, die durch Let’s Encrypt ausgestellten Zertifikate regelmäßig zu aktualisieren.

S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage

Was würde ich erhalten, und was würde ich anders machen, wenn ich den Speicher von Grund auf neu entwickeln würde?

Was von Anfang an hätte verwendet werden müssen

Sharding sofort. Es gab einige Probleme mit dem Sharding. Es ist einfach zu machen, aber wenn man Projekte startet, die skalierbar sein müssen, sollte man besser gleich einen shardierten Cluster wählen, selbst wenn es nur mit minimalen Knoten ist. Die Implementierung von Sharding zu Beginn ist nahezu kostenlos im Vergleich zur Einführung von Sharding in ein bestehendes System.

Arbeiten mit Tarantool über Load Balancer. Wir binden jetzt alle neuen Datenbanken sofort über Load Balancer in den Betrieb ein. Das ermöglicht es, die Funktionalität zu erweitern und eine höhere Ausfallsicherheit zu erreichen.

Auto-Failover. Ich würde alle Werkzeuge installieren, die für das Auto-Failover benötigt werden, da die ersten Misserfolge nach dem Start mit dessen Abwesenheit zusammenhingen. Nach den Erfahrungen mit S3 wurden alle nachfolgenden Produkte mit diesem Wissen implementiert.

S3-Funktion „Versionierung“. Zunächst schien mir diese Funktionalität nicht sehr gefragt zu sein. Diese Möglichkeit in die Architektur eines funktionierenden Systems zu integrieren, ist äußerst komplex.

Getrennte Abrechnung. Die Art und Weise, wie wir das Billing in unser System integriert haben, war anfangs vielversprechend, hat sich jedoch später als störend erwiesen. Es wäre besser gewesen, es als völlig separaten Service zu implementieren.

Erfolgreiche Entscheidungen

Datenmodell. Die Erfahrung hat gezeigt, dass wir im Laufe der Entwicklung des Services sehr gut mit dem Datenmodell von Amazon übereinstimmen, wodurch wir die dort vorhandenen Funktionen umsetzen können.

Shard-Schema. Ich würde dieselben Bereichs-Shardings für Buckets unterstützen, da dies eine gute Verteilung der Anfragen von verschiedenen Buckets über ein großes Cluster ermöglicht.

Einsatz von Tarantool. Tarantool hat bei der Weiterentwicklung und Modifikation des Services erheblich geholfen. Wir konnten problemlos mit Daten arbeiten, sie transformieren und das Speicher-Backend sharden, ohne in die Anwendungsschicht aufsteigen zu müssen.

Dieser Vortrag wurde erstmals gehalten auf @Databases Meetup by Mail.ru Cloud Solutions&Tarantool. Sehen Sie sich das Video anderer Vorträge an und abonnieren Sie die Veranstaltungshinweise auf Telegram. Rund um Kubernetes in der Mail.ru Group.

Sie können auch meinen alten Vortrag über S3 ansehen oder den Artikel meines Kollegen über Blockspeicher lesen.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster