{"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 zur Speicherung und Auslieferung von Fotos in Badoo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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. Derzeit haben wir etwa 330 Millionen registrierte Nutzer weltweit. Aber was in unserem heutigen Gespr\u00e4ch viel wichtiger ist, ist, dass wir rund 3 Petabyte an Benutzerfotos speichern. T\u00e4glich laden unsere Nutzer etwa 3,5 Millionen neue Fotos hoch, und die Leseanfragen belaufen sich auf ungef\u00e4hr <b>80.000 Anfragen pro Sekunde<\/b>. Das ist ziemlich anspruchsvoll f\u00fcr unser Backend, und manchmal gibt es dabei Schwierigkeiten.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Fotos speichert und bereitstellt, und ich gebe einen Entwicklerblick darauf. Ich werde kurz die Entwicklung beleuchten und die wichtigsten Meilensteine ansprechen, aber ausf\u00fchrlicher \u00fcber die L\u00f6sungen sprechen, die wir derzeit verwenden.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nUnd jetzt lassen Sie uns beginnen.<\/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 R\u00fcckschau sein, und um damit zu beginnen, nehmen wir das naheliegendste Beispiel.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Fotos der Nutzer empfangen, speichern und bereitstellen. In diesem allgemeinen Kontext k\u00f6nnen wir alles verwenden:<\/p>\n<ul>\n<li>modernen Cloud-Speicher,<\/li>\n<li>eine Box-L\u00f6sung, von denen es jetzt auch viele gibt;<\/li>\n<li>wir k\u00f6nnen mehrere Maschinen in unserem Rechenzentrum einrichten, gro\u00dfe Festplatten installieren und die Fotos dort speichern.<\/li>\n<\/ul>\n<p>\nBadoo lebt historisch \u2014 und das gilt sowohl jetzt als auch damals, als es gerade anfing \u2014 auf eigenen Servern in unseren eigenen Rechenzentren. Daher war diese Option f\u00fcr uns optimal.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9434fbabada15670297c551066ad7e71.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben einfach ein paar Maschinen genommen, sie 'photos' genannt, und so einen Cluster aufgebaut, der die Fotos speichert. Aber es scheint, dass etwas fehlt. Um das alles funktionsf\u00e4hig zu machen, m\u00fcssen wir irgendwie bestimmen, auf welcher Maschine welche Fotos gespeichert werden. Hier muss man keine neue Wahrheit entdecken.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/36258e7107fd8c60f7e9e563a2cb681c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir f\u00fcgen unserem Speicher eine Information \u00fcber die Nutzer hinzu, ein Feld. Dies wird der Sharding-Schl\u00fcssel sein. In unserem Fall haben wir es place_id genannt, und dieser Ort-ID zeigt auf den Speicherort der Benutzerfotos. Wir erstellen Karten.<\/p>\n<p>In der ersten Phase kann das sogar manuell gemacht werden \u2014 wir sagen, dass das Foto dieses Nutzers mit diesem Ort auf diesen Server gespeichert wird. Dank dieser Karte wissen wir immer, wo das Foto gespeichert werden soll, sobald der Nutzer es hochl\u00e4dt, und kennen auch den Ort, von dem es bereitgestellt werden soll.<\/p>\n<p>Das ist ein absolut triviales Schema, aber es bietet einige wesentliche Vorteile. Erstens ist es, wie ich bereits erw\u00e4hnte, einfach, und zweitens \u2014 mit diesem Ansatz k\u00f6nnen wir einfach horizontal skalieren, indem wir neue Maschinen hinzuf\u00fcgen und sie in die Karte einf\u00fcgen. Mehr muss nicht getan werden.<\/p>\n<p>So war es eine Zeit lang bei uns.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Maschinen geliefert, geliefert\u2026<\/p>\n<p>Und irgendwann begannen wir zu bemerken, dass dieses Schema bestimmte Nachteile hat. Welche Nachteile?<\/p>\n<p>In erster Linie ist es die begrenzte Kapazit\u00e4t. Wir k\u00f6nnen auf einem physischen Server nicht so viele Festplatten unterbringen, wie wir es gerne h\u00e4tten. Und das wurde im Laufe der Zeit und mit der steigenden Datenmenge zu einem Problem.<\/p>\n<p>Und zweitens. Es handelt sich um eine atypische Maschinenkonfiguration, da solche Maschinen schwer in anderen Clustern wiederverwendet werden k\u00f6nnen; sie sind ziemlich spezifisch, d.h. sie m\u00fcssen in der Leistung schwach sein, aber gleichzeitig gro\u00dfe Festplatten haben.<\/p>\n<p>Das alles war im Jahr 2009, aber im Grunde sind diese Anforderungen auch heute noch relevant. Da wir eine Retrospektive haben, war es 2009 damit sehr schlecht.<\/p>\n<p>Und der letzte Punkt \u2014 die Kosten.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e49010eaeab139199d8fe010caa65bf0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie Kosten waren damals sehr hoch, und wir mussten nach Alternativen suchen. Das hei\u00dft, wir mussten sehen, wie wir sowohl den Platz in den Rechenzentren als auch die physischen Server, auf denen alles untergebracht ist, besser nutzen k\u00f6nnen. Unsere Systemingenieure haben eine gro\u00dfe Studie gemacht, in der sie viele verschiedene Optionen \u00fcberpr\u00fcft haben. Sie haben sich auch Cluster-Dateisystemen wie PolyCeph und Lustre angesehen. Dort gab es Leistungsprobleme und eine ziemlich schwere Nutzung. Davon wurden sie abgebracht. Sie haben versucht, den gesamten Datensatz \u00fcber NFS auf jede Maschine zu mounten, um so irgendwie zu skalieren. Das Lesen war auch nicht ideal, sie haben verschiedene L\u00f6sungen von verschiedenen Anbietern ausprobiert.<\/p>\n<p>Und schlie\u00dflich haben wir uns entschieden, das sogenannte Storage Area Network zu verwenden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 speziell f\u00fcr die Speicherung gro\u00dfer Datenmengen ausgelegt sind. 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, die f\u00fcr unsere Auslieferungslogik, wie zum Beispiel nginx oder anderen, transparent sind, bedienen die Anfragen nach diesen Fotos.<\/p>\n<p>Diese L\u00f6sung brachte offensichtliche Vorteile mit sich. Es handelt sich um SHDs, die auf die Speicherung von Fotos ausgerichtet sind. Es ist g\u00fcnstiger, als wenn wir Maschinen mit Festplatten einrichten.<\/p>\n<p>Ein weiterer Vorteil. <\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7fd2e7d629cc239096b14c68be5f76bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie Kapazit\u00e4t ist erheblich gestiegen, das hei\u00dft, wir k\u00f6nnen in deutlich kleinerem Umfang viel mehr Speicherplatz unterbringen.<\/p>\n<p>Aber es gab auch Nachteile, die sich schnell zeigten. Mit der steigenden Anzahl von Nutzern und der Belastung des Systems traten Leistungsprobleme auf. Das Problem ist offensichtlich \u2013 jede SHD, die daf\u00fcr gedacht ist, viele Fotos auf engem Raum zu speichern, leidet in der Regel unter intensiven Lesevorg\u00e4ngen. Dies ist tats\u00e4chlich auch f\u00fcr jeden Cloud-Speicher relevant. Gegenw\u00e4rtig gibt es kein ideales Speicherger\u00e4t, das unbegrenzt skalierbar ist, in das man alles M\u00f6gliche stecken kann und das gleichzeitig gut mit Lesevorg\u00e4ngen umgehen kann, insbesondere mit zuf\u00e4lligen Lesevorg\u00e4ngen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/566e836e2fe13a2a3d040ae3fa865d6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWie im Fall unserer Fotos, da diese unregelm\u00e4\u00dfig angefragt werden, was die Leistung erheblich beeinflusst.<\/p>\n<p>Schon nach heutigen Zahlen, wenn bei uns mehr als 500 RPS pro Maschine mit Speicher ausfallen, entstehen bereits Probleme. Und das war f\u00fcr uns problematisch, da die Anzahl der Nutzer w\u00e4chst und alles nur schlimmer werden sollte. Wir m\u00fcssen das irgendwie optimieren.<\/p>\n<p>Um zu optimieren, haben wir damals offensichtlicherweise beschlossen, das Lastprofil zu betrachten \u2013 was passiert, was optimiert werden muss.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d67310e6b90c4ee1337065790576c9a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd hier spielen uns alle Faktoren in die Karten.<\/p>\n<p>Ich habe bereits auf der ersten Folie erw\u00e4hnt: Wir haben 80.000 Leseanfragen pro Sekunde bei nur 3,5 Millionen Uploads pro Tag. Das ist eine Differenz von drei Gr\u00f6\u00dfenordnungen. Offensichtlich muss das Lesen optimiert werden und es ist nahezu klar, wie.<\/p>\n<p>Es gibt noch einen kleinen Punkt. Die Spezifik des Services besteht darin, dass sich ein Nutzer registriert, ein Foto hochl\u00e4dt, danach aktiv die Fotos anderer Nutzer ansieht, sie liked und aktiv anderen Nutzern angezeigt wird. Dann findet er einen Partner oder nicht, das kommt darauf an, und h\u00f6rt f\u00fcr eine Weile auf, den Service zu nutzen. In dem Moment, in dem er aktiv ist, sind seine Fotos sehr gefragt \u2013 sie werden von vielen Nutzern angesehen. Sobald er damit aufh\u00f6rt, f\u00e4llt er schnell aus den intensiven Anzeigen, wie vorher, heraus, und seine Fotos werden praktisch nicht mehr angefragt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 daf\u00fcr gibt es viele Anfragen. Eine offensichtliche L\u00f6sung besteht darin, einen Cache hinzuzuf\u00fcgen.<\/p>\n<p>Ein LRU-Cache wird all unsere Probleme l\u00f6sen. Was tun wir?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Speichercluster noch einen vergleichsweise kleinen hinzu, den wir Fotok\u00e4se (photoscache) nennen. Das ist im Grunde ein Proxy, der die Daten cached.<\/p>\n<p>Wie funktioniert das intern? Hier ist unser Nutzer, hier ist der Speicher. Alles wie zuvor. Was f\u00fcgen wir zwischen ihnen hinzu?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 lokalen Festplatte, zum Beispiel SSD. Auf dieser Festplatte befindet sich ein lokaler Cache.<\/p>\n<p>Wie sieht das aus? Der Nutzer sendet eine Anfrage nach einem Foto. NGINX sucht zuerst im lokalen Cache. Falls nicht vorhanden, macht es einfach einen proxy_pass zu unserem Speicher, l\u00e4dt das Foto von dort herunter und gibt es dem Nutzer.<\/p>\n<p>Das klingt sehr einfach und es ist nicht klar, was intern passiert. Es funktioniert ungef\u00e4hr so.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 von \"drei Ebenen\" spreche, bedeutet das nicht, dass es ein kompliziertes System ist. Nein, es sind einfach drei Verzeichnisse im Dateisystem:<\/p>\n<ol>\n<li>Ein Puffer, wohin gerade aus dem Proxy geladene Fotos gelangen.<\/li>\n<li>Ein hei\u00dfer Cache, in dem aktiv angeforderte Fotos gespeichert werden.<\/li>\n<li>Und ein kalter Cache, wo Fotos nach und nach aus dem hei\u00dfen Cache gedr\u00e4ngt werden, wenn weniger Anfragen eingehen.<\/li>\n<\/ol>\n<p>\nDamit das funktioniert, m\u00fcssen wir irgendwie diesen Cache verwalten, Fotos darin verschieben usw. Das ist auch ein sehr primitiver Prozess.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9b16fe3e99a5f88f06169f6e5eedf2b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNginx schreibt bei jedem Request einfach in access.log auf RAMDisk, wo der Pfad zum Bild angegeben ist, das gerade bedient wird (nat\u00fcrlich relativer Pfad), und welcher Abschnitt daf\u00fcr zust\u00e4ndig war. Das hei\u00dft, dort k\u00f6nnte stehen \u201eFoto 1\u201c und danach entweder Puffer, hei\u00dfer Cache, kalter Cache oder Proxy.<\/p>\n<p>Je nachdem m\u00fcssen wir eine Entscheidung treffen, was wir mit dem Bild machen.<\/p>\n<p>Auf jeder Maschine l\u00e4uft ein kleiner Daemon, der st\u00e4ndig dieses Log ausliest und in seinem Speicher eine Statistik \u00fcber die Nutzung bestimmter Fotos speichert.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0dceda5e5ff432d1609520f0c152f152.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEr sammelt einfach die Daten, f\u00fchrt Z\u00e4hlungen und macht dann regelm\u00e4\u00dfig Folgendes: Aktive Fotos, f\u00fcr die viele Requests kommen, verschiebt er in den hei\u00dfen Cache, egal wo sie sich gerade befinden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/941c13ecfea88372f3a7eb62d81b0c4e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFotos, die selten angefordert werden und deren Anfragen zur\u00fcckgehen, schiebt er allm\u00e4hlich aus dem hei\u00dfen Cache in den kalten.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a07235246995ad2fa4e6aeccae23a629.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd wenn der Platz in unserem Cache eng wird, beginnen wir einfach, alles ohne Unterscheidung aus dem kalten Cache zu l\u00f6schen. Und das funktioniert \u00fcbrigens ganz gut.<\/p>\n<p>Um sicherzustellen, dass das Foto sofort beim Proxying in den Puffer gespeichert wird, verwenden wir die Direktive proxy_store, und der Puffer ist ebenfalls RAMDisk, d.h. f\u00fcr den Nutzer funktioniert das sehr schnell. Das betrifft die interne Struktur des Cache-Servers.<\/p>\n<p>Die Frage bleibt, wie wir die Requests auf diese Server verteilen.<\/p>\n<p>Nehmen wir an, es gibt ein Cluster aus zwanzig Storage-Maschinen und drei Cache-Server (so hat es sich ergeben).<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Requests f\u00fcr welche Fotos wo hin geleitet werden.<\/p>\n<p>Die einfachste Variante ist Round Robin. Oder zuf\u00e4llig zu entscheiden?<\/p>\n<p>Das hat offenbar eine Reihe von Nachteilen, da wir in so einer Situation den Cache sehr ineffizient nutzen w\u00fcrden. Anfragen w\u00fcrden auf irgendwelche zuf\u00e4lligen Maschinen fallen: hier wurde sie gecached, auf der benachbarten ist sie schon nicht mehr vorhanden. Und wenn es funktioniert, dann sehr schlecht. Selbst bei einer geringen Anzahl von Maschinen im Cluster.<\/p>\n<p>Wir m\u00fcssen eindeutig bestimmen, auf welchen Server welcher Request geleitet werden soll.<\/p>\n<p>Es gibt einen einfachen Weg. Wir nehmen den Hash der URL oder den Hash unseres Sharding-Schl\u00fcssels, der in der URL enthalten ist, und teilen diesen durch die Anzahl der Server. Wird das funktionieren? Ja.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/794a82ac1268b651ab936f0225b802a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas bedeutet, unser hundertprozentiger Request, zum Beispiel f\u00fcr irgendeine \u201eexample_url\u201c, wird immer auf den Server mit dem Index \u201e2\u201c geleitet, und der Cache wird konstant optimal genutzt.<\/p>\n<p>Aber in solch einem Schema entsteht ein Problem mit dem Resharding. Mit Resharding meine ich die \u00c4nderung der Anzahl von Servern.<\/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 sie hinzu.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5f2fcba4c4f267c069811c3677bd0213.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJetzt teilen wir nicht mehr durch drei, sondern durch vier. Somit wohnen praktisch alle Schl\u00fcssel, die wir fr\u00fcher hatten, praktisch alle URLs nun auf anderen Servern. Der gesamte Cache wurde einfach in diesem Moment ung\u00fcltig. Alle Anfragen str\u00f6mten auf unser Cluster-Storage, es gab eine \u00dcberlastung und unzufriedene Nutzer. Das wollen wir nicht.<\/p>\n<p>Diese Option ist uns ebenfalls nicht geeignet.<\/p>\n<p>Was m\u00fcssen wir also tun? Wir m\u00fcssen irgendwie den Cache effizient nutzen, st\u00e4ndig einen Request auf denselben Server leiten und dabei resistent gegen Resharding sein. Und es gibt eine L\u00f6sung daf\u00fcr, die nicht allzu kompliziert ist. Sie hei\u00dft konsistentes Hashing.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/44f97abfac46fa9f361055548819e8a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir nehmen eine Funktion des Sharding-Keys und verteilen alle ihre Werte gleichm\u00e4\u00dfig auf einem Kreis. Das hei\u00dft, an Punkt 0 treffen sich ihre minimalen und maximalen Werte. Dann platzieren wir auf demselben Kreis alle unsere Server ungef\u00e4hr so:<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 bis zu ihm im Uhrzeigersinn geht, wird entsprechend von diesem Host bedient. Wenn uns Anfragen erreichen, sehen wir sofort, dass beispielsweise Anfrage A \u2014 hat diesen Hash \u2014 und wird von Server 2 bedient. Anfrage B \u2014 von Server 3. Und so weiter.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 zur Speicherung und Auslieferung 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 schieben jeden Sektor um eine kleine Distanz, so dass unser sechster Server, den wir hinzuf\u00fcgen wollen, in den freigewordenen Platz passt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8680e0cf023ce911b4d162e9102c0545.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSicher, in solch einer Situation verschieben sich auch die Schl\u00fcssel. Aber sie verschieben sich viel weniger als fr\u00fcher. Und wir sehen, dass unsere ersten beiden Schl\u00fcssel auf ihren Servern geblieben sind, w\u00e4hrend nur der Cache-Server f\u00fcr den letzten Schl\u00fcssel gewechselt hat. Das funktioniert ziemlich effektiv, und wenn Sie neue Hosts inkrementell hinzuf\u00fcgen, gibt es dabei kein gro\u00dfes Problem. Sie f\u00fcgen nach und nach neue hinzu, warten, bis der Cache wieder voll ist, und alles funktioniert gut.<\/p>\n<p>Die einzige Frage bleibt bei Ausf\u00e4llen. Nehmen wir an, dass eine unserer Maschinen ausgefallen ist.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8e3301af782ce8983716c4bc9add79a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnd wir m\u00f6chten in diesem Moment nicht die Karte neu generieren, den Cache invalidieren usw., falls beispielsweise die Maschine neu gestartet wurde und wir die Anfragen bedienen m\u00fcssen. Wir halten einfach einen Backup-Fotokache auf jedem Standort, der als Ersatz f\u00fcr jede Maschine dient, die derzeit ausgefallen ist. Und wenn pl\u00f6tzlich ein Server nicht mehr verf\u00fcgbar ist, wird der Traffic dorthin geleitet. Dabei haben wir nat\u00fcrlich keinen Cache, d.h. er ist kalt, aber zumindest werden die Nutzeranfragen bearbeitet. Falls es nur f\u00fcr einen kurzen Zeitraum ist, kommen wir damit ganz gut klar. Es wird einfach mehr Last auf dem Speicher liegen. Wenn es einen langen Zeitraum betrifft, k\u00f6nnen wir die Entscheidung treffen \u2013 diesen Server von der Karte zu entfernen oder nicht, oder vielleicht ihn durch einen anderen zu ersetzen.<\/p>\n<p>Das war zur Caching-System. Lassen Sie uns die Ergebnisse betrachten.<\/p>\n<p>Es scheint nichts Kompliziertes dabei zu sein. Aber dieser Ansatz zur Cache-Verwaltung hat uns eine Hitrate von etwa 98 % beschert. D.h. von diesen 80.000 Anfragen pro Sekunde erreichen nur 1.600 die Speicher, und das ist eine ganz normale Last, die sie problemlos bew\u00e4ltigen k\u00f6nnen, wir haben immer einen Puffer.<\/p>\n<p>Wir haben diese Server in drei unserer Rechenzentren platziert und erhalten drei Pr\u00e4senzpunkte \u2013 Prag, Miami und Hongkong.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 tats\u00e4chlich ungenutzt ist, da sie f\u00fcr die Bereitstellung von Inhalten nicht so stark ben\u00f6tigt wird. Dort haben wir mit NGINX+ Lua viel pragmatische Logik implementiert.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 progressive jpeg experimentieren (das sind moderne effiziente Formate), ansehen, wie sich das auf den Traffic auswirkt, Entscheidungen treffen, dies f\u00fcr bestimmte L\u00e4nder aktivieren usw.; dynamisches Resize oder Cropping von Fotos on-the-fly durchf\u00fchren.<\/p>\n<p>Das ist ein guter Anwendungsfall, wenn Sie beispielsweise eine mobile Anwendung haben, die Fotos anzeigt, und die mobile Anwendung nicht die CPU des Clients f\u00fcr das Abrufen eines gro\u00dfen Fotos verwenden m\u00f6chte, um es dann auf eine bestimmte Gr\u00f6\u00dfe zu skalieren, um in die Ansicht zu passen. Wir k\u00f6nnen einfach dynamisch im URL einige Parameter im sogenannten UPort angeben, und der Fotokache wird das Bild selbst resize. In der Regel w\u00e4hlt er die Gr\u00f6\u00dfe aus, die wir physisch auf der Festplatte haben und die der angeforderten m\u00f6glichst nahekommt, und skaliert es an bestimmten Koordinaten herunter.<\/p>\n<blockquote><p>\u00dcbrigens haben wir die Videoaufzeichnungen der letzten f\u00fcnf Jahre von Konferenzen \u00fcber hochbelastete Systeme \u00f6ffentlich zug\u00e4nglich gemacht. <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex>. Sehen Sie sich das an, lernen Sie, teilen Sie es und abonnieren Sie den <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/profyclub\">YouTube-Kanal<\/a><\/noindex>.<\/p><\/blockquote>\n<p>\nAu\u00dferdem k\u00f6nnen wir dort viele produktbezogene Logik hinzuf\u00fcgen. Zum Beispiel k\u00f6nnen wir basierend auf den URL-Parametern unterschiedliche Wasserzeichen hinzuf\u00fcgen, Fotos verwischen, unscharf oder pixelieren. Das ist, wenn wir ein Foto einer Person zeigen m\u00f6chten, aber nicht ihr Gesicht zeigen wollen, das funktioniert gut, all das ist hier realisiert.<\/p>\n<p>Was haben wir erhalten? Wir haben drei Pr\u00e4senzpunkte, eine gute Hitrate, und dabei wird die CPU dieser Maschinen nicht ungenutzt. Sie ist nun nat\u00fcrlich wichtiger geworden als zuvor. Wir m\u00fcssen uns st\u00e4rkere Maschinen anschaffen, aber das ist es wert.<\/p>\n<p>Was die Bereitstellung von Fotos betrifft, ist alles ziemlich klar und offensichtlich. Ich denke, ich habe nicht Amerika entdeckt; so funktioniert praktisch jedes CDN.<\/p>\n<p>Und wahrscheinlich k\u00f6nnte bei einem gestandenen Zuh\u00f6rer die Frage aufkommen: Warum nicht einfach alles auf ein CDN umstellen? Es w\u00e4re ziemlich das Gleiche, alle modernen CDNs k\u00f6nnen das. Und hier gibt es einige Gr\u00fcnde.<\/p>\n<p>Der erste sind die Fotos.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Schl\u00fcsselpunkte unserer Infrastruktur, und wir ben\u00f6tigen so viel Kontrolle wie m\u00f6glich dar\u00fcber. Wenn dies eine L\u00f6sung eines Drittanbieters ist und Sie keine Kontrolle dar\u00fcber haben, wird es Ihnen schwer fallen, damit zu leben, wenn Sie einen gro\u00dfen Datensatz haben und wenn Sie einen sehr gro\u00dfen Strom von Benutzeranfragen haben.<\/p>\n<p>Ich gebe ein Beispiel. Derzeit k\u00f6nnen wir in unserer Infrastruktur, falls es Probleme oder Ersch\u00fctterungen gibt, auf die Maschine zugreifen und dort debuggen, sozusagen. Wir k\u00f6nnen spezifische Metriken erfassen, die nur f\u00fcr uns von Interesse sind, experimentieren und beobachten, wie sich dies auf die Grafiken auswirkt und so weiter. Momentan sammeln wir eine gro\u00dfe Menge an Statistiken zu diesem Cache-Cluster. Wir schauen regelm\u00e4\u00dfig darauf und analysieren lange anomale Werte. W\u00e4re dies auf der CDN-Seite, w\u00e4re es viel schwieriger zu kontrollieren. Oder zum Beispiel, wenn es zu einem Vorfall kommt, wissen wir, was passiert ist, wissen, wie wir damit leben k\u00f6nnen und wie wir es bew\u00e4ltigen k\u00f6nnen. Das ist die erste Erkenntnis.<\/p>\n<p>Die zweite Erkenntnis ist eher historisch, weil sich das System bereits lange entwickelt, und es gab viele verschiedene Gesch\u00e4ftsanforderungen in verschiedenen Phasen, die nicht immer in das CDN-Konzept passten.<\/p>\n<p>Und der Punkt, der sich daraus ergibt \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/007cf3aed2f9cc12185fc3865bf9d196.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs gibt viele spezifische Logiken in unseren Fotocaches, die oft nicht auf Anfrage hinzugef\u00fcgt werden k\u00f6nnen. Wahrscheinlich wird kein CDN auf Ihre Anfrage hin benutzerdefinierte Dinge hinzuf\u00fcgen. Zum Beispiel die Verschl\u00fcsselung von URLs, wenn Sie nicht m\u00f6chten, dass Kunden etwas \u00e4ndern k\u00f6nnen. Wenn Sie die URL auf dem Server \u00e4ndern und sie verschl\u00fcsseln m\u00f6chten, um dann einige dynamische Parameter zu \u00fcbergeben.<\/p>\n<p>Welche Schlussfolgerung dr\u00e4ngt sich auf? In unserem Fall ist das CDN keine besonders gute Alternative.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/cfc2963cca2357cf6b0f63419a4dc436.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn Ihrem Fall jedoch, wenn Sie spezifische Gesch\u00e4ftsanforderungen haben, k\u00f6nnen Sie das, was ich Ihnen gezeigt habe, ganz entspannt selbst umsetzen. Und das wird bei \u00e4hnlichem 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 Ihnen die Zeit und Ressourcen viel wichtiger sind als die Kontrolle.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b76d25404918a5d0d8bf1d6644c8d873.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nModerne CDNs verf\u00fcgen \u00fcber nahezu alles, was ich Ihnen gerade erz\u00e4hlt habe. Mit Ausnahme von plus minus einigen Funktionen.<\/p>\n<p>Das betrifft die Auslieferung von Bildern.<\/p>\n<p>Lassen Sie uns jetzt ein wenig in unserer R\u00fcckschau nach vorne bewegen und \u00fcber die Speicherung sprechen.<\/p>\n<p>Das Jahr 2013<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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, Performance-Probleme sind verschwunden. Alles ist gut. Das Dataset w\u00e4chst. Im Jahr 2013 hatten wir etwa 80 Server, die mit Storage verbunden waren, 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 zur Speicherung und Auslieferung 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 begannen die Betriebskosten erheblich zu steigen. In was \u00e4u\u00dferte sich das?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6cf5e489a4e97bc6e26fc6d4d16505b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn diesem Diagramm, das gezeichnet ist \u2013 mit SAN, mit angeschlossenen Maschinen und Caches \u2013 gibt es sehr viele Ausfallpunkte. Wenn wir fr\u00fcher mit den Ausf\u00e4llen der Cache-Server schon umgehen konnten, da war alles mehr oder weniger vorhersehbar und verst\u00e4ndlich, dann war es auf der Seite des Storages viel problematischer.<\/p>\n<p>Einerseits kann das Storage Area Network (SAN) ausfallen.<\/p>\n<p>Andererseits ist es \u00fcber Glasfaser mit den Endger\u00e4ten verbunden. Es k\u00f6nnen Probleme mit den optischen Karten und Switches auftreten.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6959b79284c5b1244a70a1d64f191893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs sind zwar nicht so viele wie mit dem SAN selbst, aber dennoch sind auch das Ausfallpunkte.<\/p>\n<p>Dann gibt es die Maschinen, die mit dem Storage verbunden sind. Auch diese k\u00f6nnen ausfallen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1801cb502663a4de14329a5e67dfed79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nInsgesamt haben wir drei Ausfallpunkte.<\/p>\n<p>Neben den Ausfallpunkten gibt es die schwierige Wartung der Speicher.<\/p>\n<p>Es ist ein komplexes, mehrkomponentenes System, und es ist f\u00fcr Systemingenieure oft schwierig, damit umzugehen.<\/p>\n<p>Und der letzte, wichtigere Punkt. Wenn an einem dieser drei Punkte ein Ausfall auftritt, haben wir eine nicht nullwahrscheinliche Gefahr, Benutzerdaten zu verlieren, weil das Dateisystem besch\u00e4digt werden kann.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 kann einerseits lange dauern \u2013 das kann bei gro\u00dfen Datenmengen eine Woche in Anspruch nehmen. Und andererseits werden wir wahrscheinlich eine Menge unverst\u00e4ndlicher Dateien erhalten, die wir irgendwie den Benutzerfotos zuordnen 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 Kette entstehen, desto gr\u00f6\u00dfer wird dieses Risiko.<\/p>\n<p>Damit musste etwas unternommen werden. Und wir beschlossen, dass wir einfach die Daten sichern m\u00fcssen. Das ist tats\u00e4chlich eine offensichtliche und gute L\u00f6sung. Was haben wir gemacht?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 zuvor mit dem Storage verbunden war. Dies ist eine Hauptpartition, eine blockbasierte Einheit, die tats\u00e4chlich ein Mount auf den entfernten Storage \u00fcber Lichtwellenleiter darstellt.<\/p>\n<p>Wir haben einfach eine zweite Partition hinzugef\u00fcgt.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 allzu teuer) und ihn Backup-Partition genannt. Er ist ebenfalls \u00fcber Glasfaser verbunden und befindet sich auf derselben Maschine. Aber wir m\u00fcssen die Daten zwischen ihnen synchronisieren.<\/p>\n<p>Hier erstellen wir einfach eine asynchrone Warteschlange daneben.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/67bced2b45c589009cfb01a1c21398a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs ist nicht sehr belastet. Wir wissen, dass wir nur wenige Eintr\u00e4ge haben. Die Warteschlange ist einfach eine Tabelle in MySQL, in die Zeilen wie \u201eDieses Foto muss gesichert werden\u201c geschrieben werden. Bei jeder \u00c4nderung oder beim Upload kopieren wir asynchron oder mit einem Hintergrundprozess vom Hauptspeicher auf das Backup.<\/p>\n<p>So haben wir immer zwei konsistente Speichereinheiten. Selbst wenn ein Teil dieses Systems ausf\u00e4llt, k\u00f6nnen wir immer den Hauptspeicher mit dem Backup austauschen, und alles funktioniert weiter.<\/p>\n<p>Aber dadurch steigt die Leselast erheblich, denn neben den Clients, die vom Hauptspeicher lesen, weil sie sich das Foto dort zun\u00e4chst ansehen (es ist ja dort aktueller), suchen sie erst auf dem Backup, wenn sie es dort nicht finden (aber das erledigt NGINX einfach). Unsere Backup-L\u00f6sung zieht nun auch Daten vom Hauptspeicher. Das ist nicht wirklich ein Engpass, aber ich wollte die Last nicht unn\u00f6tig erh\u00f6hen.<\/p>\n<p>Also haben wir eine dritte Festplatte hinzugef\u00fcgt, einen kleinen SSD, und haben ihn als Puffer bezeichnet.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd35481822b4170087e5f670bf338dc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo funktioniert das jetzt.<\/p>\n<p>Der Benutzer l\u00e4dt ein Foto auf den Puffer hoch, dann wird ein Event in die Warteschlange geworfen, dass es auf die beiden Speichereinheiten kopiert werden muss. Es wird kopiert, und das Foto lebt eine gewisse Zeit (sagen wir, einen Tag) im Puffer, bevor es gel\u00f6scht wird. Das verbessert das Nutzererlebnis erheblich, weil der Benutzer das Foto normalerweise hochl\u00e4dt, w\u00e4hrend sofort darauf Anfragen folgen, oder er selbst die Seite aktualisiert. Aber das h\u00e4ngt alles von der Anwendung ab, die den Upload durchf\u00fchrt.<\/p>\n<p>Oder, zum Beispiel, andere Personen, die das Foto sehen wollen, senden sofort Anfragen nach diesem Foto. Es ist noch nicht im Cache, die erste Anfrage passiert sehr schnell. Im Grunde genommen ist es so wie bei dem Fotocache. Der langsame Speicher ist daran nicht beteiligt. Wenn es nach einem Tag gel\u00f6scht wird, ist es entweder bereits in unserem Cache oder es wird wahrscheinlich niemand mehr ben\u00f6tigt. Das Nutzererlebnis hat sich durch diese einfachen Ma\u00dfnahmen also erheblich verbessert.<\/p>\n<p>Und das Wichtigste: Wir haben aufgeh\u00f6rt, Daten zu verlieren.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/526f549457dd0c438f32b0adb76df76c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir haben, sagen wir mal, aufgeh\u00f6rt <em>potenziell<\/em> Daten zu verlieren, weil wir sie nicht wirklich verloren haben. Aber die Gefahr war vorhanden. Wir sehen, dass diese L\u00f6sung nat\u00fcrlich gut ist, aber sie sieht etwas nach einer Symptombehandlung aus, anstatt das Problem wirklich zu l\u00f6sen. Und einige Probleme bleiben noch bestehen.<\/p>\n<p>Erstens gibt es den Ausfallpunkt in Form des physischen Hosts, auf dem diese ganze Infrastruktur l\u00e4uft, der ist nicht verschwunden.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0eb3d292655a7edf912793ed81e8931c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZweitens gibt es immer noch Probleme mit SANs, der schwere Wartungsaufwand usw. Das war nicht wirklich ein kritischer Faktor, aber wir wollten versuchen, ohne das auszukommen.<\/p>\n<p>Also haben wir die dritte Version entwickelt (in Wirklichkeit die zweite) \u2013 die Version mit Reservierung. Wie sah das aus?<\/p>\n<p>Das war es, was war \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8b1749b6feed200f8a64529ee2316c1a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnsere Hauptprobleme lagen darin, dass dies ein physischer Host war.<\/p>\n<p>Erstens entfernen wir die SANs, weil wir experimentieren wollen, wir wollen einfach lokale Festplatten ausprobieren.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 hatte sich die Situation mit Festplatten und deren Speicherkapazit\u00e4t pro Host erheblich verbessert. Wir dachten uns, warum nicht einfach mal ausprobieren.<\/p>\n<p>Und dann nehmen wir einfach unseren Backup-Speicher und verlagern ihn physisch auf eine separate Maschine.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/456e00bc8557d3340b06efcd1dde8a08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo erhalten wir ein solches Schema. Wir haben zwei Maschinen, die identische Datenmengen speichern. Sie sichern sich gegenseitig vollst\u00e4ndig und synchronisieren die Daten \u00fcber das Netzwerk mittels einer asynchronen Warteschlange im gleichen MySQL.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 nur wenige Eintr\u00e4ge haben. Wenn die Anzahl der Eintr\u00e4ge mit der Anzahl der Lesevorg\u00e4nge vergleichbar gewesen w\u00e4re, h\u00e4tten wir m\u00f6glicherweise eine Netzwerk\u00fcberlastung und Probleme bekommen. Wenige Eintr\u00e4ge, viele Lesevorg\u00e4nge \u2013 diese Methode funktioniert gut, d.h. wir kopieren Fotos zwischen diesen beiden Servern relativ selten.<\/p>\n<p>Wie funktioniert das, wenn wir es etwas detaillierter betrachten?<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/071c11abb6ee1d7734c53052139ff04b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUpload. Der Lastenausgleich w\u00e4hlt einfach zuf\u00e4llig Hosts aus dem Paar und f\u00fchrt den Upload auf ihnen durch. Dabei f\u00fchrt er nat\u00fcrlich Gesundheitschecks durch und stellt sicher, dass die Maschine nicht ausgefallen ist. D.h. er l\u00e4dt Fotos nur auf den funktionierenden Server hoch, und dann wird alles \u00fcber eine asynchrone Warteschlange auf den Nachbarn kopiert. Der Upload ist also ganz einfach.<\/p>\n<p>Die Aufgabe ist etwas komplizierter.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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, denn mit Vanilla NGINX ist es manchmal schwierig, eine solche Logik umzusetzen. Wir machen zun\u00e4chst eine Anfrage an den ersten Server, um zu sehen, ob das Foto dort vorhanden ist, denn es k\u00f6nnte theoretisch auch auf dem Nachbarserver hochgeladen worden sein und ist hier noch nicht angekommen. Wenn das Foto dort vorhanden ist, ist das gut. Wir geben es sofort an den Kunden weiter und cachen es m\u00f6glicherweise.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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, machen wir einfach eine Anfrage an den Nachbarn und erhalten es von dort garantiert.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Leistungsprobleme auftreten, weil st\u00e4ndige Round-Trips \u2013 das Foto wurde hochgeladen, aber hier ist es nicht, wir machen zwei Anfragen anstelle von einer, das sollte langsam arbeiten.<\/p>\n<p>In unserer Situation funktioniert das nicht langsam.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/52ca3902d80990f512201672cd5e6441.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir sammeln eine Menge Metriken zu diesem System, und die bedingte Trefferquote eines solchen Mechanismus liegt bei etwa 95 %. Das hei\u00dft, die Verz\u00f6gerung dieses Backups ist gering, und dadurch holen wir das Foto nahezu garantiert beim ersten Mal ab, nachdem es hochgeladen wurde, und m\u00fcssen nicht zweimal nachfragen.<\/p>\n<p>Was haben wir also noch erhalten, und das ist wirklich toll?<\/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 Hauptspeicher gesucht und dann auf dem Backup. Das war ein Durchgang.<\/p>\n<p>Jetzt nutzen wir das Lesen von zwei Maschinen gleichzeitig. Wir verteilen die Anfragen im Round-Robin-Verfahren. In einem kleinen Prozentsatz der F\u00e4lle machen wir zwei Anfragen. Aber insgesamt haben wir jetzt doppelt so viel Lesepuffer wie zuvor. Und die Belastung ist deutlich gesunken, sowohl auf den ausgebenden Maschinen als auch direkt auf den Speichern, die wir zu diesem Zeitpunkt ebenfalls hatten.<\/p>\n<p>Was die Fehlertoleranz angeht: Genau daf\u00fcr haben wir haupts\u00e4chlich gek\u00e4mpft. Mit der Fehlertoleranz l\u00e4uft hier alles hervorragend.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/42900b24e340c03ea642fd49f5b410ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKeine Probleme! Der Systemingenieur muss nicht einmal nachts aufwachen, er kann bis zum Morgen warten, es wird nichts Schlimmes passieren.<\/p>\n<p>Selbst wenn die Warteschlange bei einem Ausfall dieser Maschine nicht mehr funktioniert, gibt es keine Probleme, das Protokoll wird einfach zun\u00e4chst auf der funktionierenden Maschine angesammelt und sp\u00e4ter in die Warteschlange \u00fcberf\u00fchrt, und dann an die Maschine, die nach einiger Zeit wieder in Betrieb genommen wird.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 Wartungsarbeiten. Wir schalten einfach eine der Maschinen aus, entfernen sie manuell aus allen Pools, sie erh\u00e4lt keinen Verkehr mehr, f\u00fchren Wartungsarbeiten durch, beheben etwas, und nachdem wir sie wieder in Betrieb nehmen, wird dieses Backup recht schnell aufgeholt. Das hei\u00dft, w\u00e4hrend der Ausfallzeit einer Maschine wird in ein paar Minuten aufgeholt. Das ist wirklich sehr wenig. Bei der Fehlertoleranz, wie gesagt, l\u00e4uft hier alles super.<\/p>\n<p>Was k\u00f6nnen wir aus diesem Backup-Schema zusammenfassen?<\/p>\n<p>Wir haben Fehlertoleranz erhalten.<\/p>\n<p>Einfache Wartung. Da die Maschinen lokale Festplatten haben, ist das aus Sicht der Ingenieure, die damit arbeiten, viel bequemer.<\/p>\n<p>Wir haben einen doppelten Lesepuffer erhalten.<\/p>\n<p>Das ist ein sehr guter Bonus zur Fehlertoleranz.<\/p>\n<p>Aber es gibt auch Probleme. Jetzt haben wir eine viel komplexere Entwicklung von Funktionen, die damit zusammenh\u00e4ngen, da das System jetzt zu 100 % schlie\u00dflich konsistent ist.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 dar\u00fcber nachdenken: 'Auf welchem Server sind wir gerade?', 'Gibt es hier wirklich das aktuelle Foto?' und so weiter. Das ist nat\u00fcrlich alles in Wrapper eingebunden, und f\u00fcr den Programmierer, der die Gesch\u00e4ftslogik schreibt, ist das transparent. Aber dennoch ist das ein gro\u00dfer, komplizierter Layer entstanden. Aber wir sind bereit, damit zu leben im Austausch f\u00fcr die Vorteile, die wir dadurch erhalten haben.<\/p>\n<p>Und hier entsteht erneut 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 uns das gefallen hat.<\/p>\n<p>Ja, in der Tat hat sich die Situation im Laufe der Zeit stark ver\u00e4ndert, und mittlerweile gibt es viele Vorteile in diesem Ansatz. Erstens haben wir eine viel einfachere Wartung.<\/p>\n<p>Zweitens ist es leistungsf\u00e4higer, weil wir diese automatischen Controller f\u00fcr die Verbindung zu Festplattenspeichern nicht haben.<\/p>\n<p>Dort gibt es eine riesige Maschinerie, aber hier sind einfach einige Festplatten, die hier auf der Maschine in einem RAID zusammengefasst sind.<\/p>\n<p>Aber es gibt auch Nachteile.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3c090e0801f1a686dc0d5fefce697c56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist ungef\u00e4hr 1,5-mal teurer als die Verwendung von SANs selbst zu heutigen Preisen. Daher haben wir beschlossen, nicht so mutig unseren gesamten gro\u00dfen Cluster in Maschinen mit lokalen Festplatten zu konvertieren und ein hybrides System zu \u00fcbrig zu lassen.<\/p>\n<p>Ein Teil der Maschinen arbeitet mit Festplatten (nun, nicht die H\u00e4lfte \u2013 wahrscheinlich etwa 30 Prozent). Der verbleibende Teil sind alte Maschinen, auf denen fr\u00fcher das erste Backup-Schema war. Wir haben sie einfach umgemountet, da wir keine neuen Daten oder \u00e4hnliches ben\u00f6tigen, wir haben nur die Mounts von einem physischen Host auf zwei \u00fcbertragen.<\/p>\n<p>Und wir haben einen gro\u00dfen Lesepuffer erhalten, und wir haben uns vergr\u00f6\u00dfert. Wenn wir fr\u00fcher einen Speicher auf eine Maschine montiert haben, montieren wir jetzt zum Beispiel vier auf ein Paar. Und das funktioniert normal.<\/p>\n<p>Lassen Sie uns eine kurze Zusammenfassung dessen geben, was wir erreicht haben, wof\u00fcr wir gek\u00e4mpft haben und ob es funktioniert hat.<\/p>\n<h3>Ergebnisse<\/h3>\n<p>\nWir haben Nutzer \u2013 ganze 33 Millionen.<\/p>\n<p>Wir haben drei Standorte \u2013 Prag, Miami, Hongkong.<\/p>\n<p>In ihnen befindet sich eine Caching-Schicht, die aus Maschinen mit schnellen lokalen Festplatten (SSD) besteht, auf denen eine einfache Maschine mit NGINX, seinen access.log und Python-Daemons arbeitet, die alles verarbeiten und den Cache verwalten.<\/p>\n<p>Falls gew\u00fcnscht, k\u00f6nnen Sie in Ihrem Projekt, wenn Ihnen Fotos nicht so wichtig sind wie uns, oder wenn Ihr Trade-off zwischen Kontrolle und Geschwindigkeit zugunsten der Ressourcenkosten geht, ganz einfach auf ein CDN wechseln; moderne CDNs schaffen das gut.<\/p>\n<p>Darauf folgt die Speicherschicht, in der wir Cluster aus Paaren von Maschinen haben, die sich gegenseitig sichern und asynchron Dateien von einer zu der anderen Kopie bei jeder \u00c4nderung.<\/p>\n<p>Ein Teil dieser Maschinen arbeitet mit lokalen Festplatten.<\/p>\n<p>Ein Teil dieser Maschinen ist an SANs angeschlossen.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5ddbc4f73d86aa1f83734885d8c9dea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEinerseits ist das in der Handhabung bequemer und etwas leistungsf\u00e4higer, andererseits bietet es Vorteile hinsichtlich der Dichte und der Kosten pro Gigabyte.<\/p>\n<p>Das ist eine kurze \u00dcbersicht \u00fcber die Architektur dessen, was wir erreicht haben und wie sich alles entwickelt hat.<\/p>\n<p>Ein paar einfache Tipps von Cap.<\/p>\n<p>Zun\u00e4chst, falls Sie sich entscheiden, dass Sie dringend alles in Ihrer Foto-Infrastruktur verbessern m\u00fcssen, messen Sie zuerst, denn m\u00f6glicherweise gibt es nichts, was verbessert werden m\u00fcsste.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7770f41d0b190eb78ae0d19f4c8182a6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEin Beispiel: Wir haben einen Cluster von Maschinen, der Fotos aus Anh\u00e4ngen in Chats ausliefert, und dort l\u00e4uft immer noch das Schema von 2009, und niemand leidet darunter. Allen gef\u00e4llt es.<\/p>\n<p>Um zu messen, h\u00e4ngen Sie zun\u00e4chst eine Menge Metriken an, schauen Sie sich diese an und entscheiden Sie dann, mit was Sie unzufrieden sind und was verbessert werden muss. Daf\u00fcr haben wir ein tolles Werkzeug namens Pinba.<\/p>\n<p>Es erm\u00f6glicht das Sammeln von sehr detaillierten Statistiken von NGINX f\u00fcr jede Anfrage sowie Antwortcodes und Zeitverteilungen \u2014 alles, was Sie wollen. Es hat Bindungen zu verschiedenen Analysesystemen, und Sie k\u00f6nnen alles sch\u00f6n betrachten.<\/p>\n<p>Zuerst gemessen \u2014 dann verbessert.<\/p>\n<p>Wir optimieren das Lesen mit Cache, das Schreiben mit Sharding, aber das ist offensichtlich.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f53a4777f1a2c7793eba4a72c94263a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWenn Sie gerade erst anfangen, Ihr System zu bauen, ist es viel besser, Fotos als immutable Dateien zu speichern. So verlieren Sie sofort eine ganze Klasse von Problemen mit Cache-Invalidierung und wie die Logik die richtige Version des Fotos finden sollte.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung von Fotos in Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f345c59681275326cda1320b4f188ce9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNehmen wir an, Sie haben ein Bild hochgeladen und anschlie\u00dfend gedreht, stellen Sie sicher, dass es sich um eine physisch andere Datei handelt. D.h. Sie m\u00fcssen nicht denken: Ich spare ein wenig Platz, indem ich es in die gleiche Datei schreibe und die Version \u00e4ndere. Das funktioniert immer schlecht und bringt sp\u00e4ter viel Kopfzerbrechen.<\/p>\n<p>Der n\u00e4chste Punkt: Resize zur Laufzeit.<\/p>\n<p>Fr\u00fcher haben wir, als Benutzer ein Foto hochluden, sofort eine ganze Reihe von verschiedenen Gr\u00f6\u00dfen f\u00fcr alle m\u00f6glichen Anwendungsf\u00e4lle geschnitten, die auf der Festplatte lagen. Jetzt haben wir das aufgegeben.<\/p>\n<p>Wir haben nur drei Hauptgr\u00f6\u00dfen beibehalten: klein, mittel und gro\u00df. Alles andere wird einfach aus der Gr\u00f6\u00dfe, die hinter der angeforderten steht, heruntergerechnet \u2014 wir machen einfach Downsizing und geben es dem Benutzer.<\/p>\n<p>Die CPU der Caching-Schicht ist hier viel g\u00fcnstiger, als wenn wir diese Gr\u00f6\u00dfen auf jedem Speicher st\u00e4ndig neu generieren w\u00fcrden. Angenommen, wir m\u00f6chten eine neue Gr\u00f6\u00dfe hinzuf\u00fcgen, dann dauert das einen Monat \u2014 ein Skript, das das \u00fcberall ordentlich macht, w\u00e4hrend der Cluster nicht \u00fcberlastet wird. Das bedeutet, wenn Sie jetzt eine Entscheidung treffen k\u00f6nnen, ziehen Sie es vor, so wenige physische Gr\u00f6\u00dfen wie m\u00f6glich zu haben, aber mit einer gewissen Verteilung, sagen wir drei. Und alles andere einfach zur Laufzeit mit vorhandenen Modulen zu resize.<\/p>\n<p>Und inkrementelles asynchrones Backup ist gro\u00dfartig.<\/p>\n<p>Wie unsere Praxis gezeigt hat, funktioniert ein solches Schema hervorragend f\u00fcr das verz\u00f6gerte Kopieren ge\u00e4nderter Dateien.<\/p>\n<p><img decoding=\"async\" alt=\"Architektur zur Speicherung und Auslieferung 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 ebenso offensichtlich. Wenn Sie in Ihrer Infrastruktur jetzt keine solchen Probleme haben, aber es etwas gibt, das kaputtgehen k\u00f6nnte, wird es best\u00e4ndig kaputtgehen, wenn es ein wenig mehr wird. Daher ist es besser, im Voraus dar\u00fcber nachzudenken und dabei keine Probleme zu haben. Das ist alles von meiner Seite.<\/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\/\">Badoo Unternehmensblog<\/a><\/noindex><\/p>\n<blockquote><p>Dieser Bericht ist eine Transkription eines der besten Vortr\u00e4ge auf der Konferenz f\u00fcr Entwickler von hochbelasteten Systemen. <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 HighLoad++ 2017 Konferenz 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>, und der Zeitplan wird jetzt aktiv erstellt.<\/p>\n<p>In diesem Jahr setzen wir unser Thema der Architektur 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 Nutzer bedient und Terabit-Traffic bereitstellt.<\/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 VKontakte von Grund auf neu schreibt und sie 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\">Der Ausverkaufs-Tod: Wie Yandex.Money versuchte, sich f\u00fcr den Black Friday aufzustellen 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\">Ausfallsichere Architektur des Frontsystems der Bank<\/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 Enterprise<\/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 sorgf\u00e4ltig ausgew\u00e4hlter Briefe, Artikel, Materialien und Videos. In unserem Handbuch gibt es bereits \u00fcber 30 einzigartige Materialien. Melden Sie sich an!\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.0.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.0.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 bei 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}]}}