{"id":55009,"date":"2020-01-10T00:00:00","date_gmt":"2020-01-09T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo"},"modified":"2020-02-18T14:03:04","modified_gmt":"2020-02-18T11:03:04","slug":"arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","title":{"rendered":"Architektur der Speicherung und Ausgabe von Fotos in Badoo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/04d68ff091d9d271bfd352a6639e2f20.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Artem Denisov ( <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/users\/bo0rsh201\/\" class=\"user_link\">bo0rsh201<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/company\/badoo\/\">Badoo<\/a><\/noindex>)<\/h2>\n<p>\nBadoo ist die gr\u00f6\u00dfte Dating-Website der Welt. Momentan haben wir etwa 330 Millionen Nutzer weltweit registriert. Doch was in unserem heutigen Gespr\u00e4ch viel wichtiger ist, ist die Tatsache, dass wir ungef\u00e4hr 3 Petabyte an Nutzerdaten speichern. Jeden Tag laden unsere Nutzer etwa 3,5 Millionen neue Fotos hoch, und die Leselast betr\u00e4gt etwa <b>80.000 Anfragen pro Sekunde<\/b>. Das ist ziemlich viel f\u00fcr unser Backend, und manchmal gibt es dabei Herausforderungen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4e4690f9b0d95bd76fbbc1cd6805c26c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIch werde \u00fcber das Design dieses Systems sprechen, das die Fotos insgesamt speichert und bereitstellt, und ich werde einen Entwicklerblick darauf werfen. Es wird eine kurze Retrospektive dar\u00fcber geben, wie es sich entwickelt hat, wo ich die wichtigsten Meilensteine aufzeigen werde, aber ich werde nur ausf\u00fchrlich \u00fcber die L\u00f6sungen sprechen, die wir jetzt verwenden.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nJetzt lass uns anfangen.<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"SU9ETg39FEg\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/SU9ETg39FEg\/hqdefault.jpg\" alt=\"Video abspielen\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nWie ich bereits sagte, wird dies eine Retrospektive sein, und um sie zu beginnen, lasst uns ein ganz banales Beispiel nehmen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/22b9627cda7ccadd9869b64e9d043d89.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben eine allgemeine Aufgabe, wir m\u00fcssen die Fotos der Nutzer empfangen, speichern und bereitstellen. In dieser Form ist die Aufgabe allgemein, wir k\u00f6nnen alles M\u00f6gliche verwenden:<\/p>\n<ul>\n<li>moderne Cloud-Speicher,<\/li>\n<li>Fertigungsl\u00f6sungen, von denen es jetzt auch viele gibt;<\/li>\n<li>wir k\u00f6nnen mehrere Maschinen in unserem Rechenzentrum einrichten und gro\u00dfe Festplatten darauf installieren und die Fotos dort speichern.<\/li>\n<\/ul>\n<p>\nBadoo lebt historisch \u2014 sowohl jetzt als auch damals (zur Zeit des Entstehens) \u2014 auf eigenen Servern, innerhalb unserer eigenen Rechenzentren. Daher war diese Option f\u00fcr uns optimal.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9434fbabada15670297c551066ad7e71.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben einfach mehrere Maschinen genommen, sie \"photos\" genannt, und so haben wir einen Cluster erstellt, der die Fotos speichert. Aber es scheint, als w\u00fcrde etwas fehlen. Damit das alles funktioniert, muss man irgendwie bestimmen, auf welcher Maschine welche Fotos gespeichert werden. Und hier muss man auch nicht das Rad neu erfinden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/36258e7107fd8c60f7e9e563a2cb681c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir f\u00fcgen in unser Speichersystem mit Informationen \u00fcber die Nutzer ein Feld hinzu. Das wird der Sharding-Schl\u00fcssel sein. In unserem Fall haben wir es place_id genannt, und diese ID des Ortes gibt an, wo die Fotos der Nutzer gespeichert werden. Wir erstellen Karten.<\/p>\n<p>In der ersten Phase kann man das sogar von Hand machen \u2013 wir sagen, dass das Foto dieses Benutzers mit diesem Standort auf diesem Server gespeichert wird. Dank dieser Karte wissen wir immer, wann ein Benutzer ein Foto hochl\u00e4dt, wo wir es speichern und von wo wir es zur\u00fcckgeben k\u00f6nnen.<\/p>\n<p>Es ist ein absolut triviales Schema, aber es hat einige ziemlich wesentliche Vorteile. Erstens \u2013 es ist einfach, wie ich bereits gesagt habe, und zweitens \u2013 mit diesem Ansatz k\u00f6nnen wir leicht horizontal skalieren, indem wir einfach neue Maschinen bereitstellen und sie in die Karte aufnehmen. Es gibt nichts weiter zu tun.<\/p>\n<p>So war es eine Zeit lang bei uns.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3effb442702f162f7bad9c18ec54392e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas war ungef\u00e4hr im Jahr 2009. Wir haben Autos geliefert, geliefert\u2026<\/p>\n<p>Und irgendwann bemerkten wir, dass dieses Schema bestimmte Nachteile hatte. Welche Nachteile?<\/p>\n<p>In erster Linie ist es die begrenzte Kapazit\u00e4t. Auf einen physischen Server k\u00f6nnen wir nicht so viele Festplatten unterbringen, wie wir gerne h\u00e4tten. Und das wurde mit der Zeit und dem Wachstum des Datensatzes zu einem bestimmten Problem.<\/p>\n<p>Und zweitens. Es ist eine untypische Maschinenkonfiguration, da solche Maschinen schwer in anderen Clustern wiederverwendet werden k\u00f6nnen; sie sind recht spezifisch, das hei\u00dft, sie sollten leistungsschwach sein, aber gleichzeitig gro\u00dfe Festplatten besitzen.<\/p>\n<p>Das alles war 2009 der Fall, aber im Prinzip sind diese Anforderungen bis heute relevant. Wir haben eine R\u00fcckschau, sodass es 2009 in dieser Hinsicht wirklich schlecht war.<\/p>\n<p>Und der letzte Punkt \u2013 der Preis.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e49010eaeab139199d8fe010caa65bf0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDer Preis war damals sehr hoch, und wir mussten nach Alternativen suchen. Das hei\u00dft, wir mussten einen besseren Umgang mit dem Platz in den Rechenzentren und den physischen Servern finden, auf denen das alles l\u00e4uft. Unsere Systemingenieure begannen mit umfassenden Untersuchungen und \u00fcberdachten viele verschiedene Optionen. Sie schauten sich auch Clusterdateisysteme wie PolyCeph und Lustre an. Dort gab es Probleme mit der Leistung und eine recht komplexe Wartung. Sie haben es aufgegeben. Sie haben versucht, den gesamten Datensatz \u00fcber NFS auf jede Maschine zu mounten, um auf diese Weise irgendwie zu skalieren. Das Lesen hat sich ebenfalls als problematisch erwiesen, sie haben verschiedene L\u00f6sungen von verschiedenen Anbietern ausprobiert.<\/p>\n<p>Am Ende haben wir uns darauf geeinigt, dass wir das sogenannte Storage Area Network verwenden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e99402fa641f3bd5fc8d57a9f8995642.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas sind gro\u00dfe SHDs, die darauf ausgelegt sind, gro\u00dfe Datenmengen zu speichern. Sie bestehen aus Regalen mit Festplatten, die an die Endger\u00e4te \u00fcber Optik angeschlossen sind. So haben wir einen relativ kleinen Pool an Maschinen, und diese SHDs sind f\u00fcr unsere Abgabelogik transparent, das hei\u00dft, f\u00fcr unser Nginx oder andere, die die Anfragen nach diesen Fotos bedienen.<\/p>\n<p>Diese L\u00f6sung hatte offensichtliche Vorteile. Es handelt sich um SHDs, die darauf ausgelegt sind, Fotos zu speichern. Das ist g\u00fcnstiger, als wenn wir Maschinen mit Festplatten einrichten.<\/p>\n<p>Der zweite Vorteil. <\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7fd2e7d629cc239096b14c68be5f76bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist die erh\u00f6hte Kapazit\u00e4t, d.h. wir k\u00f6nnen viel mehr Speicher in viel geringerem Volumen unterbringen.<\/p>\n<p>Aber es gab auch Nachteile, die ziemlich schnell bemerkbar wurden. Mit dem Wachstum der Nutzerzahl und der Last auf dieses System traten Leistungsprobleme auf. Und das Problem ist ziemlich offensichtlich \u2013 jede SHD, die darauf ausgelegt ist, viele Fotos in kleinem Volumen zu speichern, leidet in der Regel unter intensivem Lesen. Das gilt auch f\u00fcr jeden Cloud-Speicher und was auch immer. Es gibt derzeit keinen perfekten Speicher, der unendlich skalierbar ist, in den man alles hineinstecken kann und der gut mit Lesevorg\u00e4ngen zurechtkommt. Besonders mit zuf\u00e4lligen Lesevorg\u00e4ngen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/566e836e2fe13a2a3d040ae3fa865d6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWie im Falle unserer Fotos, weil die Fotos nicht sequenziell angefordert werden, was sich stark auf ihre Leistung auswirkt.<\/p>\n<p>Selbst nach den heutigen Zahlen, wenn wir irgendwo \u00fcber 500 RPS f\u00fcr Fotos pro Maschine, die mit dem Speicher verbunden ist, haben, treten bereits Probleme auf. Das war f\u00fcr uns ziemlich schlecht, weil die Anzahl der Nutzer steigt und alles schlimmer wird. Das muss irgendwie optimiert werden.<\/p>\n<p>Um zu optimieren, haben wir damals beschlossen, uns offensichtlich das Lastprofil anzusehen \u2013 was \u00fcberhaupt passiert ist und was optimiert werden muss.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d67310e6b90c4ee1337065790576c9a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd hier spielt alles in unsere H\u00e4nde.<\/p>\n<p>Ich habe bereits in der ersten Folie gesagt: Wir haben 80.000 Leseanfragen pro Sekunde bei insgesamt 3,5 Millionen Uploads pro Tag. Das ist ein Unterschied von drei Gr\u00f6\u00dfenordnungen. Es ist offensichtlich, dass das Lesen optimiert werden muss und praktisch klar ist, wie.<\/p>\n<p>Es gibt noch einen kleinen Punkt. Die Besonderheit des Services ist, dass sich der Nutzer registriert, ein Foto hochl\u00e4dt, dann aktiv andere Personen anschaut, ihnen gef\u00e4llt und er anderen aktiv gezeigt wird. Danach findet er einen Partner oder auch nicht, wie es eben kommt, und nutzt den Service f\u00fcr eine Weile nicht mehr. In diesem Moment, in dem er aktiv ist, sind seine Fotos sehr gefragt \u2013 sie werden von vielen Menschen angesehen. Sobald er damit aufh\u00f6rt, wird er ziemlich schnell aus den intensiven Anzeigen f\u00fcr andere Menschen herausgenommen, wie es vorher war, und seine Fotos werden kaum noch angefragt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/dcc7e306055d8f2b0895f24679bfc3e2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas hei\u00dft, wir haben einen sehr kleinen hei\u00dfen Datensatz. Aber gleichzeitig gibt es daf\u00fcr sehr viele Anfragen. Daher liegt es nahe, einen Cache hinzuzuf\u00fcgen.<\/p>\n<p>Ein LRU-Cache l\u00f6st all unsere Probleme. Was machen wir?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/2bd0c88a97d928f386db21549fc02500.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir f\u00fcgen vor unserem gro\u00dfen Cluster mit dem Storage noch einen vergleichsweise kleinen hinzu, der als Fotoscache (photoscache) bezeichnet wird. Das ist im Wesentlichen einfach ein cacheproxy.<\/p>\n<p>Wie funktioniert das intern? Hier ist unser Nutzer, da ist der Storage. Alles wie fr\u00fcher. Was f\u00fcgen wir zwischen ihnen hinzu?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7b7b5f102f1c012b2aef8f02ec731fac.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist einfach eine Maschine mit einer schnellen physischen Festplatte. Nehmen wir eine SSD. Und auf dieser Festplatte wird ein lokaler Cache gespeichert.<\/p>\n<p>Wie sieht das aus? Der Nutzer sendet eine Anfrage nach einem Foto. NGINX sucht zuerst in dem lokalen Cache danach. Wenn es nicht da ist, macht es einfach einen proxy_pass auf unseren Storage, l\u00e4dt das Foto von dort herunter und gibt es dem Nutzer.<\/p>\n<p>Aber das ist sehr banal und unverst\u00e4ndlich, was im Inneren passiert. So funktioniert es etwa.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/46be24df171d1008e2a9099b7e4c9be6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDer Cache ist logisch in drei Ebenen unterteilt. Wenn ich \"drei Ebenen\" sage, bedeutet das nicht, dass es ein komplexes System gibt. Nein, es sind einfach drei Verzeichnisse im Dateisystem:<\/p>\n<ol>\n<li>Das ist der Puffer, in den gerade aus dem Proxy hochgeladene Fotos gelangen.<\/li>\n<li>Das ist der hei\u00dfe Cache, in dem aktuell h\u00e4ufig angefragte Fotos gespeichert werden.<\/li>\n<li>Und der kalte Cache, in den Fotos schrittweise aus dem hei\u00dfen Cache gedr\u00e4ngt werden, wenn weniger Anfragen zu ihnen kommen.<\/li>\n<\/ol>\n<p>\nDamit das funktioniert, m\u00fcssen wir diesen Cache irgendwie verwalten, Fotos darin verschieben usw. Das ist ebenfalls ein sehr einfacher Prozess.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9b16fe3e99a5f88f06169f6e5eedf2b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNginx schreibt einfach f\u00fcr jede Anfrage in das RAMDisk access.log, in dem der Pfad zum Bild, das er gerade bedient hat (nat\u00fcrlich der relative Pfad), und welcher Abschnitt es bedient hat, angegeben ist. Das hei\u00dft, dort k\u00f6nnte stehen \u201eFoto 1\u201c und weiter entweder ein Puffer, ein hei\u00dfer Cache, ein kalter Cache oder ein Proxy.<\/p>\n<p>Je nach dem m\u00fcssen wir entscheiden, was mit dem Bild zu tun ist.<\/p>\n<p>Auf jeder Maschine l\u00e4uft ein kleiner Daemon, der st\u00e4ndig dieses Log ausliest und in seinem Speicher Statistiken \u00fcber die Nutzung der jeweiligen Bilder speichert.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0dceda5e5ff432d1609520f0c152f152.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEr sammelt einfach dort, f\u00fchrt Z\u00e4hler und macht periodisch Folgendes. Aktiv angeforderte Bilder, f\u00fcr die viele Anfragen kommen, verschiebt er in den hei\u00dfen Cache, wo auch immer sie abgelegt sind.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/941c13ecfea88372f3a7eb62d81b0c4e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBilder, die selten angefordert werden und noch seltener angefordert werden, schiebt er schrittweise aus dem hei\u00dfen Cache in den kalten.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a07235246995ad2fa4e6aeccae23a629.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd wenn unser Cache voll ist, beginnen wir einfach, alles ohne Unterscheidung aus dem kalten Cache zu l\u00f6schen. Und das funktioniert \u00fcbrigens gut.<\/p>\n<p>Damit das Bild sofort bei der Proxyierung im Puffer gespeichert wird, verwenden wir die Direktive proxy_store, und der Puffer ist ebenfalls ein RAMDisk, d.h. f\u00fcr den Benutzer funktioniert es sehr schnell. Das betrifft die Details des cachenden Servers.<\/p>\n<p>Es bleibt die Frage, wie wir die Anfragen auf diese Server verteilen.<\/p>\n<p>Angenommen, es gibt einen Cluster aus zwanzig Storage-Maschinen und drei cachenden Servern (so ist es dazu gekommen).<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6bc970b687701f3b6d57e153e3abed18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir m\u00fcssen irgendwie bestimmen, welche Anfragen nach welchen Bildern und wohin sie geleitet werden sollen.<\/p>\n<p>Die einfachste Variante ist Round Robin. Oder sollte man es zuf\u00e4llig machen?<\/p>\n<p>Das hat offensichtlich eine Reihe von Nachteilen, da wir in einer solchen Situation den Cache sehr ineffizient nutzen werden. Anfragen werden auf irgendwelche zuf\u00e4lligen Maschinen geleitet: hier wurde es zwischengespeichert, nebenan ist es schon nicht mehr da. Und das wird, falls es funktioniert, sehr schlecht sein. Sogar bei einer geringen Anzahl von Maschinen im Cluster.<\/p>\n<p>Wir m\u00fcssen irgendwie eindeutig bestimmen, auf welchen Server welche Anfrage geleitet wird.<\/p>\n<p>Es gibt eine simple Methode. Wir nehmen den Hash von der URL oder den Hash von unserem Sharding-Schl\u00fcssel, der in der URL enthalten ist, und teilen ihn ganzzahlig durch die Anzahl der Server. Wird das funktionieren? Ja.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/794a82ac1268b651ab936f0225b802a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas hei\u00dft, wir haben eine hundertprozentige Anfrage, zum Beispiel bei einer bestimmten \"example_url\" landet sie immer auf dem Server mit dem Index \"2\", und der Cache wird st\u00e4ndig so gut wie m\u00f6glich genutzt.<\/p>\n<p>Aber es gibt ein Problem mit dem Resharding in diesem Schema. Resharding \u2013 ich meine die Ver\u00e4nderung der Anzahl der Server.<\/p>\n<p>Angenommen, unser Cache-Cluster kann nicht mehr mithalten, und wir haben beschlossen, eine weitere Maschine hinzuzuf\u00fcgen.<\/p>\n<p>Wir f\u00fcgen hinzu.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5f2fcba4c4f267c069811c3677bd0213.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJetzt teilen wir alles nicht mehr durch drei, sondern durch vier. Somit leben praktisch alle Schl\u00fcssel, die wir zuvor hatten, fast alle URLs jetzt auf anderen Servern. Der gesamte Cache wurde einfach im Augenblick ung\u00fcltig. Alle Anfragen str\u00f6mten auf unser Cluster-Storage, es wurde schlimm, Dienstleisterausf\u00e4lle und unzufriedene Benutzer. So m\u00f6chte ich es nicht machen.<\/p>\n<p>Diese Option passt uns auch nicht.<\/p>\n<p>Was m\u00fcssen wir also tun? Wir m\u00fcssen somehow effizient den Cache nutzen, st\u00e4ndig eine Anfrage auf denselben Server leiten, w\u00e4hrend wir gleichzeitig resistent gegen Resharding sind. Und es gibt eine solche L\u00f6sung, die nicht allzu kompliziert ist. Sie hei\u00dft konsistentes Hashing.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1380758686274df9755a7ebf7d1c8753.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWie sieht das aus?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/44f97abfac46fa9f361055548819e8a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir nehmen irgendeine Funktion vom Sharding-Schl\u00fcssel und verteilen alle ihre Werte gleichm\u00e4\u00dfig auf einem Kreis. Das hei\u00dft, an Punkt 0 treffen sich die minimalen und maximalen Werte. Dann platzieren wir auf demselben Kreis all unsere Server ungef\u00e4hr wie folgt:<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d470ec615a789913a6baa2726b05acea.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJeder Server wird durch einen Punkt definiert, und der Sektor, der im Uhrzeigersinn bis zu ihm geht, wird entsprechend von diesem Host bedient. Wenn wir Anfragen erhalten, sehen wir sofort, dass beispielsweise Anfrage A \u2013 ihr Hash sieht so aus \u2013 und sie wird von Server 2 bedient. Anfrage B \u2013 von Server 3. Und so weiter.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fcdbd1caa9f1162cf02e8b0a1c79cb74.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWas passiert in dieser Situation beim Resharding?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7386cda826e9419d5f8a9a0d6d6703c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir invalidieren nicht den gesamten Cache, wie fr\u00fcher, und verschieben nicht alle Schl\u00fcssel, sondern verschieben jeden Sektor um eine kleine Distanz, sodass in den freigewordenen Platz, um es so zu sagen, unser sechster Server, den wir hinzuf\u00fcgen m\u00f6chten, passt und wir ihn dort hinzuf\u00fcgen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8680e0cf023ce911b4d162e9102c0545.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn einer solchen Situation geraten die Schl\u00fcssel tats\u00e4chlich ins Wanken. Aber sie wackeln deutlich weniger als fr\u00fcher. Und wir sehen, dass unsere beiden ersten Schl\u00fcssel auf ihren Servern geblieben sind, w\u00e4hrend sich der caching-Server nur f\u00fcr den letzten Schl\u00fcssel ge\u00e4ndert hat. Das funktioniert ziemlich effektiv, und wenn Sie schrittweise neue Hosts hinzuf\u00fcgen, gibt es hier kein gro\u00dfes Problem. Sie f\u00fcgen nach und nach hinzu, warten, bis der Cache wieder gef\u00fcllt ist, und alles funktioniert gut.<\/p>\n<p>Die einzige Frage bleibt bei Ausf\u00e4llen. Angenommen, wir haben einen Ausfall eines bestimmten Ger\u00e4ts.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8e3301af782ce8983716c4bc9add79a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd in diesem Moment m\u00f6chten wir eigentlich nicht diese Karte neu generieren, einen Teil des Caches ung\u00fcltig machen und so weiter, falls beispielsweise die Maschine neu gestartet werden musste, wir aber irgendwie die Anfragen bedienen m\u00fcssen. Wir halten einfach an jedem Standort einen Reserve-Foto-Cache bereit, der als Ersatz f\u00fcr jedes Ger\u00e4t dient, das derzeit ausgefallen ist. Wenn pl\u00f6tzlich ein Server nicht mehr verf\u00fcgbar ist, geht der Verkehr dorthin. In diesem Fall haben wir nat\u00fcrlich keinen Cache, d.h. er ist kalt, aber zumindest werden die Nutzeranfragen bearbeitet. Wenn es sich um einen kurzen Zeitraum handelt, \u00fcberstehen wir das ganz problemlos. Es lastet einfach mehr auf dem Speicher. Wenn der Zeitraum l\u00e4nger ist, k\u00f6nnen wir bereits entscheiden \u2014 ob wir diesen Server von der Karte entfernen oder nicht, oder vielleicht durch einen anderen ersetzen.<\/p>\n<p>Das ist zur Cache-System. Lassen Sie uns die Ergebnisse betrachten.<\/p>\n<p>Es scheint eigentlich nichts Kompliziertes dabei zu sein. Aber diese Art der Cache-Verwaltung hat uns eine Trefferquote von etwa 98 % eingebracht. D.h. von diesen 80.000 Anfragen pro Sekunde erreichen nur 1.600 die Speichersysteme, und das ist eine v\u00f6llig normale Last, die sie problemlos bew\u00e4ltigen k\u00f6nnen, wir haben immer einen Puffer.<\/p>\n<p>Wir haben diese Server in unseren drei Rechenzentren platziert und damit drei Standorte erhalten \u2014 Prag, Miami und Hongkong.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/64eef492b65a014d8ba3c808b6579b41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSomit sind sie mehr oder weniger lokal zu jedem unserer Zielm\u00e4rkte positioniert.<\/p>\n<p>Und als angenehmer Bonus haben wir diesen caching-Proxy erhalten, auf dem die CPU eigentlich ungenutzt ist, weil sie f\u00fcr die Bereitstellung von Inhalten nicht so stark ben\u00f6tigt wird. Und dort haben wir mit NGINX+ Lua sehr viel n\u00fctzliche Logik umgesetzt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b65c609df5e1985240d04ee65a3e4f55.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZum Beispiel k\u00f6nnen wir mit webp oder progressiven jpeg experimentieren (das sind moderne, effiziente Formate), sehen, wie sich das auf den Traffic auswirkt, Entscheidungen treffen, es f\u00fcr bestimmte L\u00e4nder aktivieren usw.; dynamisches Resize oder Cropping von Fotos in Echtzeit durchf\u00fchren.<\/p>\n<p>Das ist ein guter Use Case, wenn Sie zum Beispiel eine mobile Anwendung haben, die Fotos anzeigt, und die mobile Anwendung CPU-Leistung des Ger\u00e4ts nicht aufwenden m\u00f6chte, um ein gro\u00dfes Foto anzufordern und es dann auf eine bestimmte Gr\u00f6\u00dfe zu bringen, um es in das View zu bringen. Wir k\u00f6nnen einfach dynamisch in der URL irgendwelche Parameter im UPort festlegen, und der Fotocache resized das Foto automatisch. In der Regel w\u00e4hlt er die Gr\u00f6\u00dfe aus, die wir physisch auf der Festplatte haben und die der angeforderten am n\u00e4chsten kommt, und er skaliert sie dann in den entsprechenden Koordinaten herunter.<\/p>\n<blockquote><p>\u00dcbrigens haben wir die Videoaufzeichnungen der letzten f\u00fcnf Jahre der Konferenz f\u00fcr Entwickler hochbelasteter Systeme ver\u00f6ffentlicht. <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex>. Schauen Sie sich um, lernen Sie, teilen Sie und abonnieren Sie unseren <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/profyclub\">YouTube-Kanal.<\/a><\/noindex>.<\/p><\/blockquote>\n<p>\nWir k\u00f6nnen auch viele Produktlogik hinzuf\u00fcgen. Zum Beispiel k\u00f6nnen wir je nach URL-Parametern verschiedene Wasserzeichen hinzuf\u00fcgen, Fotos verwischen, vernebeln oder pixeln. Das ist n\u00fctzlich, wenn wir ein Foto einer Person zeigen wollen, aber deren Gesicht nicht zeigen m\u00f6chten, das funktioniert gut, und das ist hier alles implementiert.<\/p>\n<p>Was haben wir erreicht? Wir haben drei Pr\u00e4senzpunkte, eine gute Hitquote und dabei bleibt die CPU auf diesen Maschinen nicht ungenutzt. Sie ist jetzt nat\u00fcrlich wichtiger als fr\u00fcher. Wir m\u00fcssen leistungsst\u00e4rkere Maschinen installieren, aber das ist es wert.<\/p>\n<p>Das betrifft die Bereitstellung von Fotos. Hier ist alles ziemlich klar und offensichtlich. Ich denke nicht, dass ich hier eine neue Erkenntnis pr\u00e4sentiere, so funktioniert praktisch jedes CDN.<\/p>\n<p>Und wahrscheinlich k\u00f6nnte ein erfahrener Zuh\u00f6rer sich die Frage stellen: Warum nicht einfach alles auf ein CDN umstellen? Das w\u00e4re ungef\u00e4hr das Gleiche, alle modernen CDNs k\u00f6nnen das. Es gibt allerdings mehrere Gr\u00fcnde daf\u00fcr.<\/p>\n<p>Der erste Grund sind die Fotos.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/592c10eb74d46191bfcedec120f68556.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist einer der wichtigsten Punkte unserer Infrastruktur, und wir m\u00fcssen so viel Kontrolle \u00fcber sie wie m\u00f6glich haben. Wenn es sich um eine L\u00f6sung eines Drittanbieters handelt und Sie in keiner Weise die Kontrolle dar\u00fcber haben, wird es f\u00fcr Sie ziemlich schwierig, damit umzugehen, wenn Sie einen gro\u00dfen Datensatz haben und einen sehr hohen Anfrageaufkommen von Nutzern.<\/p>\n<p>Ich gebe ein Beispiel. Momentan k\u00f6nnen wir in unserer Infrastruktur, im Falle von Problemen oder unterirdischen Ger\u00e4uschen, auf die Maschine zugreifen und uns dort debugging-technisch bet\u00e4tigen, sozusagen. Wir k\u00f6nnen Metriken sammeln, die nur f\u00fcr uns wichtig sind, wir k\u00f6nnen experimentieren und sehen, wie sich das auf die Grafiken auswirkt und so weiter. Momentan wird sehr viel Statistik \u00fcber diesen caching Cluster gesammelt. Und wir beobachten sie regelm\u00e4\u00dfig und untersuchen lange Zeit bestimmte Anomalien. Wenn das auf der CD-Seite w\u00e4re, w\u00e4re es viel schwieriger zu kontrollieren. Oder, wenn ein Unfall passiert, wissen wir, was passiert ist, wir wissen, wie wir damit umgehen und wie wir es bek\u00e4mpfen k\u00f6nnen. Das ist die erste Schlussfolgerung.<\/p>\n<p>Die zweite Schlussfolgerung ist auch eher historisch, da das System sich schon lange entwickelt und viele verschiedene Gesch\u00e4ftsanforderungen in verschiedenen Phasen bestanden haben, die nicht immer in das Konzept eines CDNs passen.<\/p>\n<p>Und der Punkt, der sich aus dem vorherigen ergibt \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/007cf3aed2f9cc12185fc3865bf9d196.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist, dass wir bei den Foto-Caches viel spezifische Logik haben, die nicht immer auf Anfrage hinzugef\u00fcgt werden kann. Es ist unwahrscheinlich, dass irgendein CDN auf Ihre Anfrage hin ma\u00dfgeschneiderte Dinge f\u00fcr Sie hinzuf\u00fcgt. Zum Beispiel die Verschl\u00fcsselung von URLs, wenn Sie nicht m\u00f6chten, dass der Kunde etwas \u00e4ndern kann. Sie m\u00f6chten die URL auf dem Server \u00e4ndern und sie verschl\u00fcsseln, und dann hier einige dynamische Parameter \u00fcbergeben.<\/p>\n<p>Welche Schlussfolgerung dr\u00e4ngt sich auf? In unserem Fall ist CDN keine sehr gute Alternative.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/cfc2963cca2357cf6b0f63419a4dc436.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn Ihrem Fall, wenn Sie spezielle Gesch\u00e4ftsanforderungen haben, k\u00f6nnen Sie v\u00f6llig entspannt das implementieren, was ich Ihnen gezeigt habe. Und das wird bei einem \u00e4hnlichen Lastprofil hervorragend funktionieren.<\/p>\n<p>Aber wenn Sie eine allgemeine L\u00f6sung haben und die Aufgabe nicht sehr speziell ist, k\u00f6nnen Sie problemlos ein CDN nutzen. Oder wenn f\u00fcr Sie die Zeit und die Ressourcen wichtiger sind als die Kontrolle.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b76d25404918a5d0d8bf1d6644c8d873.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nModerne CDNs bieten praktisch alles, was ich Ihnen gerade erz\u00e4hlt habe. Mit Ausnahme von ein paar speziellen Funktionen.<\/p>\n<p>Das betrifft die Auslieferung von Bildern.<\/p>\n<p>Lassen Sie uns jetzt ein wenig in unserer R\u00fcckschau voranschreiten und \u00fcber die Speicherung sprechen.<\/p>\n<p>Das Jahr 2013 war.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f218bfc899512041967842430c02aa9b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie Cache-Server wurden hinzugef\u00fcgt, die Performance-Probleme sind verschwunden. Alles ist gut. Der Datensatz w\u00e4chst. Im Jahr 2013 hatten wir etwa 80 Server, die mit Storages verbunden sind, und etwa 40 Cache-Server in jedem Rechenzentrum. Das sind 560 Terabyte Daten in jedem Rechenzentrum, also insgesamt etwa ein Petabyte.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef741ba4a9164e6940f55e93dfb46ef0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMit dem Wachstum des Datensatzes sind auch die Betriebskosten erheblich gestiegen. Inwieweit \u00e4u\u00dferte sich das?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6cf5e489a4e97bc6e26fc6d4d16505b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn diesem Schema, das gezeichnet ist \u2013 mit SAN, den angeschlossenen Maschinen und Caches \u2013 gibt es viele Fehlerpunkte. W\u00e4hrend wir mit dem Ausfall der Cache-Server, den wir bereits bew\u00e4ltigt haben, recht gut klargekommen sind, war es auf der Seite des Storages viel schlimmer.<\/p>\n<p>Zun\u00e4chst einmal kann selbst das Storage Area Network (SAN) ausfallen.<\/p>\n<p>Au\u00dferdem ist es \u00fcber Glasfaser mit den Endmaschinen verbunden. Es kann Probleme mit den optischen Karten oder Switches geben.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6959b79284c5b1244a70a1d64f191893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDiese sind zwar nicht so zahlreich wie beim SAN selbst, aber dennoch sind sie auch Punkte, an denen Ausf\u00e4lle auftreten k\u00f6nnen.<\/p>\n<p>Dar\u00fcber hinaus die Maschine selbst, die mit dem Storage verbunden ist. Sie kann ebenfalls ausfallen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1801cb502663a4de14329a5e67dfed79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nInsgesamt haben wir also drei Fehlerpunkte.<\/p>\n<p>Zus\u00e4tzlich zu den Fehlerpunkten ist der Wartungsaufwand der Storages hoch.<\/p>\n<p>Es handelt sich um ein komplexes, mehrkomponentiges System, und es kann f\u00fcr Systemtechniker schwierig sein, damit umzugehen.<\/p>\n<p>Und der letzte, der wichtigste Punkt. Wenn an einem dieser drei Punkte ein Ausfall auftritt, haben wir eine nicht zu vernachl\u00e4ssigende Wahrscheinlichkeit, dass Benutzerdaten verloren gehen, da das Dateisystem besch\u00e4digt werden kann.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4bf8bc1c73a2beef74cb4ee0ee45679b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAngenommen, unser Dateisystem ist besch\u00e4digt. Die Wiederherstellung dauert erstens lange \u2013 das kann bei einer gro\u00dfen Datenmenge eine Woche in Anspruch nehmen. Und zweitens erhalten wir wahrscheinlich eine Menge unverst\u00e4ndlicher Dateien, die wir irgendwie mit den Fotos der Benutzer abgleichen m\u00fcssen. Und wir riskieren, Daten zu verlieren. Das Risiko ist ziemlich hoch. Je h\u00e4ufiger solche Situationen auftreten und je mehr Probleme in dieser gesamten Kette entstehen, desto h\u00f6her ist dieses Risiko.<\/p>\n<p>Damit mussten wir etwas unternehmen. Und wir haben beschlossen, einfach die Daten zu sichern. Das ist tats\u00e4chlich eine naheliegende und gute L\u00f6sung. Was haben wir gemacht?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f80ec2b65003c40bd2fabf88966b3e05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo sah unser Server aus, der fr\u00fcher mit dem Storage verbunden war. Das ist eine Hauptpartition, ein einfaches Blockger\u00e4t, das tats\u00e4chlich ein Mount auf den entfernten Storage \u00fcber Glasfaser darstellt.<\/p>\n<p>Wir haben einfach eine zweite Partition hinzugef\u00fcgt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d3dba75ef477269d92145cd69d587527.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben einen zweiten Storage daneben installiert (zum Gl\u00fcck ist das finanziell nicht so teuer) und ihn Backup-Bereich genannt. Er ist ebenfalls \u00fcber Glasfaser verbunden und befindet sich auf demselben Server. Aber wir m\u00fcssen die Daten irgendwie zwischen ihnen synchronisieren.<\/p>\n<p>Hier richten wir einfach eine asynchrone Warteschlange daneben ein.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/67bced2b45c589009cfb01a1c21398a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSie ist nicht sehr stark ausgelastet. Wir wissen, dass wir wenig Eintr\u00e4ge haben. Die Warteschlange ist einfach eine Tabelle in MySQL, in die Zeilen eingef\u00fcgt werden wie \"Wir m\u00fcssen dieses Foto sichern\". Bei jeder \u00c4nderung oder beim Upload kopieren wir asynchron oder einfach mit einem Background Worker vom Hauptbereich auf das Backup.<\/p>\n<p>So haben wir immer zwei konsistente Bereiche. Selbst wenn ein Teil dieses Systems ausf\u00e4llt, k\u00f6nnen wir den Hauptbereich mit dem Backup austauschen und alles funktioniert weiter.<\/p>\n<p>Aber dadurch steigt die Leselast stark, da neben den Clients, die vom Hauptbereich lesen, weil sie sich die Fotos dort zuerst ansehen (sie sind dort frischer), und dann auf dem Backup suchen, falls sie nichts finden (aber das erledigt einfach NGINX), auch unser Backup-System nun vom Hauptbereich liest. Es ist nicht so, dass das der Engpass w\u00e4re, aber ich wollte die Last nicht einfach so erh\u00f6hen.<\/p>\n<p>Und wir haben eine dritte Festplatte hinzugef\u00fcgt, die ein kleiner SSD ist und als Puffer bezeichnet wird.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd35481822b4170087e5f670bf338dc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWie funktioniert das jetzt?<\/p>\n<p>Der Benutzer l\u00e4dt ein Foto auf den Puffer hoch, woraufhin ein Ereignis in die Warteschlange geworfen wird, dass es auf zwei Bereiche kopiert werden muss. Es wird kopiert, und das Foto bleibt eine Zeit lang (sagen wir, einen Tag) im Puffer, bevor es gel\u00f6scht wird. Das verbessert die Benutzererfahrung erheblich, denn der Benutzer l\u00e4dt das Foto normalerweise hoch und erh\u00e4lt sofort Anfragen, oder er aktualisiert die Seite, refresht. Aber das h\u00e4ngt alles von der Anwendung ab, die den Upload durchf\u00fchrt.<\/p>\n<p>Oder zum Beispiel senden andere Menschen, die es sehen, direkt nach diesem Foto Anfragen. Im Cache ist es noch nicht, die erste Anfrage erfolgt sehr schnell. Im Grunde genommen ist es dasselbe wie beim Foto-Cache. Der langsame Storage ist daran \u00fcberhaupt nicht beteiligt. Wenn es nach einem Tag gel\u00f6scht wird, ist es entweder bereits in unserer Caching-Schicht zwischengespeichert oder es wird wahrscheinlich niemand mehr ben\u00f6tigt. Das hei\u00dft, die Benutzererfahrung hat dank solcher einfachen Manipulationen enorm zugenommen.<\/p>\n<p>Und das Wichtigste: Wir haben aufgeh\u00f6rt, Daten zu verlieren.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/526f549457dd0c438f32b0adb76df76c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben sozusagen aufgeh\u00f6rt. <em>potenziell<\/em> Daten zu verlieren, weil wir sie eigentlich nicht wirklich verloren haben. Aber die Gefahr war da. Wir sehen, dass diese L\u00f6sung nat\u00fcrlich gut ist, aber sie \u00e4hnelt ein wenig dem Gl\u00e4tten der Symptome des Problems, anstatt es vollst\u00e4ndig zu l\u00f6sen. Und einige Probleme sind hier geblieben.<\/p>\n<p>Erstens ist das ein Ausfallpunkt, n\u00e4mlich der physikalische Host, auf dem all diese Maschine l\u00e4uft; dieser ist nicht verschwunden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0eb3d292655a7edf912793ed81e8931c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZweitens bleiben Probleme mit den SANs, ihre schwierige Wartung usw. Es war nicht unbedingt ein kritischer Faktor, aber wir wollten versuchen, wie es w\u00e4re, ohne sie zu leben.<\/p>\n<p>Wir haben die dritte Version (im Grunde genommen die zweite) \u2013 die Version der Reservierung gemacht. Wie sah das aus?<\/p>\n<p>Das war, was war \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8b1749b6feed200f8a64529ee2316c1a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnsere Hauptprobleme liegen darin, dass es sich um einen physikalischen Host handelt.<\/p>\n<p>Erstens entfernen wir die SANs, weil wir experimentieren und einfach nur lokale Festplatten ausprobieren wollen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd0f5a8627d9179fcbc7097c1c18505f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs war bereits 2014-2015, und zu diesem Zeitpunkt hat sich die Situation mit Festplatten und deren Kapazit\u00e4t in einem Host erheblich verbessert. Wir dachten, warum nicht ausprobieren.<\/p>\n<p>Anschlie\u00dfend nehmen wir einfach unsere Backup-Partition und \u00fcbertragen sie physisch auf eine separate Maschine.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/456e00bc8557d3340b06efcd1dde8a08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo ergeben sich folgende Struktur. Wir haben zwei Maschinen, die identische Datens\u00e4tze speichern. Sie sichern sich gegenseitig vollst\u00e4ndig und synchronisieren die Daten \u00fcber das Netzwerk mithilfe einer asynchronen Warteschlange im selben MySQL.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d44cdb7b440ad4c58cc625123306a8c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWarum das gut funktioniert \u2013 weil wir wenige Schreibvorg\u00e4nge haben. Das hei\u00dft, wenn die Schreibvorg\u00e4nge mit den Lesevorg\u00e4ngen vergleichbar w\u00e4ren, w\u00fcrden wir m\u00f6glicherweise einen gewissen Netzwerk-Overhead und Probleme haben. Wenige Schreibvorg\u00e4nge, viele Lesevorg\u00e4nge \u2013 diese Methode funktioniert gut, das hei\u00dft, wir kopieren ziemlich selten Fotos zwischen diesen beiden Servern.<\/p>\n<p>Wie das funktioniert, wenn man etwas detaillierter hinschaut.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/071c11abb6ee1d7734c53052139ff04b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUpload. Der Load-Balancer w\u00e4hlt einfach zuf\u00e4llig Hosts aus und f\u00fchrt den Upload auf ihm durch. Dabei f\u00fchrt er nat\u00fcrlich Gesundheitschecks durch und sorgt daf\u00fcr, dass die Maschine nicht ausf\u00e4llt. Das hei\u00dft, er l\u00e4dt Fotos nur auf einen aktiven Server hoch, und anschlie\u00dfend wird alles \u00fcber die asynchrone Warteschlange auf seinen Nachbarn kopiert. Mit dem Upload ist alles ganz einfach.<\/p>\n<p>Mit der Aufgabe ist es ein bisschen komplizierter.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f494904aec823456e18b987a8c98bf56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHier hat uns Lua geholfen, weil es mit Vanilla NGINX schwierig ist, eine solche Logik umzusetzen. Zun\u00e4chst machen wir eine Anfrage an den ersten Server und pr\u00fcfen, ob das Foto dort vorhanden ist, da es m\u00f6glicherweise zum Nachbarn hochgeladen wurde und hier noch nicht angekommen ist. Wenn das Foto vorhanden ist, ist das gut. Wir geben es sofort an den Kunden weiter und speichern es m\u00f6glicherweise im Cache.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/de5f77e997bb049f4cfc1709da0f1788.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWenn es nicht vorhanden ist, stellen wir einfach eine Anfrage an den Nachbarn und erhalten es garantiert von dort.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/79aa5592acd28dfbc815261d0276c2e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo kann man wieder sagen: Es k\u00f6nnen Performance-Probleme auftreten, da st\u00e4ndige Round Trips \u2013 das Foto wurde hochgeladen, hier ist es nicht, wir machen zwei Anfragen statt einer \u2013 langsam funktionieren sollten.<\/p>\n<p>In unserer Situation funktioniert es jedoch nicht langsam.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/52ca3902d80990f512201672cd5e6441.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir sammeln viele Metriken zu diesem System, und die bedingte Trefferquote dieses Mechanismus liegt bei etwa 95 %. Das hei\u00dft, die Verz\u00f6gerung dieses Backups ist gering, und dadurch k\u00f6nnen wir praktisch garantiert, nachdem das Foto hochgeladen wurde, es beim ersten Mal abholen und m\u00fcssen nirgends zweimal hin.<\/p>\n<p>Was haben wir also noch erhalten, und was ist sehr cool?<\/p>\n<p>Fr\u00fcher hatten wir einen Haupt-Backup-Bereich, und wir haben sequenziell von dort gelesen. Das hei\u00dft, wir haben immer zuerst auf dem Haupt-Backup gesucht und dann auf dem Backup. Das war ein Durchlauf.<\/p>\n<p>Jetzt nutzen wir das Lesen von zwei Maschinen gleichzeitig. Wir verteilen die Anfragen round robin. In einem kleinen Prozentsatz der F\u00e4lle machen wir zwei Anfragen. Aber insgesamt haben wir jetzt eine doppelt so gro\u00dfe Lesekapazit\u00e4t wie fr\u00fcher. Und die Last hat sich sowohl auf den abgebenden Maschinen als auch auf den Speichermedien, die wir damals auch hatten, deutlich reduziert.<\/p>\n<p>Was die Ausfallsicherheit betrifft. Daf\u00fcr haben wir haupts\u00e4chlich gek\u00e4mpft. Bei der Ausfallsicherheit lief hier alles gro\u00dfartig.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a030a477e60d6e1f3d0b4e3395013df5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEine Maschine f\u00e4llt aus.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/42900b24e340c03ea642fd49f5b410ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKein Problem! Der Systemingenieur kann sogar nachts schlafen, er wartet bis zum Morgen, es wird nichts Schlimmes passieren.<\/p>\n<p>Selbst wenn bei einem Ausfall dieser Maschine die Warteschlange ausgefallen ist, gibt es auch keine Probleme; einfach wird das Protokoll zuerst auf der funktionierenden Maschine gesammelt und dann geht es in die Warteschlange, und anschlie\u00dfend auf die Maschine, die nach einer gewissen Zeit wieder in Betrieb genommen wird.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef42eadaaf3e3ecbf70847e9f88c1582.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas Gleiche gilt f\u00fcr das Maintenance. Wir schalten einfach eine der Maschinen aus, ziehen sie manuell aus allen Pools, ihr Traffic stoppt, wir f\u00fchren ein gewisses Maintenance durch, \u00e4ndern etwas, und danach bringen wir sie wieder in den Betrieb. Dieses Backup holt schnell auf. Das hei\u00dft, ein Ausfall von einem Tag wird innerhalb von wenigen Minuten aufgeholt. Das ist wirklich sehr wenig. Mit der Ausfallsicherheit, muss ich sagen, ist hier alles gro\u00dfartig.<\/p>\n<p>Welche Schlussfolgerungen k\u00f6nnen wir aus diesem Schema der Redundanz ziehen?<\/p>\n<p>Wir haben Ausfallsicherheit erreicht.<\/p>\n<p>Einfache Bedienung. Da die Maschinen lokale Festplatten haben, ist das aus Sicht der Ingenieure, die damit arbeiten, viel bequemer.<\/p>\n<p>Wir haben einen doppelten Puffer beim Lesen erhalten.<\/p>\n<p>Das ist ein sehr guter Bonus zur Ausfallsicherheit.<\/p>\n<p>Aber es gibt auch Probleme. Jetzt ist die Entwicklung gewisser Funktionen damit viel komplexer, weil das System zu 100 % eventually consistent geworden ist.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b650276a41730cc303180e8304c5dabb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir m\u00fcssen zum Beispiel in einem Hintergrundjob st\u00e4ndig \u00fcberlegen: \u201eAuf welchem Server sind wir gerade aktiv?\u201c, \u201eGibt es hier wirklich ein aktuelles Bild?\u201c usw. Das ist nat\u00fcrlich alles in Wrappern eingekapselt, und f\u00fcr den Programmierer, der die Gesch\u00e4ftslogik schreibt, ist es transparent. Dennoch ist dies eine gro\u00dfe komplexe Schicht entstanden. Aber wir sind bereit, damit zu leben, im Austausch gegen die Vorteile, die wir dadurch erhalten haben.<\/p>\n<p>Und hier entsteht wieder ein gewisser Konflikt.<\/p>\n<p>Ich habe zu Beginn gesagt, dass es schlecht ist, alles auf lokalen Festplatten zu speichern. Und jetzt sage ich, dass es uns gefallen hat.<\/p>\n<p>Ja, tats\u00e4chlich hat sich die Situation im Laufe der Zeit stark ver\u00e4ndert, und dieser Ansatz hat nun viele Vorteile. Erstens erhalten wir eine viel einfachere Bedienung.<\/p>\n<p>Zweitens ist es effizienter, da wir diese automatischen Controller und Verbindungen zu den Disk-Arrays nicht haben.<\/p>\n<p>Dort gibt es eine riesige Maschinenlandschaft, hier handelt es sich nur um einige Platten, die konkret hier im RAID auf der Maschine zusammengeschaltet sind.<\/p>\n<p>Aber es gibt auch Nachteile.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3c090e0801f1a686dc0d5fefce697c56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs ist ungef\u00e4hr 1,5-mal teurer als die Nutzung von SANs, selbst zu den heutigen Preisen. Deshalb haben wir uns entschieden, nicht so k\u00fchn zu sein und unser ganzes gro\u00dfes Cluster in Maschinen mit lokalen Festplatten zu konvertieren und haben uns f\u00fcr eine hybride L\u00f6sung entschieden.<\/p>\n<p>Die H\u00e4lfte unserer Maschinen arbeitet mit Festplatten (naja, nicht die H\u00e4lfte \u2013 vielleicht 30 Prozent). Der Rest sind alte Ger\u00e4te, auf denen fr\u00fcher das erste Backup-System lief. Wir haben sie einfach umkonfiguriert, da wir weder neue Daten noch etwas anderes brauchen, sondern einfach die Mounts von einem physischen Host auf zwei umgestellt haben.<\/p>\n<p>Wir haben nun einen gro\u00dfen Puffer beim Lesen, und wir haben uns vergr\u00f6\u00dfert. Fr\u00fcher haben wir jeweils einen Storage auf eine Maschine montiert, jetzt montieren wir auf ein Paar vier, zum Beispiel. Und das funktioniert gut.<\/p>\n<p>Lassen Sie uns eine kurze Zusammenfassung dessen geben, was wir erreicht haben, worum wir gek\u00e4mpft haben und ob es geklappt hat.<\/p>\n<h3>Ergebnisse<\/h3>\n<p>\nWir haben 33 Millionen Benutzer.<\/p>\n<p>Wir haben drei Standorte \u2013 Prag, Miami, Hongkong.<\/p>\n<p>Dort haben wir eine Cache-Schicht, die aus Maschinen mit schnellen lokalen Festplatten (SSD) besteht, auf denen eine einfache Maschine aus NGINX, dessen access.log und Daemonen in Python arbeitet, die alles verarbeiten und den Cache verwalten.<\/p>\n<p>Wenn Sie in Ihrem Projekt m\u00f6chten, dass Fotos nicht so kritisch sind wie f\u00fcr uns, oder wenn der Trade-off zwischen Kontrolle und Entwicklungs- sowie Ressourcenkosten auf Ihrer Seite eher zu Gunsten der Geschwindigkeit geht, k\u00f6nnen Sie es problemlos durch ein CDN ersetzen; moderne CDNs machen das gut.<\/p>\n<p>Dann kommt die Speicherschicht, auf der Cluster von Maschinenp\u00e4rchen angeordnet sind, die sich gegenseitig sichern, wobei Dateien bei \u00c4nderungen asynchron von einer auf die andere kopiert werden.<\/p>\n<p>Einige dieser Maschinen arbeiten mit lokalen Festplatten.<\/p>\n<p>Einige dieser Maschinen sind mit SANs verbunden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5ddbc4f73d86aa1f83734885d8c9dea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd auf der einen Seite ist es in der Bedienung bequemer und etwas leistungsf\u00e4higer, auf der anderen Seite ist es aus Sicht der Dichte und der Kosten pro Gigabyte praktisch.<\/p>\n<p>Das ist eine kurze \u00dcbersicht \u00fcber die Architektur dessen, was wir erhalten haben und wie es sich entwickelt hat.<\/p>\n<p>Noch ein paar ganz einfache Tipps vom Chef.<\/p>\n<p>Erstens, wenn Sie pl\u00f6tzlich entscheiden, dass Sie dringend alles in Ihrer Foto-Infrastruktur verbessern m\u00fcssen, messen Sie zuerst, denn m\u00f6glicherweise gibt es nichts zu verbessern.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7770f41d0b190eb78ae0d19f4c8182a6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIch gebe ein Beispiel. Wir haben einen Cluster von Maschinen, der Fotos aus Anh\u00e4ngen in Chats bereitstellt, und dort l\u00e4uft immer noch das System aus dem Jahr 2009, und niemand leidet darunter. Alle sind zufrieden, alle finden es gut.<\/p>\n<p>Um zu messen, h\u00e4ngen Sie zun\u00e4chst eine Reihe von Metriken auf, schauen Sie sich diese an und entscheiden Sie dann, was Ihnen nicht gef\u00e4llt und was verbessert werden muss. Um das zu messen, haben wir ein gro\u00dfartiges Tool namens Pinba.<\/p>\n<p>Es erm\u00f6glicht, sehr detaillierte Statistiken von NGINX f\u00fcr jede Anfrage, die Antwortcodes und Zeitverteilungen zu sammeln \u2013 alles, was man will. Es gibt Bindings f\u00fcr verschiedene Analysesysteme, sodass Sie alles sch\u00f6n anzeigen k\u00f6nnen.<\/p>\n<p>Zuerst gemessen \u2013 dann verbessert.<\/p>\n<p>Weiter. Wir optimieren das Lesen mit Caching, das Schreiben \u2013 mit Sharding, aber das ist offensichtlich.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f53a4777f1a2c7793eba4a72c94263a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWeiter. Wenn Sie gerade erst anfangen, Ihr System aufzubauen, ist es viel besser, Bilder als unver\u00e4nderliche Dateien zu speichern. Auf diese Weise vermeiden Sie gleich einen ganzen Klassensatz an Problemen mit Cache-Invalidierung und der Frage, wie die Logik die richtige Version des Bildes finden soll.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f345c59681275326cda1320b4f188ce9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAngenommen, Sie haben ein Hundert hochgeladen, dann haben Sie es gedreht, sorgen Sie daf\u00fcr, dass es eine physisch andere Datei ist. Das hei\u00dft, Sie m\u00fcssen nicht denken: Jetzt spare ich ein bisschen Platz, ich speichere in derselben Datei, \u00e4ndere die Version. Das funktioniert immer schlecht und f\u00fchrt sp\u00e4ter zu vielen Kopfschmerzen.<\/p>\n<p>N\u00e4chster Punkt. \u00dcber das Resize in Echtzeit.<\/p>\n<p>Fr\u00fcher, als Benutzer ein Foto hochluden, haben wir sofort eine ganze Menge Gr\u00f6\u00dfen f\u00fcr alle Lebenslagen f\u00fcr verschiedene Clients erstellt, und alle lagen auf der Festplatte. Jetzt haben wir das eingestellt.<\/p>\n<p>Wir haben nur drei Hauptgr\u00f6\u00dfen behalten: klein, mittel und gro\u00df. Alles andere skalieren wir einfach von der Gr\u00f6\u00dfe, die hinter der angeforderten Gr\u00f6\u00dfe steht, in Uport herab, einfach Downsizing und dem Benutzer geben.<\/p>\n<p>Der CPU-Caching-Schicht ist hier viel g\u00fcnstiger, als wenn wir diese Gr\u00f6\u00dfen auf jedem Storage st\u00e4ndig neu generieren w\u00fcrden. Angenommen, wir m\u00f6chten eine neue hinzuf\u00fcgen, es dauert einen Monat \u2013 ein Skript \u00fcberall laufen zu lassen, das alles ordentlich macht, ohne den Cluster zu \u00fcberlasten. Das hei\u00dft, wenn es jetzt die M\u00f6glichkeit gibt, sollte man m\u00f6glichst wenige physische Gr\u00f6\u00dfen erstellen, aber um eine gewisse Verteilung zu haben, sagen wir drei. Und alles andere einfach in Echtzeit mithilfe fertiger Module skalieren. Das ist jetzt alles sehr einfach und zug\u00e4nglich.<\/p>\n<p>Und inkrementelles, asynchrones Backup ist gut.<\/p>\n<p>Wie unsere Praxis gezeigt hat, funktioniert ein solches Schema sehr gut mit der verz\u00f6gerten Kopie ge\u00e4nderter Dateien.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur der Speicherung und Ausgabe von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0e550721e838654e61e1fa4d08f9bb93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDer letzte Punkt ist ebenfalls offensichtlich. Wenn es in Ihrer Infrastruktur derzeit keine solchen Probleme gibt, aber etwas vorhanden ist, das ausfallen k\u00f6nnte, wird es definitiv dann ausfallen, wenn es etwas mehr wird. Daher ist es besser, sich im Voraus Gedanken dar\u00fcber zu machen und dabei keine Probleme zu haben. Ich habe alles.<\/p>\n<h3>Kontakte<\/h3>\n<p>\n\u00bb <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/users\/bo0rsh201\/\" class=\"user_link\">bo0rsh201<\/a><\/noindex> <br \/>\n\u00bb <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/company\/badoo\/\">Blog des Unternehmens Badoo<\/a><\/noindex><\/p>\n<blockquote><p>Dieser Vortrag ist eine Transkription eines der besten Vortr\u00e4ge auf der Konferenz f\u00fcr Entwickler hochbelasteter Systeme. <noindex><a rel=\"nofollow\" href=\"http:\/\/highload.ru\/?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">HighLoad++<\/a><\/noindex>. Bis zur Konferenz HighLoad++ 2017 sind es weniger als einen Monat.<\/p>\n<p>Wir sind bereits bereit, <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\">Konferenzprogramm<\/a><\/noindex>das Programm wird gerade aktiv erstellt.<\/p>\n<p>In diesem Jahr setzen wir unsere Erkundung des Themas Architekturen und Skalierung fort:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\/2946.html?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">Wie man eine Milliarde Benutzer bedient und Terabit-Traffic abgibt<\/a><\/noindex> \/ \u0418\u0433\u043e\u0440\u044c \u0412\u0430\u0441\u0438\u043b\u044c\u0435\u0432<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\/3088.html?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">Wie man die Datenbank f\u00fcr pers\u00f6nliche Nachrichten von \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 von Grund auf neu schreibt und ohne Ausfallzeit migriert<\/a><\/noindex> \/ \u0414\u043c\u0438\u0442\u0440\u0438\u0439 \u0415\u0433\u043e\u0440\u043e\u0432<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\/2843.html?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">Tod durch den Ausverkauf: wie Yandex.Money versuchte, sich auf den Black Friday vorzubereiten und durchzuhalten<\/a><\/noindex> \/ \u0410\u043d\u0430\u0442\u043e\u043b\u0438\u0439 \u041f\u043b\u0430\u0441\u043a\u043e\u0432\u0441\u043a\u0438\u0439<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\/3003.html?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">Fehlertolerante Architektur des Banksystems<\/a><\/noindex> \/ \u0420\u043e\u043c\u0430\u043d \u0428\u0435\u0445\u043e\u0432\u0446\u043e\u0432, \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u0413\u0440\u043e\u043c\u0430\u0442\u0447\u0438\u043a\u043e\u0432<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\/2948.html?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">Architektur des Zahlungssystems: fast Unternehmensniveau<\/a><\/noindex> \/ \u0424\u0438\u043b\u0438\u043f\u043f \u0414\u0435\u043b\u044c\u0433\u044f\u0434\u043e<\/li>\n<\/ul>\n<p>\nEinige dieser Materialien verwenden wir auch in unserem Online-Kurs zur Entwicklung hochbelasteter Systeme. <noindex><a rel=\"nofollow\" href=\"http:\/\/highload.guide\/?utm_source=habr&amp;utm_medium=media&amp;utm_campaign=past.articles&amp;utm_content=common\">HighLoad.Guide<\/a><\/noindex> ist eine Reihe von speziell ausgew\u00e4hlten E-Mails, Artikeln, Materialien und Videos. In unserem Lehrbuch befinden sich bereits \u00fcber 30 einzigartige Materialien. Machen Sie mit!\n<\/p><\/blockquote>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/oleg-bunin\/blog\/340976\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u0440\u0442\u0435\u043c \u0414\u0435\u043d\u0438\u0441\u043e\u0432 ( bo0rsh201, Badoo) Badoo \u2014 \u044d\u0442\u043e \u043a\u0440\u0443\u043f\u043d\u0435\u0439\u0448\u0438\u0439 \u0432 \u043c\u0438\u0440\u0435 \u0441\u0430\u0439\u0442 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 330 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043c\u0438\u0440\u0443. \u041d\u043e, \u0447\u0442\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0433\u043e \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u0430, \u2014 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u043e\u043a\u043e\u043b\u043e 3 \u043f\u0435\u0442\u0430\u0431\u0430\u0439\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439. \u041a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c \u043d\u0430\u0448\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0437\u0430\u043b\u0438\u0432\u0430\u044e\u0442 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 3,5 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-55009","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u0440\u0442\u0435\u043c \u0414\u0435\u043d\u0438\u0441\u043e\u0432 (\" \/>\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-hraneniya-i-otdachi-fotografij-v-badoo\" \/>\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 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0447\u0438 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 \u0432 Badoo | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u0440\u0442\u0435\u043c \u0414\u0435\u043d\u0438\u0441\u043e\u0432 (\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo\" \/>\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-01-09T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:03:04+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\udd47Architektur der Speicherung und Bereitstellung von Fotos in Badoo | ProHoster","description":"Artem Denisov (","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","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 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0447\u0438 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 \u0432 Badoo | ProHoster","og:description":"\u0410\u0440\u0442\u0435\u043c \u0414\u0435\u043d\u0438\u0441\u043e\u0432 (","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","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-01-09T21:00:00+00:00","article:modified_time":"2020-02-18T11:03:04+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55009","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":"2026-01-24 13:30:15","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:53:49","updated":"2026-01-24 13:30:15","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\/55009","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=55009"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/55009\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=55009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=55009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=55009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}