Architectuur voor het opslaan en delen van foto's in Badoo.

Architectuur voor het opslaan en delen van foto's in Badoo.

Artem Denisov ( bo0rsh201, Badoo)

Badoo is de grootste datingsite ter wereld. Momenteel hebben we ongeveer 330 miljoen geregistreerde gebruikers wereldwijd. Maar wat veel belangrijker is in de context van ons gesprek vandaag, is dat we ongeveer 3 petabyte aan gebruikersfoto's opslaan. Elke dag uploaden onze gebruikers zo'n 3,5 miljoen nieuwe foto's, en de leesbelasting bedraagt ongeveer 80.000 verzoeken per seconde. Dit is behoorlijk veel voor onze backend, en soms gaat het wel eens mis.

Architectuur voor het opslaan en delen van foto's in Badoo.

Ik zal het ontwerp van dit systeem bespreken dat foto's opslaat en levert, en ik zal een ontwikkelaarsblik erop werpen. Ik zal ook kort terugblikken op de ontwikkeling ervan, waarbij ik belangrijke mijlpalen aanstip, maar verder zal ik alleen in detail ingaan op de oplossingen die we nu gebruiken.

Laten we nu beginnen.

Video afspelen

Zoals ik al zei, dit zal een terugblik zijn, en om die te starten, laten we een heel eenvoudig voorbeeld nemen.

Architectuur voor het opslaan en delen van foto's in Badoo.

We hebben een algemene taak, we moeten de foto's van gebruikers ontvangen, opslaan en leveren. In deze vorm is de taak algemeen, we kunnen alles gebruiken:

  • moderne cloudopslag,
  • kant-en-klare oplossingen, waarvan er momenteel ook veel zijn;
  • we kunnen een aantal machines in ons datacenter opzetten en er grote harde schijven op installeren om de foto’s daar op te slaan.

Badoo bestaat historisch gezien — zowel nu als toen (in de tijd dat het net begon) — op eigen servers, binnen onze eigen datacenters. Daarom was deze optie voor ons optimaal.

Architectuur voor het opslaan en delen van foto's in Badoo.

We hebben gewoon een paar machines genomen, ze ‘photos’ genoemd, en zo kregen we een cluster dat foto's opslaat. Maar het lijkt erop dat er iets ontbreekt. Om dit alles te laten werken, moeten we op de een of andere manier bepalen op welke machine we welke foto's gaan opslaan. En hier hoeven we ook geen nieuwe dingen te ontdekken.

Architectuur voor het opslaan en delen van foto's in Badoo.

We voegen een veld toe aan onze opslag met informatie over gebruikers. Dit wordt de sharding sleutel. In ons geval hebben we het place_id genoemd, en deze id van plaatsen geeft aan waar de foto's van de gebruikers worden opgeslagen. We maken kaarten.

In de eerste fase kan dit zelfs handmatig gedaan worden — we zeggen dat de foto van deze gebruiker met deze plaats op deze server zal landen. Dankzij deze kaart weten we altijd waar we de foto moeten opslaan en vanwaar we deze moeten aanbieden wanneer de gebruiker deze uploadt.

Dit is een absoluut triviaal schema, maar het heeft een aantal belangrijke voordelen. Ten eerste is het eenvoudig, zoals ik al zei, en ten tweede kunnen we met deze benadering gemakkelijk horizontaal opschalen door simpelweg nieuwe machines te leveren en ze aan de kaart toe te voegen. Daar is verder niets voor nodig.

Zo was het een tijdje bij ons.

Architectuur voor het opslaan en delen van foto's in Badoo.

Het was ergens in 2009. We leverden auto's, we leverden...

En op een gegeven moment begonnen we op te merken dat dit schema bepaalde nadelen had. Wat voor nadelen?

In de eerste plaats is er de beperkte capaciteit. We kunnen niet zoveel harde schijven in één fysieke server stoppen als we zouden willen. En dit is in de loop van de tijd en met de groei van de dataset een probleem geworden.

En ten tweede. Dit is een atypische configuratie van machines, omdat het moeilijk is om dergelijke machines opnieuw te gebruiken in andere clusters; ze zijn vrij specifiek, dat wil zeggen, ze moeten laag in prestaties zijn, maar tegelijkertijd met een grote harde schijf.

Dit alles was in 2009, maar in principe zijn deze eisen vandaag de dag nog steeds relevant. We hebben een retrospectief, dus in 2009 was het qua dit alles slecht.

En het laatste punt — de prijs.

Architectuur voor het opslaan en delen van foto's in Badoo.

De prijs was toen behoorlijk hoog, en we moesten naar alternatieven zoeken. We moesten beter omgaan met de ruimte in datacenters en met de fysieke servers waarop dit allemaal geplaatst was. Onze systeemingenieurs begonnen een groot onderzoek, waarin ze een heleboel verschillende opties heroverwogen. Ze keken ook naar clustered file systems, zoals PolyCeph en Lustre. Daar waren er prestatieproblemen en een vrij zware exploitatie. We hebben dat verworpen. We probeerden de hele dataset via NFS op elke machine te monteren, om zo op de een of andere manier op te schalen. Het lezen ging ook slecht, we hebben verschillende oplossingen van verschillende leveranciers geprobeerd.

En uiteindelijk kwamen we tot de conclusie dat we gebruik gingen maken van wat we een Storage Area Network noemen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dit zijn grote SHD's die specifiek zijn gericht op de opslag van grote hoeveelheden gegevens. Ze bestaan uit rekken met schijven die zijn gemonteerd op eindmachines via optische verbinding. Zo hebben we een pool van machines, relatief klein, en deze SHD's, die transparant zijn voor onze afgevende logica, dat wil zeggen voor onze nginx of iemand anders, verwerken aanvragen voor deze foto's.

Deze oplossing had duidelijke voordelen. Dit is een SHD. Het is gericht op het opslaan van foto's. Het is goedkoper dan het simpelweg opzetten van machines met harde schijven.

Een tweede voordeel.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dit is dat de capaciteit veel groter is geworden, dat wil zeggen dat we in een veel kleinere ruimte veel meer opslag kunnen plaatsen.

Maar er waren ook nadelen, die snel aan het licht kwamen. Met de groei van het aantal gebruikers en de belasting op dit systeem begonnen er prestatieproblemen op te duiken. En het probleem is vrij duidelijk — elke SHD die is ontworpen om veel foto's in een kleine ruimte op te slaan, heeft doorgaans last van intensief lezen. Dit is in feite ook relevant voor elke cloudopslag en wat dan ook. Op dit moment bestaat er geen ideale opslag die oneindig schaalbaar is, waarin je alles kunt stoppen en die heel goed om kan gaan met lezen. Vooral met willekeurig lezen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Net als in het geval van onze foto's, omdat foto's niet-sequentieel worden opgevraagd, en dit heeft een grote impact op hun prestaties.

Zelfs met de cijfers van vandaag, als we ergens meer dan 500 RPS voor foto's per machine, waar de opslag op is aangesloten, beginnen er al problemen op te duiken. En dat was behoorlijk slecht voor ons, omdat het aantal gebruikers groeit, en alles alleen maar slechter moet worden. We moeten dit op de een of andere manier optimaliseren.

Om te optimaliseren, besloten we toen, dat we duidelijk naar het belastingprofiel moesten kijken - wat er eigenlijk gebeurt, wat we moeten optimaliseren.

Architectuur voor het opslaan en delen van foto's in Badoo.

En hier speelt alles in ons voordeel.

Ik zei het al in de eerste dia: we hebben 80.000 leesaanvragen per seconde bij slechts 3,5 miljoen uploads per dag. Dat is een verschil van drie ordegrootten. Het is duidelijk dat we het lezen moeten optimaliseren en het is vrijwel duidelijk hoe.

Er is nog één klein punt. De specificiteit van de service is zo dat een persoon zich registreert, een foto uploadt, en vervolgens actief andere mensen bekijkt, hen leuk vindt, en hij/zij actief aan anderen wordt getoond. Daarna vindt hij/zij een paar of niet, dat hangt er vanaf, en stopt op een gegeven moment met het gebruik van de service. Op dat moment, wanneer hij/zij actief is, zijn de foto's heel gewild — ze worden door veel mensen bekeken. Zodra hij/zij ermee stopt, valt hij/zij vrij snel uit de intensieve weergave aan anderen, zoals eerder, en worden zijn/haar foto's praktisch niet meer opgevraagd.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dat wil zeggen, we hebben een heel kleine hot dataset. Maar er zijn wel veel aanvragen voor. En het is heel duidelijk dat hier de oplossing voor is om caching toe te voegen.

Caching met LRU zal al onze problemen oplossen. Wat doen we?

Architectuur voor het opslaan en delen van foto's in Badoo.

We voegen vóór onze grote cluster met opslag nog een relatief kleine toe, die we foto-caches (photoscache) noemen. Dit is in feite gewoon een caching proxy.

Hoe werkt dit intern? Hier is onze gebruiker, hier is de opslag. Alles zoals voorheen. Wat voegen we daartussen toe?

Architectuur voor het opslaan en delen van foto's in Badoo.

Dit is gewoon een machine met een fysieke lokale schijf die snel is. Dit is bijvoorbeeld een SSD. En op deze schijf wordt een soort lokale cache opgeslagen.

Hoe ziet dit eruit? De gebruiker stuurt een verzoek om een foto. NGINX zoekt deze eerst in de lokale cache. Als deze daar niet is, maakt het gewoon een proxy_pass naar onze opslag, downloadt de foto daarvandaan en geeft deze aan de gebruiker.

Maar dit is heel eenvoudig en onduidelijk wat er binnenin gebeurt. Het werkt ongeveer zo.

Architectuur voor het opslaan en delen van foto's in Badoo.

De cache is logisch verdeeld in drie lagen. Wanneer ik zeg 'drie lagen', betekent dat niet dat er een ingewikkeld systeem is. Nee, dit zijn voor het gemak gewoon drie mappen in het bestandssysteem:

  1. Dit is de buffer waar net uit de proxy geüploade foto's binnenkomen.
  2. Dit is de hot cache, waarin momenteel actief opgevraagde foto's worden opgeslagen.
  3. En de cold cache, waar foto's geleidelijk uit de hot cache worden geduwd wanneer er minder aanvragen voor zijn.

Om dit te laten werken, moeten we deze cache op een of andere manier beheren, we moeten foto's erin verplaatsen, enzovoorts. Dit is ook een heel primitief proces.

Architectuur voor het opslaan en delen van foto's in Badoo.

Nginx schrijft gewoon voor elke aanvraag naar de RAMDisk access.log, waarin het het pad naar de foto opgeeft die het momenteel bedient (natuurlijk een relatieve pad), en welke sectie het heeft bediend. Dat wil zeggen, het kan 'foto 1' zijn en verder of een buffer, of een warme cache, of een koude cache, of proxy.

Afhankelijk hiervan moeten we een beslissing nemen over wat te doen met de foto.

Op elke machine draait een kleine daemon die constant deze log leest en in zijn geheugen statistieken bijhoudt over het gebruik van bepaalde foto's.

Architectuur voor het opslaan en delen van foto's in Badoo.

Het verzamelt eenvoudig gegevens, houdt tellingen bij en doet periodiek het volgende. Actief opgevraagde foto's, waarvoor veel aanvragen komen, verplaatst hij naar de warme cache, ongeacht waar ze zich bevinden.

Architectuur voor het opslaan en delen van foto's in Badoo.

Foto's die zelden worden aangevraagd en die nog minder vaak worden aangevraagd, duwt hij geleidelijk uit de warme cache naar de koude cache.

Architectuur voor het opslaan en delen van foto's in Badoo.

En wanneer we geen ruimte meer in de cache hebben, beginnen we simpelweg alles uit de koude cache willekeurig te verwijderen. En dat werkt trouwens goed.

Om ervoor te zorgen dat de foto onmiddellijk wordt opgeslagen tijdens het proxy'en in de buffer, gebruiken we de proxy_store-directive en de buffer — dat is ook een RAMDisk, dus voor de gebruiker werkt het heel snel. Dat betreft de interne werking van de cache-server zelf.

Er blijft de vraag over hoe we aanvragen over deze servers moeten verdelen.

Stel, er is een cluster van twintig opslagmachines en drie caching-servers (zo is het toevallig gekomen).

Architectuur voor het opslaan en delen van foto's in Badoo.

We moeten op een bepaalde manier bepalen welke aanvragen voor welke foto's zijn en waar ze moeten landen.

De meest voor de hand liggende optie is Round Robin. Of moeten we het willekeurig doen?

Dit heeft blijkbaar een aantal nadelen, omdat we de cache in zo'n situatie erg inefficiënt zullen gebruiken. Aanvragen zullen op willekeurige machines terechtkomen: hier is het gecached, naastliggende is het al niet meer. En dit zal, zelfs met een klein aantal machines in het cluster, erg slecht functioneren.

We moeten op een bepaalde manier eenduidig bepalen op welke server elke aanvraag moet landen.

Er is een eenvoudige manier. We nemen de hash van de URL of de hash van onze sharding-sleutel die in de URL staat, en delen deze geheel door het aantal servers. Zal het werken? Ja, dat zal het.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dat wil zeggen, dat we een honderd procent request hebben, bijvoorbeeld voor een bepaalde «example_url» die altijd op de server met index «2» terechtkomt, en de cache wordt voortdurend zo efficiënt mogelijk benut.

Maar er ontstaat een probleem met herscharding in dit schema. Herscharding — ik bedoel daarmee het veranderen van het aantal servers.

Stel dat onze cache-cluster het niet meer aankan en we besluiten om een extra machine toe te voegen.

We voegen toe.

Architectuur voor het opslaan en delen van foto's in Badoo.

Nu delen we alles niet meer door drie, maar door vier. Hierdoor leven praktisch alle sleutels die we eerder hadden, bijna alle URL's nu op andere servers. De hele cache werd in één keer ongeldig. Alle requests kwamen ineens op onze cluster-storage en het ging hem slecht, service-uitval en ontevreden gebruikers. Dat willen we niet.

Deze optie is voor ons ook niet geschikt.

Dus wat moeten we doen? We moeten op de een of andere manier de cache efficiënt gebruiken, constant één request op dezelfde server laten landen, maar tegelijkertijd bestand zijn tegen herscharding. En er is een oplossing voor, het is niet zo moeilijk. Het heet consistent hashing.

Architectuur voor het opslaan en delen van foto's in Badoo.

Hoe ziet dat eruit?

Architectuur voor het opslaan en delen van foto's in Badoo.

We nemen een functie van de sharding-sleutel en verspreiden al zijn waarden over een cirkel. Dat wil zeggen, op punt 0 komen de minimale en maximale waarden samen. Vervolgens plaatsen we al onze servers op dezelfde cirkel ongeveer op de volgende manier:

Architectuur voor het opslaan en delen van foto's in Badoo.

Elke server wordt bepaald door één punt, en de sector die met de klok mee ernaartoe gaat, wordt natuurlijk bediend door deze host. Wanneer we requests ontvangen, zien we meteen dat, bijvoorbeeld, request A — het heeft die hash — en wordt bediend door server 2. Request B — door server 3. En zo verder.

Architectuur voor het opslaan en delen van foto's in Badoo.

Wat gebeurt er in deze situatie bij herscharding?

Architectuur voor het opslaan en delen van foto's in Badoo.

We maken niet de hele cache ongeldig, zoals voorheen, en verschuiven niet alle sleutels, maar we verschuiven elke sector een kleine afstand zodat het vacante stuk, bij wijze van spreken, onze zesde server, die we willen toevoegen, kan herbergen, en voegen deze daar toe.

Architectuur voor het opslaan en delen van foto's in Badoo.

Natuurlijk, in zo'n situatie verdwijnen de sleutels ook. Maar ze verdwijnen veel minder dan voorheen. We zien dat onze eerste twee sleutels op hun servers zijn gebleven, terwijl de cache-server alleen voor de laatste sleutel is veranderd. Dit werkt behoorlijk effectief, en als je nieuwe hosts geleidelijk toevoegt, is er geen groot probleem. Je voegt beetje bij beetje toe, wacht tot de cache weer vol is, en alles werkt goed.

De enige vraag blijft bij storingen. Stel je voor dat een van onze machines defect is gegaan.

Architectuur voor het opslaan en delen van foto's in Badoo.

En we willen op dat moment niet de kaart opnieuw genereren, een deel van de cache ongeldig maken, enzovoort, als bijvoorbeeld de machine opnieuw opgestart is, maar we moeten die aanvragen op een of andere manier bedienen. We houden gewoon één reservefoto-cache op elke site, die fungeert als vervanging voor elke machine die momenteel defect is. En als er plotseling een server onbereikbaar wordt, gaat het verkeer daarheen. We hebben daar natuurlijk geen cache, dus deze is koud, maar in ieder geval worden de gebruikersverzoeken verwerkt. Als dit een korte periode is, dan kunnen we dit zonder problemen doorstaan. Het zorgt alleen voor een hogere belasting op de opslag. Als het een lange periode is, dan kunnen we al een beslissing nemen — deze server uit de kaart verwijderen of niet, of misschien vervangen door een andere.

Dit betreft het cachesysteem. Laten we naar de resultaten kijken.

Het lijkt misschien niet zo moeilijk. Maar deze manier van cachebeheer heeft ons een hitrate van ongeveer 98% opgeleverd. Dat wil zeggen, van de 80.000 verzoeken per seconde komt slechts 1.600 bij de opslag aan, en dat is een volkomen normale belasting, die ze zonder probleem kunnen verwerken, we hebben altijd een reserve.

We hebben deze servers verspreid over drie van onze datacentra, en kregen drie punten van aanwezigheid — Praag, Miami en Hongkong.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dus ze zijn min of meer lokaal gelegen ten opzichte van elk van onze doelmarkten.

En als een aangename bonus hebben we deze cacheproxy, waar de CPU in feite inactief is, omdat deze niet zo nodig is voor het leveren van content. En daar hebben we met behulp van NGINX+ Lua veel nuttige logica geïmplementeerd.

Architectuur voor het opslaan en delen van foto's in Badoo.

Bijvoorbeeld, we kunnen experimenteren met webp of progressive jpeg (dit zijn moderne, efficiënte formaten), kijken hoe dit de traffic beïnvloedt, bepaalde beslissingen nemen, het inschakelen voor specifieke landen, enzovoort; dynamisch foto's resizing of cropen on-the-fly.

Dit is een goede use case, wanneer je bijvoorbeeld een mobiele applicatie hebt die foto's toont, en de mobiele applicatie wil geen CPU van de client gebruiken om een grote foto op te vragen en deze vervolgens tot een bepaalde grootte te resizing zodat deze in de view past. We kunnen simpelweg dynamisch bepaalde parameters in de URL van UPort opgeven, en de fotokas zal de foto zelf resizing. Meestal kiest het de grootte die we fysiek op de schijf hebben, zo dicht mogelijk bij wat is opgevraagd, en downgraden in de specifieke coördinaten.

Overigens hebben we de videoregistraties van de afgelopen vijf jaar van de ontwikkelaarsconferentie over high-load systemen openbaar gemaakt. HighLoad++. Kijk, bestudeer, deel en abonneer je op de YouTube-kanaal..

Ook kunnen we daar veel productlogica aan toevoegen. Bijvoorbeeld, we kunnen verschillende watermark's toevoegen op basis van URL-parameters, foto's vervagen, onscherp maken of pixeleren. Dit is wanneer we een foto van een persoon willen tonen, maar niet hun gezicht willen laten zien, dit werkt goed, en dit is hier gerealiseerd.

Wat hebben we gekregen? We hebben drie punten van aanwezigheid, een goede hit-rate, en ondertussen blijft de CPU van deze machines niet idle. Het is nu natuurlijk belangrijker geworden dan voorheen. We moeten krachtigere machines voor onszelf installeren, maar het is het waard.

Dit betreft het afleveren van foto's. Hier is alles vrij duidelijk en voor de hand liggend. Ik denk niet dat ik Amerika heb ontdekt; zo werkt praktisch elke CDN.

En waarschijnlijk heeft de doorgewinterde luisteraar de vraag gesteld: waarom niet gewoon alles overzetten naar een CDN? Het zou ongeveer hetzelfde zijn, alle moderne CDNs kunnen dit. En hier zijn verschillende redenen.

De eerste is de foto's.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dit is een van de sleutelpunten van onze infrastructuur, en we moeten zoveel mogelijk controle erover hebben. Als het een oplossing van een externe aanbieder is, en je hebt daar geen controle over, zal het vrij moeilijk zijn om te leven met een grote dataset, en wanneer je een zeer grote stroom gebruikersverzoeken hebt.

Ik geef een voorbeeld. Op dit moment kunnen we, bijvoorbeeld bij problemen of ondergrondse geluiden, op de machine in onze infrastructuur inloggen en daar debuggen, om het zo te zeggen. We kunnen gegevensverzameling toevoegen van specifieke metrics die we nodig hebben, experimenteren en kijken hoe dit de grafieken beïnvloedt, enzovoorts. We verzamelen momenteel veel statistieken over dit caching-cluster. Periodiek bekijken we deze gegevens en onderzoeken we lange tijd anomalieën. Als dit aan de CDN-zijde zou plaatsvinden, zou het veel moeilijker zijn om te controleren. Of bijvoorbeeld, als er een ongeluk gebeurt, weten we wat er aan de hand is, weten we hoe we ermee om moeten gaan en hoe we het kunnen oplossen. Dit is de eerste conclusie.

De tweede conclusie is ook meer historisch van aard, omdat het systeem al lange tijd zich ontwikkelt en er veel verschillende zakelijke eisen op verschillende momenten zijn geweest, die vaak niet passen binnen het concept van een CDN.

En het punt dat hieruit voortvloeit –

Architectuur voor het opslaan en delen van foto's in Badoo.

Op onze fotokasten hebben we veel specifieke logica, die niet altijd kan worden toegevoegd op verzoek. Het is onwaarschijnlijk dat een enkele CDN op uw verzoek bepaalde maatwerk zaken zal toevoegen. Bijvoorbeeld, URL-encryptie als u niet wilt dat de klant iets kan wijzigen. U wilt de URL op de server wijzigen en deze versleutelen en vervolgens bepaalde dynamische parameters teruggeven.

Welke conclusie dringt zich op? In ons geval is de CDN geen goede optie.

Architectuur voor het opslaan en delen van foto's in Badoo.

Maar in uw geval, als u specifieke zakelijke vereisten heeft, kunt u zelf rustig implementeren wat ik u heb laten zien. En dit zal uitstekend werken met een vergelijkbaar belastingprofiel.

Maar als u een algemene oplossing heeft en de taak niet al te specifiek is, kunt u zonder problemen een CDN gebruiken. Of als tijd en middelen voor u veel belangrijker zijn dan controle.

Architectuur voor het opslaan en delen van foto's in Badoo.

Moderne CDN's bieden vrijwel alles wat ik u nu heb verteld, met uitzondering van enkele functies.

Dit betreft het afleveren van foto's.

Laten we nu een beetje vooruitgaan in onze retrospectieve en het hebben over opslag.

Het jaar 2013 verliep.

Architectuur voor het opslaan en delen van foto's in Badoo.

Cache-servers zijn toegevoegd, problemen met de prestaties zijn verdwenen. Alles is goed. De dataset groeit. In 2013 hadden we ongeveer 80 servers die zijn aangesloten op opslagsystemen, en ongeveer 40 cache-servers in elk datacenter. Dit betekent ongeveer 560 terabyte aan gegevens per datacenter, oftewel ongeveer een petabyte in totaal.

Architectuur voor het opslaan en delen van foto's in Badoo.

En met de groei van de dataset zijn de operationele kosten sterk gestegen. Hoe heeft zich dat uitgedrukt?

Architectuur voor het opslaan en delen van foto's in Badoo.

In dit schema, dat is getekend - met de SAN, de aan deze aangesloten machines en caches - zijn er veel punten van uitval. Als we eerder al omgingen met de uitval van cache-servers, waar het meer of minder voorspelbaar en begrijpelijk was, was dat aan de opslagkant veel slechter.

Allereerst kan het Storage Area Network (SAN) zelf uitvallen.

Ten tweede is het aangesloten via glasvezel op de eindmachines. Er kunnen problemen zijn met de optische kaarten of switches.

Architectuur voor het opslaan en delen van foto's in Badoo.

Er zijn natuurlijk niet zoveel problemen als met het SAN zelf, maar dit zijn ook punten van uitval.

Vervolgens de machine zelf, die is aangesloten op de opslag. Deze kan ook defect raken.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dus in totaal hebben we drie punten van uitval.

Daarnaast, naast de punten van uitval, is het zware onderhoud van de opslag zelf.

Het is een complexe multicomponentensysteem, en systeemingenieurs hebben het er soms moeilijk mee.

En het laatste, en misschien wel het belangrijkste punt. Als er op een van deze drie punten een uitval optreedt, is de kans dat we gebruikersgegevens verliezen niet nul, omdat het bestandssysteem beschadigd kan raken.

Architectuur voor het opslaan en delen van foto's in Badoo.

Stel dat ons bestandssysteem is beschadigd. Het herstel ervan duurt, ten eerste, lang - dit kan een week duren bij een grote hoeveelheid gegevens. En ten tweede zullen we waarschijnlijk een hoop onbegrijpelijke bestanden hebben die we op de een of andere manier moeten koppelen aan de foto’s van de gebruikers. We lopen het risico gegevens te verliezen. Het risico is behoorlijk groot. En hoe vaker zulke situaties zich voordoen, en hoe meer problemen er in de hele keten ontstaan, des te hoger dat risico.

Hier moesten we iets aan doen. En we besloten dat we gewoon de gegevens moesten back-uppen. Dit is in feite een voor de hand liggende en goede oplossing. Wat hebben we gedaan?

Architectuur voor het opslaan en delen van foto's in Badoo.

Zo zag onze server eruit, die eerder op de opslag was aangesloten. Dit is één primaire partitie, dit is gewoon een blokapparaat dat in feite een mount op de externe opslag via glasvezel vertegenwoordigt.

We hebben gewoon een tweede partitie toegevoegd.

Architectuur voor het opslaan en delen van foto's in Badoo.

We placed a second storage unit nearby (thankfully, it wasn't too expensive), and we named it the backup section. It is also connected via fiber optic, located on the same machine. However, we need to synchronize the data between them in some way.

Here we simply create an asynchronous queue alongside.

Architectuur voor het opslaan en delen van foto's in Badoo.

It isn't very busy. We know that we have few entries. The queue is just a table in MySQL, where lines like "we need to back up this photo" are written. Whenever there is a change or an upload, we copy from the main section to the backup asynchronously or using some background worker.

This way, we always have two consistent sections. Even if one part of this system fails, we can always switch the main section with the backup, and everything continues to work.

However, this significantly increases the load on reading, as besides the clients who read from the main section (because they first look at the photo there, since it is more up to date), and then look for it on the backup if they can't find it (but NGINX does this), our backup system is also reading from the main section. It's not necessarily a bottleneck, but we did not want to increase the load unnecessarily.

So we added a third disk, which is a small SSD, and we called it the buffer.

Architectuur voor het opslaan en delen van foto's in Badoo.

Here's how it works now.

The user uploads a photo to the buffer, and then an event is triggered in the queue to copy it to both sections. It gets copied, and the photo lives on the buffer for some time (say, a day) before it gets purged. This greatly improves user experience because once the user uploads a photo, requests for it usually start coming in immediately, or they refresh the page right away. But this all depends on the application performing the upload.

Or, for example, other people who start to see it immediately send requests for that photo. It's not in the cache yet, so the first request happens very quickly. Essentially, it's similar to photo caching. The slow storage is not involved at all in this. When it gets purged after a day, it is either already cached in our caching layer, or it is likely no longer needed. Thus, user experience has significantly improved due to these simple manipulations.

Well, most importantly, we've stopped losing data.

Architectuur voor het opslaan en delen van foto's in Badoo.

Let's say we've stopped. potentieel Gegevens verliezen, omdat we ze eigenlijk niet verloren zijn. Maar het gevaar was er. We zien dat zo'n oplossing natuurlijk goed is, maar het lijkt een beetje op het verdoezelen van de symptomen van het probleem, in plaats van het echt op te lossen. Er zijn nog steeds enkele problemen.

Ten eerste is er het punt van falen in de vorm van de fysieke host zelf, waarop al deze machines draaien, dat is er nog steeds.

Architectuur voor het opslaan en delen van foto's in Badoo.

Ten tweede zijn er nog problemen met SAN's, hun zware onderhoud, enzovoorts. Het was niet echt een kritische factor, maar we wilden proberen zonder dit te leven.

En we hebben een derde versie gemaakt (in feite de tweede) — de back-upversie. Hoe zag dat eruit?

Dit is wat het was —

Architectuur voor het opslaan en delen van foto's in Badoo.

Onze belangrijkste problemen waren dat dit een fysieke host was.

Ten eerste verwijderen we de SAN's, omdat we willen experimenteren, we willen gewoon lokale harde schijven uitproberen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dit is al het jaar 2014-2015, en op dat moment was de situatie met de schijven en hun capaciteit in één host veel beter geworden. We besloten, waarom niet proberen.

Vervolgens nemen we gewoon onze back-uppartitie en verplaatsen deze fysiek naar een aparte machine.

Architectuur voor het opslaan en delen van foto's in Badoo.

Zo krijgen we dit schema. We hebben twee machines die dezelfde datasets opslaan. Ze back-uppen elkaar volledig en synchroniseren gegevens via het netwerk via een asynchrone queue binnen dezelfde MySQL.

Architectuur voor het opslaan en delen van foto's in Badoo.

Waarom dit goed werkt — omdat we weinig schrijfacties hebben. Dat wil zeggen, als het schrijven vergelijkbaar zou zijn met het lezen, zouden we misschien enige netwerkoverhead en problemen ervaren. We hebben weinig schrijfacties, veel leesacties — deze aanpak werkt goed, dat wil zeggen, we kopiëren foto's vrij zelden tussen deze twee servers.

Hoe dit werkt, als we er wat meer op inzoomen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Upload. De load balancer kiest gewoon willekeurige hosts met een paar en maakt daar de upload naartoe. Uiteraard doet hij health checks en controleert of de machine niet is uitgevallen. Dat wil zeggen, hij uploadt foto's alleen naar een actieve server, en dan wordt alles via een asynchrone queue naar de buurman gekopieerd. Met de upload is het heel eenvoudig.

Met de taak is het iets complexer.

Architectuur voor het opslaan en delen van foto's in Badoo.

Hier hielp Lua ons, omdat het moeilijk kan zijn om dergelijke logica met een standaard NGINX te implementeren. We doen eerst een aanvraag naar de eerste server en kijken of er een foto daar is, omdat deze mogelijk al op de buren is geüpload en nog niet hier is aangekomen. Als de foto er is, is dat goed. We geven deze onmiddellijk aan de klant en eventueel cachen we deze.

Architectuur voor het opslaan en delen van foto's in Badoo.

Als deze er niet is, doen we eenvoudig een aanvraag naar de buren en krijgen we deze gegarandeerd daar vandaan.

Architectuur voor het opslaan en delen van foto's in Badoo.

Dus kunnen we weer zeggen: er kunnen prestatieproblemen zijn, omdat constante round trips — als de foto is geüpload, maar hier niet is — twee aanvragen in plaats van één vereisen, wat traag zou moeten werken.

In onze situatie werkt dit niet traag.

Architectuur voor het opslaan en delen van foto's in Badoo.

We verzamelen een hoop metrics over dit systeem, en de hypothese van dit mechanisme bedraagt ongeveer 95%. Dat betekent dat de vertraging van deze back-up klein is, en hierdoor kunnen we praktisch gegarandeerd, nadat de foto is geüpload, deze meteen de eerste keer ophalen zonder twee keer te hoeven vragen.

Wat hebben we nog meer gekregen, en dat is heel gaaf?

Eerder hadden we een hoofdmappen voor backups, en we lazen daar sequentially van. Dat wil zeggen, we zochten altijd eerst op de hoofdserver, en daarna op de back-up. Dat was één stap.

Nu benutten we het lezen van twee machines tegelijk. We verdelen aanvragen met een Round Robin. In een klein percentage van de gevallen doen we twee aanvragen. Maar in het algemeen hebben we nu twee keer zoveel leescapaciteit als voorheen. En de belasting is aanzienlijk verminderd, zowel op de afgevende machines als op de opslagmachines die we op dat moment ook hadden.

Wat betreft failover. Eigenlijk hiervoor hebben we voornamelijk gestreden. Wat betreft fouttolerantie is het hier geweldig verlopen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Eén machine valt uit.

Architectuur voor het opslaan en delen van foto's in Badoo.

Geen probleem! De systeemingenieur hoeft zelfs niet 's nachts wakker te worden, hij kan tot de ochtend wachten, er is niets ernstigs aan de hand.

Zelfs als de wachtrij uitvalt bij deze machine, ook geen probleem, de log zal eerst op de actieve machine worden opgeslagen en daarna zal hij naar de wachtrij gaan, en vervolgens naar die machine die na een tijd weer in gebruik komt.

Architectuur voor het opslaan en delen van foto's in Badoo.

Hetzelfde geldt voor onderhoud. We schakelen gewoon een van de machines uit, halen deze handmatig uit alle pools, er komt geen verkeer meer binnen, we voeren een vorm van onderhoud uit, passen iets aan, en daarna zetten we hem weer in bedrijf. Deze backup haalt het snel genoeg in. Dat wil zeggen, de downtime van één machine wordt binnen een paar minuten ingehaald. Dat is echt heel weinig. Wat betreft de fouttolerantie, nogmaals, hier gaat alles geweldig.

Welke conclusies kunnen we trekken uit dit schema met back-up?

We hebben fouttolerantie behaald.

Eenvoudige exploitatie. Aangezien de machines lokale harde schijven hebben, is dit veel handiger voor de ingenieurs die ermee werken.

We hebben een dubbele marge voor lezen.

Dat is een zeer goede bonus bovenop de fouttolerantie.

Maar er zijn ook problemen. Nu is de ontwikkeling van bepaalde functies veel complexer, omdat het systeem nu 100% eventually consistent is.

Architectuur voor het opslaan en delen van foto's in Badoo.

We moeten bijvoorbeeld in een achtergrondtaak constant nadenken: "Op welke server draaien we nu?" en "Is er hier wel een actuele foto?" Dit is natuurlijk allemaal verpakt in wrappers, en voor de programmeur die de businesslogica schrijft, is het transparant. Maar niettemin is er een grote, complexe laag bijgekomen. Maar we zijn bereid hiermee te leven in ruil voor de voordelen die we ervoor hebben gekregen.

En hier ontstaat opnieuw een conflict.

In eerste instantie zei ik dat alles op lokale harde schijven opslaan slecht is. En nu zeg ik dat we het leuk vinden.

Ja, inderdaad, de situatie is in de loop van de tijd sterk veranderd, en nu heeft deze aanpak veel voordelen. Ten eerste krijgen we een veel eenvoudigere exploitatie.

Ten tweede is het efficiënter, omdat we geen automatische controllers hebben voor de verbinding met de schijfopslagsystemen.

Daar is enorme machinebouw, maar dit zijn gewoon een paar schijven die specifiek hier in de machine in een RAID zijn samengesteld.

Maar er zijn ook nadelen.

Architectuur voor het opslaan en delen van foto's in Badoo.

Het is ongeveer 1,5 keer duurder dan het gebruik van SAN's, zelfs tegen de huidige prijzen. Daarom hebben we besloten ons grote cluster niet zomaar te converteren naar machines met lokale harde schijven en hebben we besloten om een hybride oplossing aan te houden.

Ongeveer de helft van onze machines werkt met harde schijven (nou, niet de helft – ongeveer 30 procent denk ik). De overige machines zijn oude systemen waarop eerder het eerste back-up schema draaide. We hebben ze gewoon opnieuw gemonteerd, omdat we geen nieuwe gegevens nodig hebben of iets dergelijks; we hebben simpelweg de mounts van één fysieke host naar twee verplaatst.

En we hebben een grote leescapaciteit, en we hebben geschaald. Waar we voorheen één opslag op één machine monteerden, monteren we nu op één paar vier, bijvoorbeeld. En dat werkt prima.

Laten we een korte samenvatting geven van wat we hebben bereikt, waar we voor hebben gestreden, en of we dat ook daadwerkelijk hebben bereikt.

Conclusies

We hebben gebruikers - maar liefst 33 miljoen.

We hebben drie aanwezigheidspunten - Praag, Miami, Hong Kong.

Daar is een cache-laag geplaatst, bestaande uit machines met snelle lokale schijven (SSD), waar een eenvoudige opstelling van NGINX draait, evenals zijn access.log en Python-daemons die alles verwerken en het cachebeheer uitvoeren.

Als je wilt, kun je in jouw project, als foto's voor jou niet zo cruciaal zijn als voor ons, of als je trade-off controle versus ontwikkelsnelheid en middelen in een andere richting gaat, het gewoon vervangen door een CDN; moderne CDN's doen dat goed.

Daarna komt de opslaglaag, waarop we clusters van paren machines hebben die elkaar back-uppen en asynchroon bestanden van de een naar de ander kopiëren bij elke wijziging.

Een deel van deze machines werkt met lokale harde schijven.

Een deel van deze machines is aangesloten op SAN's.

Architectuur voor het opslaan en delen van foto's in Badoo.

En aan de ene kant is dit handiger in gebruik en iets efficiënter, maar aan de andere kant is het handig qua dichtheid en prijs per gigabyte.

Dit is een kort overzicht van de architectuur van wat we hebben behaald en hoe dit allemaal is ontwikkeld.

Nog een paar eenvoudige tips van de chief.

Ten eerste, als je besluit dat je alles snel moet verbeteren in je fotoinfrastructuur, meet dan eerst, want misschien is er niets dat verbeterd moet worden.

Architectuur voor het opslaan en delen van foto's in Badoo.

Ik geef een voorbeeld. We hebben een cluster van machines dat foto's levert uit bijlagen in chats, en daar draait nog steeds het schema van 2009, en niemand heeft daar last van. Iedereen is tevreden, iedereen vindt het goed.

Om te meten, hang eerst een aantal metrics op, kijk ernaar en beslis dan wat je niet tevreden maakt en wat verbeterd moet worden. Voor deze metingen hebben we een geweldige tool die Pinba heet.

Het stelt je in staat om zeer gedetailleerde statistieken van NGINX te verzamelen voor elke aanvraag, inclusief responscodes en tijdsverdelingen — alles wat je maar wilt. Het heeft bindings naar verschillende analytische systemen, zodat je dit later mooi kunt bekijken.

Eerst gemeten — dan verbeterd.

Vervolg. We optimaliseren lezen met caching, schrijven met sharding, maar dit is een voor de hand liggend punt.

Architectuur voor het opslaan en delen van foto's in Badoo.

Vervolg. Als je net begint met het bouwen van je systeem, is het veel beter om foto's als immutabele bestanden op te slaan. Hierdoor vermijd je meteen een hele klasse problemen met cache-invalidatie, hoe de logica de juiste versie van de foto moet vinden, enzovoort.

Architectuur voor het opslaan en delen van foto's in Badoo.

Stel je hebt een foto geüpload, deze gedraaid, zorg ervoor dat het een fysiek ander bestand is. Dus denk niet: ik bespaar nu een beetje ruimte door dezelfde bestand te bewerken en de versie te veranderen. Dit werkt altijd slecht en zorgt later voor veel hoofdpijn.

Volgende punt. Resize on the fly.

Vroeger, toen gebruikers een foto uploaden, sneden we meteen heel veel verschillende formaten voor alle gevallen, voor verschillende klanten, en die lagen allemaal op de schijf. Nu hebben we dit afgeschaft.

We hebben alleen drie basisformaten behouden: klein, medium en groot. Al het andere downsizeten we gewoon vanuit de maat die is aangevraagd in Uport, we downsizen en geven het aan de gebruiker terug.

CPU van de cache-laag is hier veel goedkoper dan wanneer we deze formaten constant opnieuw zouden genereren op elke opslag. Stel dat we een nieuw formaat willen toevoegen, dit kost een maand — we moeten overal een script draaien dat dit netjes doet, zonder het cluster te laten crashen. Dus als er nu een keuze is, is het beter om zo min mogelijk fysieke maten te maken, maar ervoor te zorgen dat er ten minste enige spreiding is, zeg drie. En al het andere gewoon on-the-fly resizen met behulp van kant-en-klare modules. Dit is nu allemaal heel eenvoudig en toegankelijk.

En incrementele asynchrone backups zijn goed.

Onze ervaring heeft aangetoond dat zo'n schema uitstekend werkt met uitgestelde kopieën van gewijzigde bestanden.

Architectuur voor het opslaan en delen van foto's in Badoo.

Het laatste punt is ook voor de hand liggend. Als er momenteel geen problemen in uw infrastructuur zijn, maar er is iets dat kan falen, dan zal het zeker falen wanneer de belasting iets toeneemt. Het is daarom beter om hier van tevoren over na te denken en problemen te vermijden. Dat is alles.

Contacten

» bo0rsh201
» Blog van Badoo

Deze presentatie is een transcriptie van een van de beste lezingen op de conferentie voor ontwikkelaars van hoogbelaste systemen HighLoad++. Voor de HighLoad++ 2017-conferentie is er minder dan een maand over.

We zijn al klaar Programma van de conferentie, en het schema wordt momenteel actief opgesteld.

Dit jaar blijven we het onderwerp architecturen en schaalbaarheid onderzoeken:

Ook worden sommige van deze materialen door ons gebruikt in de online cursus over de ontwikkeling van hoogbelaste systemen HighLoad.Gids is een reeks speciaal samengestelde brieven, artikelen, materialen en video's. Onze leeromgeving bevat nu al meer dan 30 unieke materialen. Sluit je aan!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster