{"id":91090,"date":"2020-08-08T13:42:11","date_gmt":"2020-08-08T11:42:11","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage"},"modified":"2020-08-08T13:42:11","modified_gmt":"2020-08-08T11:42:11","slug":"arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage","title":{"rendered":"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/a53775776b3fc969cc15c9d13a64039d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<em><noindex><a rel=\"nofollow\" href=\"https:\/\/www.deviantart.com\/st-pete\/art\/Storage-Corridor-408874509\">Lagerflur<\/a><\/noindex> von St-Pete<\/em><\/p>\n<p><\/p>\n<p>Hallo zusammen! Ich bin Mons Anderson, Architekt der Plattform <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/\">Mail.ru Cloud Solutions<\/a><\/noindex>, und ich werde erz\u00e4hlen, wie wir unseren S3-Speicher aufgebaut haben, wie er funktioniert, welche L\u00f6sungen erfolgreich waren und welche man \u00e4ndern sollte, wenn wir solch ein Projekt heute von Grund auf neu starten w\u00fcrden.<\/p>\n<p><\/p>\n<p>Der Artikel basiert auf einem Bericht von <noindex><a rel=\"nofollow\" href=\"https:\/\/corp.mail.ru\/ru\/press\/events\/databases-2\/\">@Databases Meetup<\/a><\/noindex> Mail.ru Cloud Solutions &amp; Tarantool. In dem Artikel sprechen wir \u00fcber:<\/p>\n<p><\/p>\n<ul>\n<li>wie der Mail.ru Speicher eingerichtet war, auf dem wir den S3-Speicher aufgebaut haben;<\/li>\n<li>was wir hinzugef\u00fcgt haben, um den Mail.ru Cloud Storage zu schaffen;<\/li>\n<li>wie das Objektmodell der Speicherung funktioniert und welche Schritte unternommen wurden, um in die Produktion zu gehen;<\/li>\n<li>\u00fcber die Verbesserungen des produktiven Systems: Failover und Skalierung;<\/li>\n<li>wie wir Sharding und Re-Sharding umgesetzt haben;<\/li>\n<li>und auch \u00fcber die Arbeit mit SSL-Zertifikaten.<\/li>\n<\/ul>\n<p><\/p>\n<p>Wenn Sie nicht lesen m\u00f6chten, k\u00f6nnen Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/NEgm1nsv-qg\">sehen<\/a><\/noindex>.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"kak-bylo-ustroeno-hranilische-mailru-poverh-kotorogo-my-stroili-s3-hranilische\">Wie der Mail.ru Speicher eingerichtet war, auf dem wir den S3-Speicher aufgebaut haben<\/h2>\n<p><\/p>\n<p>Die Entwicklung unseres S3 begann auf dem Speicher der Mail.ru Cloud, daher ist es zun\u00e4chst wichtig, zu erz\u00e4hlen, wie er aufgebaut ist und was er kann.<\/p>\n<p><\/p>\n<p>Das Mail.ru Cloud-Speicher besteht aus Servern mit Festplatten. Im Durchschnitt ist ein moderner Storage-Server mit 36 Festplatten von je 12\u201314 Terabyte ausgestattet. Fr\u00fcher waren die Festplatten kleiner, aber im Laufe von drei Jahren sind die Festplattengr\u00f6\u00dfen gewachsen, und heute sind es fast ein halbes Petabyte an Rohdaten. <\/p>\n<p><\/p>\n<p>Festplatten aus verschiedenen Storage-Servern werden in sogenannten \u201ePaaren\u201c (pair) zusammengefasst. Ein Paar ist eine einzelne Einheit zur Speicherung von Dateien. Es handelt sich im Prinzip um eine Festplatte, die in einem bestimmten Partition und Pfad eingebunden ist, wo Dateien liegen k\u00f6nnen, die durch Hashes identifiziert sind. <\/p>\n<p><\/p>\n<p>Paar ist ein historischer Begriff, der bis heute erhalten geblieben ist, obwohl es in einem Paar nicht unbedingt nur zwei Festplatten geben muss. Es k\u00f6nnen auch drei Festplatten oder verschiedene hybride Speicherl\u00f6sungen wie 3\/2 vorhanden sein. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/544ab79846539262e2d4dff6ab95ffff.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Paare (pair) \u2014 Einheiten der Objektlagerung<\/em><\/p>\n<p><\/p>\n<p>Alle Paare werden in PairDB gespeichert \u2014 einer Anwendung auf Basis von Tarantool. Alle Datenbanken in unserem Speicher, beginnend mit den allerersten, sind Tarantool, andere Datenbanken nutzen wir nicht.<\/p>\n<p><\/p>\n<p>PairDB speichert alle Paare, deren Zust\u00e4nde, den verf\u00fcgbaren Speicher, die Ausfallm\u00f6glichkeiten und die letzten Fehler. Au\u00dferdem kann sie selbst zu den Paaren gehen, deren Zustand aktualisieren und \u00fcberpr\u00fcfen, ob sie funktionieren oder nicht. Das hei\u00dft, PairDB ist eine Art Gesamt\u00fcbersicht \u00fcber den Zustand aller Festplatten unseres Systems.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/d50781b8b51ed5fe126bc84e19c934d1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Pair DB: Datenbank mit dem Zustand der Paare<\/em><\/p>\n<p><\/p>\n<p>In den Paaren werden Dateien gespeichert, und um zu wissen, welche Datei sich bei welchem Paar befindet, ist eine weitere Datenbank n\u00f6tig \u2013 FileDB. Sie speichert das Mapping, die Zuordnung: Diese Datei wird bei diesem Paar gespeichert, sowie eine kleine Anzahl ben\u00f6tigter Attribute.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/b1a64737cf7f916bff446c10c1f01d4c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><em>File DB: Ort, an dem die Datei gespeichert wird<\/em><\/p>\n<p>Ein weiteres wichtiges Glied ist der Dienst Nylon, ein Router f\u00fcr die Arbeit mit Datenbanken. Er ist der einzige Einstiegspunkt und erm\u00f6glicht die Arbeit \u00fcber eine einheitliche Schnittstelle sowohl mit PairDB als auch mit FileDB. Dies ist ein stateless-Dienst, er f\u00fchrt die Lastverteilung der Anfragen durch, versteht, zu welchem Shard FileDB navigiert werden muss, und wei\u00df, welche Paare aktiv sind und welche nicht.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/3e2225f229c8cfa462d620d2b5fb581e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Nylon: Router f\u00fcr die Arbeit mit Datenbanken<\/em><\/p>\n<p><\/p>\n<p>Au\u00dferdem muss der Inhalt irgendwie in das Speicher gespeichert werden. Daf\u00fcr gibt es den Dienst \u2013 Streamer. Er bietet zwei HTTP-Methoden an: die PUT-Methode, um Inhalte in den Speicher hochzuladen, und die GET-Methode, um sie dort abzurufen. HTTP ist ein ziemlich beliebtes und bequemes Protokoll f\u00fcr die Daten\u00fcbertragung. <\/p>\n<p><\/p>\n<p>Wenn wir auf Streamer\u2018y zugreifen, kommuniziert er \u00fcber Nylon mit PairDB, um herauszufinden, auf welches Paar die Datei hochgeladen werden kann, und \u00fcbertr\u00e4gt die Daten anschlie\u00dfend \u00fcber WebDAV an dieses Paar. <\/p>\n<p><\/p>\n<p>Im Grunde genommen ist jeder Storage-Server nginx plus die Platten, die an vorgegebene Pfade eingebunden sind. Wir k\u00f6nnen \u00fcber den Streamer eine Datei in den Speicher hochladen, sie l\u00f6schen, umbenennen oder ihre Integrit\u00e4t \u00fcberpr\u00fcfen. Das hei\u00dft, dies ist eine bequeme Schnittstelle f\u00fcr die niedrigstufige Interaktion mit dem Speicher. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/3722a89ed44cace36e9cb1f8bee4bd1e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Streamer: Einstiegspunkt in den Speicher<\/em><\/p>\n<p><\/p>\n<h2 id=\"chto-my-dobavili-chtoby-sdelat-s3-hranilische\">Was wir hinzugef\u00fcgt haben, um die S3-Speicherung zu erstellen<\/h2>\n<p><\/p>\n<p>Also, wir haben die grundlegende Struktur des Speichers betrachtet, als wir bereit waren, S3-Speicher zu implementieren. Mithilfe der PUT-Methode konnten wir dort beliebige Inhalte ablegen und als Identifikator dieser Daten einen Hash erhalten. Mit diesem Identifikator konnte man sp\u00e4ter zur\u00fcckkehren und die urspr\u00fcngliche Datei abholen. Aber das reicht nicht f\u00fcr die Implementierung von S3. Im S3-Protokoll gibt es neben der eigentlichen Speicherung der Objekte auch:<\/p>\n<p><\/p>\n<ul>\n<li>Speicherung von Metadaten \u2013 zus\u00e4tzlichen Eigenschaften der Objekte;<\/li>\n<li>Zugriffsorganisation auf Objekte \u00fcber HTTP;<\/li>\n<li>Gruppierung von Objekten in Sammlungen \u2013 Buckets;<\/li>\n<li>HTTP-S3-Endpunkt. S3 organisiert Daten in bestimmte Strukturen \u2013 Buckets, von denen jeder einen Einstiegspunkt f\u00fcr die Speicherung von Dateien bietet.<\/li>\n<\/ul>\n<p><\/p>\n<p>Um diese Logik umzusetzen, war ein separater Dienst erforderlich. Auch wollte man gleich die Architektur f\u00fcr das zuk\u00fcnftige Wachstum des Dienstes mit linearer Skalierbarkeit voraussehen.<\/p>\n<p><\/p>\n<h2 id=\"pervye-komponenty\">Erste Komponenten<\/h2>\n<p><\/p>\n<p>Ein Demon, der die S3-API implementiert. Dies ist die Standard-S3-API von Amazon, die die Arbeit mit XML f\u00fcr Metadaten unterst\u00fctzt und es erm\u00f6glicht, Inhalte direkt zu \u00fcbertragen. Wir mussten nichts neu erfinden, alles ist beschrieben und dokumentiert.<\/p>\n<p><\/p>\n<p>Vor dem Dienst haben wir auch Nginx bereitgestellt. Diesen haben wir f\u00fcr die SSL-Terminierung, Lastverteilung sowie f\u00fcr einige Logik in Lua (Metriken, Logging und Tracing) verwendet.<\/p>\n<p><\/p>\n<p>F\u00fcr die Speicherung der S3-Metadaten haben wir ebenfalls Tarantool gew\u00e4hlt. In der ersten Version ging der S3-Demon f\u00fcr Metadaten in diese Datenbank; die Inhalte wurden in einem gro\u00dfen Speicher \u00fcber Streamer aufbewahrt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/03dddec282b5bb41eb63748ccfb6c9a4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<em>Nginx + S3 API + Metadaten<\/em><\/p>\n<p><\/p>\n<h2 id=\"obektnaya-model-hraneniya\">Objektmodell f\u00fcr die Speicherung<\/h2>\n<p><\/p>\n<p>Schauen wir uns an, wie S3 funktioniert. Der Benutzer kann einen Bucket erstellen \u2013 eine Sammlung von Objekten. Der Bucket wird \u00fcber 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\u00e4rdaten, das wir im Speicher aufbewahren werden. Auch hat das Objekt Attribute: den Namen \u2013 die eben genannte URL, ACL (Zugriffssteuerungsliste), sowie andere zus\u00e4tzliche oder benutzerdefinierte Attribute \u2013 all dies wird in den Metadaten gespeichert. <\/p>\n<p><\/p>\n<p>Das normalisierte Schema dieser Daten k\u00f6nnte so aussehen: Es gibt Projekte, die Buckets besitzen, die Objekte besitzen k\u00f6nnen, und Objekte k\u00f6nnen zusammengesetzt sein. Da ein Objekt auf verschiedene Teile hochgeladen werden kann, gibt es daf\u00fcr zwei Hilfstabellen: uploads und chunks. Auch haben Projekte Zugangsdaten und Abrechnungen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/e2bede45ba4044f658b47a9840fd5224.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<em>Datenschema<\/em><\/p>\n<p><\/p>\n<p>Da wir einen B2B-Dienst mit kostenpflichtigem Zugang erstellt haben, war in diesem Schema eine Abrechnung erforderlich.<br \/>\nDen Abrechnungsdienst haben wir ebenfalls in Tarantool umgesetzt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/d5b1a63e2273e933c95deecdb054bfe6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"dorabotki-s3-hranilischa-shagi-k-prodakshenu\">Verbesserungen am S3-Speicher: Schritte zur Produktion<\/h2>\n<p><\/p>\n<p>Wir haben bereits ein funktionierendes Modell erstellt, das verwendet werden kann: Objekte und Metadaten wurden gespeichert, aber f\u00fcr den Produktionsstart fehlten noch einige Punkte.<\/p>\n<p><\/p>\n<p>Zun\u00e4chst das System der Ratenbegrenzung. Wenn man den Dienst ohne dieses System starten w\u00fcrde, k\u00f6nnten wir bei hoher Auslastung unvorhersehbare \u00dcberlastungen in einem Teil des Systems verursachen. Die Ratenbegrenzung sollte so funktionieren: Jeder S3-Anfrage wird an einen bestimmten Host gesendet, dieser Host ist der Identifikator des Buckets, und der Bucket geh\u00f6rt einem bestimmten Kunden. Wir m\u00fcssen eine Funktion f\u00fcr den Bucket definieren, die es uns erm\u00f6glicht, die Ratenbegrenzung zu berechnen. <\/p>\n<p><\/p>\n<p>Au\u00dferdem sollte das System der Ratenbegrenzung leistungsf\u00e4hig genug sein, um die Last, die auf S3 einwirkt, zu bew\u00e4ltigen.<\/p>\n<p><\/p>\n<p>Hier haben wir erneut Tarantool verwendet. Die Ratenbegrenzungen sind ein Cluster aus 21 Instanzen, die Instanzen sind in Gruppen aufgeteilt, \u00fcber drei physische Knoten verteilt und zu einem gro\u00dfen topologischen Cluster zusammengefasst. Konfigurations\u00e4nderungen werden automatisch darauf verteilt: Ratenbegrenzungen, Standardwerte und Konfiguration werden festgelegt. Jeder Bucket wird strikt von einer einzigen Instanz bedient. Wenn eine Anfrage f\u00fcr einen bestimmten Bucket eingeht, wird die zust\u00e4ndige Instanz f\u00fcr diesen Bucket ermittelt. Innerhalb dieses Knotens wird die aktuelle Anfragerate nach einem Algorithmus berechnet, der dem Token-Bucket \u00e4hnelt. Anschlie\u00dfend teilt das System der Ratenbegrenzung, basierend auf den aktuellen Lastwerten und den f\u00fcr den spezifischen Bucket festgelegten Eigenschaften, mit, ob die Anfrage ausgef\u00fchrt werden kann oder nicht. Die \u00dcberpr\u00fcfung der Limits erfolgt in der fr\u00fchesten Phase der Ausf\u00fchrung der S3-Anfrage, wodurch alle anderen Elemente des Systems vor \u00fcberm\u00e4\u00dfiger Belastung gesch\u00fctzt werden. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/1b91e5d1fe067c859ba9b36d58827579.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Auch unter Last ist es ziemlich schwierig, ohne Cache auszukommen. In S3 wird mehrfach auf dieselben Objekte zugegriffen, was bedeutet, dass es sich um einen hei\u00dfen Speicher handelt. Normalerweise wird der Zugriff auf eine einzelne Datei \u00fcber den gesamten Prozess bedient: Streamer, FileDB, PairDB, Storage. Bei mehrfachen Zugriffen auf eine Datei optimieren wir jedoch den Zugriff auf diesen Inhalt mithilfe eines lokalen Caches.<\/p>\n<p><\/p>\n<p>Der Cache ist mehrschichtig und wird mit nginx, lokalen, SSD- und RAM-Laufwerken realisiert. Hier haben wir Tarantool nicht verwendet, da es bequemer ist, Objekte aus dem Dateisystem auszuliefern, so k\u00f6nnen wir ein Cache-Tiering durchf\u00fchren. Au\u00dferdem haben wir gro\u00dfe Objekte mit einer maximalen Gr\u00f6\u00dfe von 32 Gigabyte, w\u00e4hrend in Tarantool nur kleine Objekte zwischengespeichert werden k\u00f6nnen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/faa02bd52a1d70642589d775f22c5e75.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dieses erste System, mit dem wir gestartet sind, hatte eine berechnete Kapazit\u00e4t, die f\u00fcr die Erforschung und das Verst\u00e4ndnis des Produkts ausreichte, sowie f\u00fcr die Gewissheit, dass es funktionieren wird. <\/p>\n<p><\/p>\n<h2 id=\"dorabotki-boevoy-sistemy-feylover-i-masshtabirovanie\">Verbesserungen am Kampfsystem: Failover und Skalierung<\/h2>\n<p><\/p>\n<p>Das System war bereits im Einsatz, wobei wir anfangs einige Punkte verpasst hatten \u2013 es war notwendig, Failover und Skalierung hinzuzuf\u00fcgen. <\/p>\n<p><\/p>\n<p>Unser S3-D\u00e4mon holte Metadaten \u00fcber das Tarantool-Protokoll ab. Anstelle der urspr\u00fcnglichen Datenbank setzten wir Tarantool ein, der als Proxy-Router f\u00fcr Anfragen nach Metadaten fungierte. Aus der Sicht der Anwendung, die die API umsetzt, hat sich nichts ge\u00e4ndert \u2013 sie greift weiterhin \u00fcber das Tarantool-Protokoll auf die Datenbank zu, aber der Router konnte aktives Failover bereitstellen. Das hei\u00dft, wir konnten die Verf\u00fcgbarkeit des Knotens \u00fcberwachen, Wartezeiten bei Umschaltungen und Ausf\u00e4llen einhalten und so weiter. Die Anwendung selbst wurde dabei nicht modifiziert. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/978ff8a458f8d48b98672121cf6eca5d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"podrobnee-o-tom-kak-my-realizovali-shardirovanie\">Mehr \u00fcber die Implementierung der Shardierung<\/h2>\n<p><\/p>\n<p>Die n\u00e4chste Herausforderung, um die wir uns k\u00fcmmern mussten, war die Shardierung. Das System wuchs, die Anzahl der Objekte stieg, und es war notwendig, M\u00f6glichkeiten f\u00fcr weiteres Wachstum zu schaffen.<\/p>\n<p><\/p>\n<p>Kehren wir zum Datenschema zur\u00fcck: Es gibt Projekte, Buckets, Credenzen und Billing. Das sind Objekte, die mit hoher Wahrscheinlichkeit in naher Zukunft weder hinsichtlich des Volumens noch der Anfragen \u00fcber den Rahmen einer einzelnen Instanz hinauswachsen werden. Daher macht es keinen Sinn, sie zu sharden, und wir haben sie in eine separate Instanz ausgelagert, die ungeshardet bleibt. Dies erm\u00f6glicht ein konsistenteres Management von Projekten und Buckets, da es einen einheitlichen ungeshardeten Punkt gibt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/c5a1c1a875e756e3dceb5f885fbda2c8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Au\u00dferdem gibt es im Schema Objekte, die linear wachsen \u2013 zun\u00e4chst waren es Hunderttausende, jetzt misst man ihre Anzahl in mehreren Milliarden. Solche Objekte und ihre Teile mussten in einen sharded Cluster verschoben werden. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/00bb418cc61ad2e3e8797caf5d1ab202.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben das Schema aufgeteilt, aber die Objekte m\u00fcssen weiterhin mit den Buckets arbeiten: Ein Objekt geh\u00f6rt immer zu einem bestimmten Bucket, und auf dem Bucket wird ACL angewendet. Daher halten wir f\u00fcr jedes Shard mit Objekten eine Schattenkopie jedes Buckets. Zudem ist es w\u00e4hrend der Modifikation von Objekten und bei Anfragen notwendig, das Volumen f\u00fcr die Abrechnung zu ber\u00fccksichtigen, weshalb auf jedem Shard Z\u00e4hler f\u00fcr die Abrechnung vorhanden sind.<\/p>\n<p><\/p>\n<p>Wir haben auch einige zus\u00e4tzliche Tabellen und Komponenten hinzugef\u00fcgt:<\/p>\n<p><\/p>\n<ul>\n<li>einen Papierkorb zum L\u00f6schen alter Projekte, die gel\u00f6scht oder eingefroren werden.<\/li>\n<li>Warteschlange f\u00fcr Hintergrundaufgaben, das hei\u00dft, der prim\u00e4re Speicher kann Hintergrundaufgaben durchf\u00fchren, die auf dem Cluster erforderlich sind;<\/li>\n<li>Lifecycle-Unterst\u00fctzung \u2013 ein Mechanismus, der es erm\u00f6glicht, mit Objekten zu arbeiten und deren Lebenszyklus zu verwalten.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/933e98dc559eb8e6bac14003215a6836.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Da ein Teil der Daten auf Shards verteilt wurde, war ein sharding Proxy erforderlich. Man h\u00e4tte den Router f\u00fcr diese Rolle wiederverwenden k\u00f6nnen, aber ein separater sharding Proxy, der nur f\u00fcr das Sharding der Daten verantwortlich ist, erm\u00f6glicht es dem Router, die Daten insgesamt abzurufen, ohne \u00fcber das Sharding nachdenken zu m\u00fcssen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/4b181ed4629180e15558f25b1e4d5718.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich werde separat erl\u00e4utern, warum wir keine fertige L\u00f6sung \u00fcbernommen haben, sondern eine benutzerdefinierte Sharding-Funktion erstellen wollten. <\/p>\n<p><\/p>\n<p>Schauen wir uns an, wie es aufgebaut ist. Wir haben 256 verf\u00fcgbare Shards. F\u00fcr jeden Bucket bestimmen wir einen Bereich mit einer konsistenten Funktion. Es ist einfach \u2013 genau wie Sie mit einer konsistenten Funktion die Zugeh\u00f6rigkeit zu einem Shard bestimmen, legen Sie den Startshard fest und weisen einen Bereich zu:<\/p>\n<p><\/p>\n<p><code>f(bucket, shards) = subset<\/code><\/p>\n<p><\/p>\n<p>Das hei\u00dft, wenn Sie einen Bucket nehmen, k\u00f6nnen Sie sagen, dass er und seine Daten immer auf einer bestimmten Teilmenge aller Shards liegen werden. Dies verringert den Einfluss einzelner Buckets auf andere und vereinfacht die Durchf\u00fchrung von Map-Reduce-Abfragen, wenn beispielsweise eine Auflistung der Objekte eines Buckets erstellt werden muss. Dazu m\u00fcssen alle Shards abgefragt werden, auf denen diese Objekte gespeichert sind. Wenn die Objekte auf allen Shards w\u00e4ren, w\u00fcrde jede Auflistung die gesamte Systemleistung beeintr\u00e4chtigen, aber hier wird nur eine bestimmte Teilmenge betroffen.<\/p>\n<p><\/p>\n<p>Weiterhin geh\u00f6rt jedes Objekt zu einem bestimmten Bucket, daher greifen wir, wenn wir auf ein Objekt zugreifen, auf das Objekt anhand des Namens in einem bestimmten Bucket zu. Das hei\u00dft, wir k\u00f6nnen eine Funktion f\u00fcr ein Objekt nicht aus dem gesamten verf\u00fcgbaren Bereich der Shards, sondern nur aus der Teilmenge seines Buckets definieren:<\/p>\n<p><\/p>\n<p><code>f(object, subset) = shard<\/code><\/p>\n<p><\/p>\n<p>Wir nehmen ein bestimmtes Objekt und \u00fcbergeben als Argumente f\u00fcr die Funktion nicht alle Shards, sondern die Teilmenge seines Buckets \u2013 und erhalten den spezifischen Shard. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/10480ad2430c228c511ff3cdc5071596.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>So, das Sharding ist implementiert, es gibt einen sharding Proxy. Als n\u00e4chstes bleibt es, vom Router und der Metadaten-Datenbank auf den sharding Proxy zuzugreifen. Zum Beispiel bei der Erstellung von Objekten von Schattenkopien \u2013 wenn wir einen Bucket erstellen, muss der prim\u00e4re Speicher einen Vertreter dieses Buckets auf allen Shards erstellen, auf denen er vorhanden sein soll.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/bb34d1f747903a3c2f08f582e4424787.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"kak-my-realizovali-resharding\">Wie wir Resharding implementiert haben<\/h2>\n<p><\/p>\n<p>Das gr\u00f6\u00dfte Problem beim Sharding ist das Re-Sharding. Es war uns wichtig, dies ohne Ausfallzeiten zu schaffen, da das System bereits in Produktion war. Ich werde zeigen, wie wir das Problem an einem \u00e4hnlichen Beispiel mit der Live-Datenmigration von einem Projekt zu einem anderen gel\u00f6st haben.<\/p>\n<p><\/p>\n<p>Unten ist das Schema unseres Clusters, das nach der Implementierung des Shardings entstanden ist. Wir haben nginx, die S3 API, einen Router, eine prim\u00e4re Datenbank mit Projekten, einen Sharding-Proxy und die Shards selbst.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/0e6bd16c7fc47437b3b7d96b6d9809a4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich habe oben den Punkt ausgelassen, dass es zu einem bestimmten Zeitpunkt im Projekt eine produktbezogene Aufgabe gab: \"Ein weiteres Speicher, Icebox, zu starten \u2013 wie Hotbox, nur f\u00fcr kalte Daten\". Im Grunde genommen handelt es sich um dasselbe Speicher, nur unter anderen URLs und ohne Caches.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/9ce9085e1d03e9a99b6b8ccc0717c653.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Icebox wurde weniger genutzt als Hotbox, daher kam es relativ lange ohne Sharding aus. Letztendlich haben wir beschlossen, darauf zu verzichten und Hotbox und Icebox zu einem Dienst zusammenzuf\u00fchren, indem wir die Speicherklassen einfach trennten. <\/p>\n<p><\/p>\n<p>Die Buckets in den Storages \u00fcberschneiden sich nicht, sie konnten einfach zusammengef\u00fchrt und verschoben werden, aber die Kunden nutzten sowohl das eine als auch das andere Storage, was bedeutete, dass wir das Problem ohne Ausfallzeiten l\u00f6sen mussten. Wir konnten nicht einfach abschalten und kopieren. Wir f\u00fchrten die Migration in mehreren Phasen durch.<\/p>\n<p><\/p>\n<p>Zun\u00e4chst synchronisierten wir die prim\u00e4ren Storages. Wir hatten Tarantool und konnten bei der Erstellung eines Objekts Folgendes tun: <\/p>\n<p><\/p>\n<ul>\n<li>Eine Anfrage zur Erstellung eines Buckets geht an die Datenbank, zum Beispiel in Hotbox;<\/li>\n<li>Tarantool \u00fcberpr\u00fcft in einer anderen Datenbank (in diesem Fall in Icebox), dass es einen solchen Bucket nicht gibt;<\/li>\n<li>Wenn der Bucket vorhanden ist, teilt die Datenbank mit, dass er nicht erstellt werden kann, und er synchronisierte sich als bestehend.<br \/>\n<img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/6694c9804f09942416c1717b455b9fd3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<em>Synchronisation der Buckets<\/em><\/li>\n<\/ul>\n<p><\/p>\n<p>In dem Storage, das alle Daten aufnehmen sollte, wurde f\u00fcr Projekte und Buckets ein Kennzeichen eingef\u00fchrt, das angibt, wo sich dieses Objekt befindet. Es konnte lokal in Hotbox gespeichert werden, in Icebox \u2013 dann gibt es im neuen Storage keine Daten davon, oder es konnte sich im Zustand der Migration befinden.<\/p>\n<p><\/p>\n<p>Wenn f\u00fcr ein Projekt oder einen Bucket das Kennzeichen 'Migrating' gesetzt war, wurde die Anfrage w\u00e4hrend der Migration zun\u00e4chst an das neue Storage gesendet, in dem die Daten gespeichert sein sollten. Falls diese dort nicht vorhanden waren, wurden die Anfragen an das alternative Storage umgeleitet.<\/p>\n<p><\/p>\n<p>Danach haben wir den Traffic umgeschaltet. Da die API sowohl Anfragen an Icebox als auch an Hotbox bedienen konnte, konnten wir den Traffic ohne Ausfallzeiten umschalten, indem wir einfach die Hosts verschoben und die entsprechenden Eintr\u00e4ge in Nginx hinzugef\u00fcgt haben. <\/p>\n<p><\/p>\n<p>Nachdem der Traffic umgeleitet wurde, konnten Nginx und die API von Icebox entfernt werden.<br \/>\nDann haben wir Icebox nginx und S3 API entfernt \u2013 und alles funktionierte:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/62d9f960fc1f11b875a8f8a5aa8e8152.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Anschlie\u00dfend haben wir einen Hintergrundprozess f\u00fcr die Migration gestartet, der innerhalb der Datenbank l\u00e4uft \u2013 er durchl\u00e4uft alle Projekte und deren Buckets elementweise, setzt f\u00fcr sie das Zeichen Migrating, \u00fcbertr\u00e4gt die Daten und setzt nach Abschluss der \u00dcbertragung das Zeichen Local.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/1a3129136f7ccacfdcff260f10cb0605.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nach der Daten\u00fcbertragung ben\u00f6tigen wir das alte Speicher nicht mehr, und wir entfernen die verbleibenden Teile des alten Systems sowie die Unterst\u00fctzung f\u00fcr den Migrationsstatus aus dem Code.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/13b6f11add40c21a3b9afc05dd0dfea9.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nach den gleichen Prinzipien wurde auch der Resharding aus dem alten Speicher in den shardierten Speicher durchgef\u00fchrt:<\/p>\n<p><\/p>\n<ul>\n<li>Wir haben alle Buckets als <code>Non-sharded<\/code>markiert. Alle Anfragen an sie gingen in den urspr\u00fcnglichen, nicht shardierten Speicher.<\/li>\n<li>Neue Buckets wurden sofort im Status <code>Sharded<\/code>.<\/li>\n<li>erstellt. Wir haben Buckets einzeln genommen, den Status <code>Migrating<\/code> gesetzt und die Daten \u00fcbertragen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Die Anfragen wurden dabei nach folgendem Prinzip bearbeitet:<\/p>\n<p><\/p>\n<ul>\n<li>Zuerst im neuen lesen, dann im alten.<\/li>\n<li>Erstellen nur im neuen.<\/li>\n<li>Bei der Aktualisierung in zwei Phasen: Wenn im neuen nichts vorhanden ist, \u00fcbertragen wir von alt nach neu, dann aktualisieren wir.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"rabota-s-ssl-sertifikatami\">Arbeiten mit SSL-Zertifikaten<\/h2>\n<p><\/p>\n<blockquote><p>Im Frontend verwenden wir Nginx. In unserem Fall ist es nicht das gew\u00f6hnliche Nginx, sondern OpenResty, Nginx mit LuaJIT-Unterst\u00fctzung.<\/p><\/blockquote>\n<p>Ein weiteres Teil des Systems ist die Arbeit mit SSL-Zertifikaten. Im S3-Speicher k\u00f6nnen Sie eine eigene Domain f\u00fcr den Zugriff auf einen bestimmten Bucket einrichten, einfach durch <code>CNAME<\/code>. Aber ohne HTTPS geht es heutzutage nicht: Eine eigene Domain setzt ein eigenes SSL-Zertifikat voraus. <\/p>\n<p><\/p>\n<p>Wie ich bereits sagte, ist Nginx f\u00fcr das Load Balancing und die SSL-Terminierung zust\u00e4ndig. In unserem Fall ist es nicht das normale Nginx, sondern OpenResty, Nginx mit LuaJIT-Unterst\u00fctzung.<\/p>\n<p><\/p>\n<p>Das hat es uns erm\u00f6glicht, Nginx relativ einfach dazu zu bringen, beliebige Zertifikate auszugeben. Dar\u00fcber hinaus war es notwendig, die Zertifikate dynamisch auszugeben (ohne sie in der Konfigurationsdatei festzuschreiben). Wir haben das Modul <code>ssl_certificate_by_lua<\/code>verwendet, das es erlaubt, Zertifikate aus beliebigen Quellen direkt w\u00e4hrend des TLS-Handshakes zu lesen. Als Zertifikatsspeicher haben wir ebenfalls Tarantool verwendet: das erm\u00f6glicht eine zentrale Verwaltung der Zertifikate und sorgt f\u00fcr eine extrem schnelle Bereitstellung.<\/p>\n<p><\/p>\n<p>Es wurde au\u00dferdem ein separater Daemon implementiert, dessen Aufgabe es ist, die mit Let\u2019s Encrypt ausgestellten Zertifikate regelm\u00e4\u00dfig zu aktualisieren.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Architektur S3: 3 Jahre Evolution des Mail.ru Cloud Storage\" src=\"\/wp-content\/uploads\/2020\/08\/8d61c1cb3084d9eb4eb8faa745e212db.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"chto-by-ya-sohranil-a-chto-sdelal-po-drugomu-esli-razrabatyvat-hranilische-zanovo\">Was ich gespeichert h\u00e4tte und was ich anders gemacht h\u00e4tte, wenn ich das Speicherreservoir von Grund auf neu entwickeln w\u00fcrde<\/h2>\n<p><\/p>\n<h3 id=\"chto-nuzhno-bylo-ispolzovat-s-samogo-nachala\">Was von Anfang an h\u00e4tte genutzt werden m\u00fcssen<\/h3>\n<p><\/p>\n<p><strong>Sharding sofort<\/strong>. Relativ viele Probleme wurden durch das Resharding verursacht. Es ist leicht umzusetzen, aber, dennoch, wenn man Projekte startet, die skalierbar sein m\u00fcssen, sollte man sofort einen shardierten Cluster w\u00e4hlen, selbst wenn es nur eine minimale Anzahl von Knoten ist. Die Umsetzung von Sharding zu Beginn ist fast kostenlos im Vergleich zur Implementierung von Sharding in ein laufendes System.<\/p>\n<p><\/p>\n<p><strong>Arbeiten mit Tarantool \u00fcber Load Balancer<\/strong>. Jetzt schlie\u00dfen wir alle neuen Datenbanken sofort \u00fcber Load Balancer in den Betrieb ein. Dies erm\u00f6glicht es, die Funktionalit\u00e4t zu erweitern und eine h\u00f6here Ausfallsicherheit zu erreichen. <\/p>\n<p><\/p>\n<p><strong>Auto-Failover<\/strong>. Ich h\u00e4tte alle notwendigen Werkzeuge f\u00fcr das Auto-Failover installiert, da die ersten Misserfolge nach dem Start auf dessen Fehlen zur\u00fcckzuf\u00fchren waren. Nach der Erfahrung mit S3 wurden alle folgenden Produkte unter Ber\u00fccksichtigung dessen gestartet.<\/p>\n<p><\/p>\n<p><strong>S3-Funktion \u201eVersionierung\u201c<\/strong>. Zun\u00e4chst schien es, dass dies eine nicht sehr gefragte Funktionalit\u00e4t ist. Diese M\u00f6glichkeit in die Architektur eines funktionierenden Systems zu integrieren, ist \u00e4u\u00dferst schwierig.<\/p>\n<p><\/p>\n<p><strong>Getrennte Abrechnung<\/strong>. Die Art, wie wir die Abrechnung in unser System integriert haben, hat sich zu Beginn als sehr gut erwiesen, wurde jedoch sp\u00e4ter st\u00f6rend; es w\u00e4re besser gewesen, dies als einen v\u00f6llig separaten Dienst bereitzustellen.<\/p>\n<p><\/p>\n<h3 id=\"chto-bylo-udachnym-resheniem\">Was eine erfolgreiche Entscheidung war<\/h3>\n<p><\/p>\n<p><strong>Datenmodell<\/strong>. Die Geschichte hat gezeigt, dass wir mit der Entwicklung des Dienstes recht genau mit dem Datenmodell von Amazon \u00fcbereinstimmen, daher k\u00f6nnen wir die Funktionen implementieren, die dort vorhanden sind.<\/p>\n<p><\/p>\n<p><strong>Shardierungsschema<\/strong>. Ich w\u00fcrde \u00e4hnliche Bereichs-Shardings nach Buckets unterst\u00fctzen, da dies erm\u00f6glicht, Anfragen von verschiedenen Buckets gut \u00fcber einen gro\u00dfen Cluster zu verteilen.<\/p>\n<p><\/p>\n<p><strong>Verwendung von Tarantool<\/strong>. Tarantool hat bei der Entwicklung des Dienstes und seiner Modifikation erheblich geholfen; wir haben problemlos mit den Daten gearbeitet, transformiert und das Speicherreservoir shardiert, ohne auf die Anwendungsebene steigen zu m\u00fcssen. <\/p>\n<p><\/p>\n<blockquote><p>Dieser Bericht wurde erstmals auf <noindex><a rel=\"nofollow\" href=\"https:\/\/corp.mail.ru\/ru\/press\/events\/databases-2\/\">@Databases Meetup<\/a><\/noindex> by Mail.ru Cloud Solutions&amp;Tarantool. Siehe <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=jM4hL2u6JM0&amp;list=PLQzTaxmOHjntyNRPWhaWHqlHp8UN_wgQ3\">das Video<\/a><\/noindex> weitere Vortr\u00e4ge und abonnieren Sie die Ank\u00fcndigungen von Veranstaltungen auf Telegram <noindex><a rel=\"nofollow\" href=\"https:\/\/t.me\/k8s_mail\">Rund um Kubernetes in der Mail.ru Group<\/a><\/noindex>.<\/p><\/blockquote>\n<p>Sie k\u00f6nnen auch meinen alten Vortrag \u00fcber S3 ansehen oder den Artikel meines Kollegen \u00fcber Blockspeicher lesen.<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=O0iIADHgBVc\">Reverse Engineering der Architektur von Amazon S3 und wie das S3-Speicherreservoir von MCS vor 3 Jahren aussah<\/a><\/noindex>.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/472694\/\">Mehr als Ceph: Blockspeicher der MCS-Cloud<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/513356\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Storage Corridor by St-Pete \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u042f Mons Anderson, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b Mail.ru Cloud Solutions, \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043d\u0430\u0448\u0435 S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0430\u043a \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0443\u0434\u0430\u0447\u043d\u044b\u043c\u0438, \u0430 \u043a\u0430\u043a\u0438\u0435 \u0441\u0442\u043e\u0438\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043d\u0443\u043b\u044f \u0441\u0435\u0439\u0447\u0430\u0441. \u0421\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430 @Databases Meetup by Mail.ru Cloud Solutions &amp; Tarantool. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":91091,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-91090","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 S3: 3 \u0433\u043e\u0434\u0430 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u0438 Mail.ru Cloud Storage | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-08T11:42:11+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-08T11:42:11+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47S3-Architektur: 3 Jahre Evolution des Mail.ru Cloud Storage | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 S3: 3 \u0433\u043e\u0434\u0430 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u0438 Mail.ru Cloud Storage | ProHoster","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-s3-3-goda-evolyuczii-mail-ru-cloud-storage","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-08T11:42:11+00:00","article:modified_time":"2020-08-08T11:42:11+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"91090","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:34:25","updated":"2022-10-02 13:27:50","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/91090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=91090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/91090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/91091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=91090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=91090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=91090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}