{"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\/ro\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","title":{"rendered":"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een 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 este cea mai mare platform\u0103 de \u00eent\u00e2lniri din lume. \u00cen prezent, avem aproximativ 330 de milioane de utilizatori \u00een \u00eentreaga lume. Dar, ceea ce este mult mai important \u00een contextul discu\u021biei noastre de ast\u0103zi, este faptul c\u0103 stoc\u0103m aproximativ 3 petabai de fotografii ale utilizatorilor. \u00cen fiecare zi, utilizatorii no\u0219tri \u00eencarc\u0103 aproximativ 3,5 milioane de fotografii noi, iar \u00eenc\u0103rc\u0103tura de citire este de aproximativ <b>80 de mii de cereri pe secund\u0103<\/b>. Asta este destul de mult pentru backend-ul nostru, iar uneori au fost dificult\u0103\u021bi \u00een gestionarea acesteia.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4e4690f9b0d95bd76fbbc1cd6805c26c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVoi vorbi despre designul acestui sistem, care stocheaz\u0103 \u0219i livrez fotografiile \u00een general, \u0219i voi oferi o privire asupra lui din perspectiva unui dezvoltator. Despre cum a evoluat, va exista o retrospectiv\u0103 scurt\u0103, unde voi marca principalele etape, dar voi discuta mai \u00een detaliu doar despre solu\u021biile pe care le utiliz\u0103m acum.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n\u0218i acum s\u0103 \u00eencepem.<\/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=\"Reda\u021bi video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nA\u0219a cum am spus deja, aceasta va fi o retrospectiv\u0103, iar pentru a \u00eencepe cu ceva, s\u0103 lu\u0103m cel mai banal exemplu.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/22b9627cda7ccadd9869b64e9d043d89.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAvem o sarcin\u0103 comun\u0103, trebuie s\u0103 primim, s\u0103 stoc\u0103m \u0219i s\u0103 livr\u0103m fotografiile utilizatorilor. \u00cen aceast\u0103 form\u0103, sarcina este general\u0103, putem folosi orice:<\/p>\n<ul>\n<li>stocare cloud modern\u0103,<\/li>\n<li>o solu\u021bie \u201ecutie\u201d, dintre care acum sunt foarte multe;<\/li>\n<li>putem seta c\u00e2teva ma\u0219ini \u00een centrul nostru de date \u0219i s\u0103 instal\u0103m pe ele discuri dure mari pentru a stoca fotografiile acolo.<\/li>\n<\/ul>\n<p>\nBadoo, istoric vorbind \u2014 \u0219i acum, \u0219i atunci (\u00een perioada \u00een care aceasta s-a n\u0103scut) \u2014 func\u021bioneaz\u0103 pe servere proprii, \u00een interiorul centrelor noastre de date. Prin urmare, pentru noi, aceast\u0103 op\u021biune a fost optim\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9434fbabada15670297c551066ad7e71.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAm luat pur \u0219i simplu c\u00e2teva ma\u0219ini, le-am numit \u201ephotos\u201d, iar noi am creat un cluster care stocheaz\u0103 fotografiile. Dar, pare c\u0103 ne lipse\u0219te ceva. Pentru ca toate acestea s\u0103 func\u021bioneze, trebuie s\u0103 determin\u0103m \u00eentr-un fel pe ce ma\u0219in\u0103 vom stoca ce fotografii. \u0218i aici nu trebuie s\u0103 descoperim America.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/36258e7107fd8c60f7e9e563a2cb681c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAd\u0103ug\u0103m \u00een stocarea noastr\u0103 cu informa\u021bii despre utilizatori un c\u00e2mp. Acesta va fi cheia shard-ului. \u00cen cazul nostru, l-am numit place_id, iar acest id al locurilor indic\u0103 locul \u00een care sunt stocate fotografiile utilizatorilor. Ne facem h\u0103r\u021bi.<\/p>\n<p>\u00cen prima etap\u0103, acest lucru se poate face chiar manual \u2014 spunem c\u0103 fotografia acestui utilizator cu un anumit loc va fi stocat\u0103 pe un anumit server. Datorit\u0103 acestei h\u0103r\u021bi, \u0219tim \u00eentotdeauna c\u00e2nd utilizatorul \u00eencarc\u0103 o fotografie, unde s\u0103 o salv\u0103m \u0219i \u0219tim de unde s\u0103 o livr\u0103m.<\/p>\n<p>Este o schem\u0103 absolut trivial\u0103, dar are suficiente avantaje semnificative. Primul \u2014 este simpl\u0103, cum am spus deja, iar al doilea \u2014 este c\u0103, cu aceast\u0103 abordare, putem scala orizontal cu u\u0219urin\u021b\u0103, pur \u0219i simplu livr\u00e2nd noi ma\u0219ini \u0219i ad\u0103ug\u00e2ndu-le pe hart\u0103. Nu este nevoie s\u0103 facem altceva.<\/p>\n<p>A\u0219a a fost pentru o vreme.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3effb442702f162f7bad9c18ec54392e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAsta s-a \u00eent\u00e2mplat undeva \u00een 2009. Livram ma\u0219ini, livram...<\/p>\n<p>\u0218i \u00eentr-un anumit moment am \u00eenceput s\u0103 observ\u0103m c\u0103 aceast\u0103 schem\u0103 are anumite dezavantaje. Ce dezavantaje?<\/p>\n<p>\u00cen primul r\u00e2nd, este capacitatea limitat\u0103. Pe un singur server fizic putem instala nu at\u00e2t de multe hard disk-uri pe c\u00e2t ne-am dori. Iar cu trecerea timpului \u0219i cre\u0219terea setului de date, aceasta a devenit o problem\u0103.<\/p>\n<p>\u0218i al doilea. Aceasta este o configura\u021bie atipic\u0103 a ma\u0219inilor, deoarece astfel de ma\u0219ini sunt greu de reutilizat \u00een alte clustere, sunt destul de specifice, adic\u0103 trebuie s\u0103 fie slabe din punct de vedere al performan\u021bei, dar totodat\u0103 cu un hard disk mare.<\/p>\n<p>Toate acestea erau valabile \u00een 2009, dar, \u00een principiu, aceste cerin\u021be sunt actuale \u0219i ast\u0103zi. Avem o retrospectiv\u0103, a\u0219a c\u0103 \u00een 2009 lucrurile erau destul de slabe \u00een aceast\u0103 privin\u021b\u0103.<\/p>\n<p>\u0218i ultimul punct \u2014 este pre\u021bul.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e49010eaeab139199d8fe010caa65bf0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPre\u021bul era atunci foarte ridicat, \u0219i trebuia s\u0103 c\u0103ut\u0103m alternative. Adic\u0103, trebuia s\u0103 ne gestion\u0103m mai bine spa\u021biul \u00een centrele de date \u0219i serverele fizice pe care era g\u0103zduit totul. Iar inginerii no\u0219tri de sistem au \u00eenceput o mare cercetare, \u00een care au revizuit o mul\u021bime de op\u021biuni diferite. Au analizat \u0219i sisteme de fi\u0219iere clusterizate, cum ar fi PolyCeph \u0219i Lustre. Au existat probleme de performan\u021b\u0103 \u0219i o utilizare destul de grea. Au renun\u021bat. Au \u00eencercat s\u0103 monteze \u00eentregul set de date prin NFS pe fiecare ma\u0219in\u0103, pentru a scalda astfel. Citirea a fost de asemenea slab\u0103, au \u00eencercat diverse solu\u021bii de la diferi\u021bi furnizori.<\/p>\n<p>\u0218i, \u00een final, ne-am oprit la ceea ce am \u00eenceput s\u0103 folosim cunoscuta re\u021bea de stocare.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e99402fa641f3bd5fc8d57a9f8995642.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcestea sunt SSD-uri mari, care sunt concepute pentru a stoca volume mari de date. Ele constau \u00een rafturi cu discuri, care sunt montate pe ma\u0219ini de livrare finale prin fibr\u0103 optic\u0103. Astfel, avem un mic grup de ma\u0219ini, iar aceste SSD-uri, care sunt transparente pentru logica noastr\u0103 de livrare, adic\u0103 pentru nginx-ul nostru sau altceva, r\u0103spund cererilor pentru aceste fotografii.<\/p>\n<p>Aceast\u0103 solu\u021bie a avut evident avantaje. Este un SSD. Este orientat pentru a stoca fotografii. Este mai ieftin dec\u00e2t atunci c\u00e2nd configur\u0103m pur \u0219i simplu ma\u0219ini cu hard disk-uri.<\/p>\n<p>Al doilea avantaj. <\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7fd2e7d629cc239096b14c68be5f76bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste faptul c\u0103 capacitatea a crescut semnificativ, adic\u0103 putem \u00eencorpora mult mai mult storage \u00eentr-un volum mult mai mic.<\/p>\n<p>Dar au existat \u0219i dezavantaje, care s-au manifestat destul de repede. Cu cre\u0219terea num\u0103rului de utilizatori \u0219i a \u00eenc\u0103rc\u0103rii asupra acestui sistem, au \u00eenceput s\u0103 apar\u0103 probleme de performan\u021b\u0103. Problema era destul de evident\u0103 \u2014 orice SSD, destinat s\u0103 stocheze multe fotografii \u00eentr-un volum mic, de obicei sufer\u0103 de solicit\u0103ri intense de citire. Acest lucru este de fapt valabil \u0219i pentru orice storage \u00een cloud, \u0219i pentru orice altceva. Acum nu exist\u0103 un storage perfect, care s\u0103 fie scalabil infinit, \u00een care s\u0103 po\u021bi introduce orice, \u0219i care s\u0103 suporte foarte bine citirile. \u00cen special citirile aleatoare.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/566e836e2fe13a2a3d040ae3fa865d6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa fel ca \u00een cazul fotografiilor noastre, pentru c\u0103 fotografiile sunt solicitate necorespunz\u0103tor, \u0219i acest lucru afecteaz\u0103 foarte mult performan\u021ba lor.<\/p>\n<p>Chiar \u0219i ast\u0103zi, dac\u0103 avem un volum mai mare de 500 de RPS pentru fotografii pe ma\u0219ina la care este conectat storage-ul, deja \u00eencep problemele. \u0218i acesta a fost destul de grav pentru noi, deoarece num\u0103rul utilizatorilor cre\u0219te, iar totul ar trebui s\u0103 devin\u0103 din ce \u00een ce mai r\u0103u. Trebuie s\u0103 optimiz\u0103m acest lucru cumva.<\/p>\n<p>Pentru a optimiza, am decis atunci, evident, s\u0103 ne uit\u0103m la profilul de \u00eenc\u0103rcare \u2014 ce se \u00eent\u00e2mpl\u0103, ce trebuie s\u0103 optimiz\u0103m.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d67310e6b90c4ee1337065790576c9a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i aici totul joac\u0103 \u00een favoarea noastr\u0103.<\/p>\n<p>\u00cen primul slide am spus deja: avem 80 de mii de cereri pe secund\u0103 pentru citire, cu doar 3,5 milioane de upload-uri pe zi. Asta este o diferen\u021b\u0103 de trei ordini de m\u0103sur\u0103. Este evident c\u0103 trebuie s\u0103 optimiz\u0103m citirea \u0219i este practic clar cum.<\/p>\n<p>Exist\u0103 \u00eenc\u0103 un mic detaliu. Specificul serviciului este c\u0103 utilizatorul se \u00eenregistreaz\u0103, \u00eencarc\u0103 o fotografie, apoi \u00eencepe s\u0103 vizioneze activ al\u021bi oameni, \u00eei d\u0103 like, \u0219i este expus activ altor utilizatori. Apoi, g\u0103se\u0219te o pereche sau nu, depinde de situa\u021bie, \u0219i pentru o perioad\u0103 de timp \u00eenceteaz\u0103 s\u0103 foloseasc\u0103 serviciul. \u00cen acel moment, c\u00e2nd este activ, fotografiile sale sunt foarte c\u0103utate \u2014 sunt solicitate de foarte mul\u021bi oameni. Odat\u0103 ce \u00eenceteaz\u0103, el este eliminat rapid din acele afi\u0219\u0103ri intense c\u0103tre al\u021bi utilizatori, a\u0219a cum erau \u00eenainte, iar fotografiile sale practic nu mai sunt solicitate.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/dcc7e306055d8f2b0895f24679bfc3e2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAdic\u0103, avem un set de date foarte mic, dar cu foarte multe solicit\u0103ri. \u0218i o solu\u021bie evident\u0103 aici este s\u0103 ad\u0103ug\u0103m un cache.<\/p>\n<p>Cache-ul cu LRU ne va rezolva toate problemele. Ce facem?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/2bd0c88a97d928f386db21549fc02500.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAd\u0103ug\u0103m \u00eenaintea cluster-ului nostru mare cu storage un alt cluster relativ mic, numit photoscache. Acesta este, \u00een esen\u021b\u0103, un proxy de caching.<\/p>\n<p>Cum func\u021bioneaz\u0103 acest lucru din interior? Iat\u0103 utilizatorul nostru, iat\u0103 storage-ul. Totul e la fel ca \u00eenainte. Ce ad\u0103ug\u0103m \u00eentre ele?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7b7b5f102f1c012b2aef8f02ec731fac.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste pur \u0219i simplu o ma\u0219in\u0103 cu un disc local fizic, care este rapid. De exemplu, cu SSD. \u0218i pe acest disc este stocat un anumit cache local.<\/p>\n<p>Cum arat\u0103 acest lucru? Utilizatorul trimite o solicitare pentru o fotografie. NGINX o caut\u0103 mai \u00eent\u00e2i \u00een cache-ul local. Dac\u0103 nu o g\u0103se\u0219te, folose\u0219te proxy_pass pentru storage-ul nostru, descarc\u0103 fotografia de acolo \u0219i o ofer\u0103 utilizatorului.<\/p>\n<p>Dar acest lucru este foarte banal \u0219i nu este clar ce se \u00eent\u00e2mpl\u0103 \u00een interior. Func\u021bioneaz\u0103 cam a\u0219a.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/46be24df171d1008e2a9099b7e4c9be6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCache-ul este logic \u00eemp\u0103r\u021bit \u00een trei straturi. C\u00e2nd spun \u00abtrei straturi\u00bb, nu \u00eenseamn\u0103 c\u0103 este vreun sistem complicat. Nu, este pur \u0219i simplu trei directoare \u00een sistemul de fi\u0219iere:<\/p>\n<ol>\n<li>Acesta este bufferul, unde ajung fotografiile proasp\u0103t \u00eenc\u0103rcate din proxy.<\/li>\n<li>Acesta este cache-ul fierbinte, unde sunt stocate fotografiile care sunt solicitate activ \u00een prezent.<\/li>\n<li>\u0218i cache-ul rece, unde fotografiile sunt \u00eempinse treptat din cache-ul fierbinte, atunci c\u00e2nd primesc mai pu\u021bine solicit\u0103ri.<\/li>\n<\/ol>\n<p>\nPentru ca acest lucru s\u0103 func\u021bioneze, trebuie s\u0103 gestion\u0103m acest cache, trebuie s\u0103 mut\u0103m fotografiile \u00een el etc. Acesta este, de asemenea, un proces foarte primitiv.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9b16fe3e99a5f88f06169f6e5eedf2b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNginx scrie pur \u0219i simplu pe fiecare cerere \u00een RAMDisk access.log, unde indic\u0103 calea c\u0103tre fotografia pe care o serve\u0219te \u00een acel moment (cale relativ\u0103, desigur), \u0219i modul \u00een care a fost procesat\u0103. Adic\u0103, acolo poate fi scris \u201ephoto 1\u201d \u0219i mai departe sau buffer, sau cache fierbinte, sau cache rece, sau proxy.<\/p>\n<p>\u00cen func\u021bie de aceasta, trebuie s\u0103 lu\u0103m o decizie despre ce s\u0103 facem cu fotografia.<\/p>\n<p>Fiecare ma\u0219in\u0103 are un mic demon care cite\u0219te constant acest log \u0219i \u00ee\u0219i p\u0103streaz\u0103 \u00een memorie statistica utiliz\u0103rii anumitor fotografii.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0dceda5e5ff432d1609520f0c152f152.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcesta doar colecteaz\u0103, \u021bine cont \u0219i face periodic urm\u0103toarele. Fotografii solicitate activ, pentru care vin multe cereri, sunt mutate \u00een cache-ul fierbinte, oriunde s-ar afla.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/941c13ecfea88372f3a7eb62d81b0c4e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFotografiile care sunt solicitate rar \u0219i au devenit \u0219i mai rare sunt \u00eempinse treptat din cache-ul fierbinte \u00een cel rece.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a07235246995ad2fa4e6aeccae23a629.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i c\u00e2nd nu mai avem loc \u00een cache, \u00eencepem pur \u0219i simplu s\u0103 \u0219tergem tot din cache-ul rece f\u0103r\u0103 discern\u0103m\u00e2nt. \u0218i, de altfel, func\u021bioneaz\u0103 foarte bine.<\/p>\n<p>Pentru ca fotografia s\u0103 fie salvat\u0103 imediat la proxy-ing \u00een buffer, folosim directiva proxy_store \u0219i bufferul \u2014 acesta este de asemenea RAMDisk, adic\u0103 pentru utilizator func\u021bioneaz\u0103 foarte rapid. Aceasta este situa\u021bia intern\u0103 a serverului de caching.<\/p>\n<p>R\u0103m\u00e2ne \u00eentrebarea despre cum s\u0103 distribuim cererile \u00eentre aceste servere.<\/p>\n<p>S\u0103 spunem c\u0103 avem un cluster format din dou\u0103zeci de ma\u0219ini de stocare \u0219i trei servere de caching (asta s-a \u00eent\u00e2mplat).<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6bc970b687701f3b6d57e153e3abed18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTrebuie s\u0103 definim \u00eentr-un fel ce cereri sunt pentru ce fotografii \u0219i unde s\u0103 le direc\u021bion\u0103m.<\/p>\n<p>Cea mai banal\u0103 op\u021biune este Round Robin. Sau ar trebui s\u0103 facem \u00eent\u00e2i aleatoriu?<\/p>\n<p>Este evident c\u0103 acest lucru are o serie de dezavantaje, deoarece vom folosi foarte ineficient cache-ul \u00een aceast\u0103 situa\u021bie. Cererile vor fi direc\u021bionate c\u0103tre ma\u0219ini aleatorii: aici s-a cache-uit, pe ma\u0219ina al\u0103turat\u0103 deja nu mai exist\u0103. \u0218i toate acestea, chiar \u0219i cu un num\u0103r mic de ma\u0219ini \u00een cluster, vor func\u021biona foarte prost.<\/p>\n<p>Trebuie s\u0103 definim \u00eentr-un fel clar pe ce server s\u0103 se direc\u021bioneze fiecare cerere.<\/p>\n<p>Exist\u0103 o metod\u0103 simpl\u0103. Lu\u0103m hash-ul din URL sau hash-ul cheii noastre de shardare, care este \u00een URL, \u0219i \u00eel \u00eemp\u0103r\u021bim \u00eentreg la num\u0103rul de servere. Va func\u021biona? Da.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/794a82ac1268b651ab936f0225b802a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAdic\u0103, avem un request de sut\u0103 la sut\u0103, de exemplu, pentru un \u201eexample_url\u201d va ajunge \u00eentotdeauna pe serverul cu indexul \u201e2\u201d, iar cache-ul va fi utilizat c\u00e2t mai eficient posibil.<\/p>\n<p>\u00cens\u0103, apare o problem\u0103 cu resharding-ul \u00een aceast\u0103 schem\u0103. Resharding \u2014 m\u0103 refer la schimbarea num\u0103rului de servere.<\/p>\n<p>S\u0103 presupunem c\u0103 clusterul nostru de caching a \u00eencetat s\u0103 fac\u0103 fa\u021b\u0103, \u0219i am decis s\u0103 ad\u0103ug\u0103m o ma\u0219in\u0103 \u00een plus.<\/p>\n<p>Ad\u0103ug\u0103m.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5f2fcba4c4f267c069811c3677bd0213.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcum totul se \u00eemparte pe \u00eentreg, nu \u00een trei, ci \u00een patru. Astfel, aproape toate cheile pe care le aveam, aproape toate URL-urile acum tr\u0103iesc pe alte servere. Tot cache-ul a fost invalidat instantaneu. Toate solicit\u0103rile au ajuns pe clusterul nostru de stocare, a avut probleme, am avut o nefunc\u021bionare \u0219i utilizatori nemul\u021bumi\u021bi. Nu ne dorim asta.<\/p>\n<p>Aceast\u0103 op\u021biune nu ne convine nici ea.<\/p>\n<p>Deci, ce trebuie s\u0103 facem? Trebuie cumva s\u0103 utiliz\u0103m eficient cache-ul, s\u0103 redirec\u021bion\u0103m un request c\u0103tre acela\u0219i server, dar s\u0103 fim \u00een acela\u0219i timp rezisten\u021bi la resharding. \u0218i exist\u0103 o astfel de solu\u021bie, nu este foarte complex\u0103. Se nume\u0219te hashing consistent.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1380758686274df9755a7ebf7d1c8753.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCum arat\u0103 aceasta?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/44f97abfac46fa9f361055548819e8a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLu\u0103m o func\u021bie din cheia de sharding \u0219i o dispers\u0103m pe cerc. Adic\u0103, la punctul 0 se \u00eent\u00e2lnesc valorile ei minime \u0219i maxime. Apoi, pe acelasi cerc, plas\u0103m toate serverele noastre \u00een mod aproximativ astfel:<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d470ec615a789913a6baa2726b05acea.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFiecare server este definit de un punct, iar sectorul care merge p\u00e2n\u0103 la el \u00een sensul acelor de ceasornic, este gestionat de acel host. C\u00e2nd primim solicit\u0103ri, vedem imediat c\u0103, de exemplu, solicitarea A \u2014 are un hash astfel \u2014 \u0219i este gestionat\u0103 de serverul 2. Solicitarea B \u2014 de serverul 3. \u0218i a\u0219a mai departe.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fcdbd1caa9f1162cf02e8b0a1c79cb74.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCe se \u00eent\u00e2mpl\u0103 \u00een aceast\u0103 situa\u021bie \u00een cazul resharding-ului?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7386cda826e9419d5f8a9a0d6d6703c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNu invalid\u0103m \u00eentregul cache, ca \u00eenainte, \u0219i nu mut\u0103m toate cheile, ci mut\u0103m fiecare sector pe o distan\u021b\u0103 mic\u0103 astfel \u00eenc\u00e2t \u00een spa\u021biul eliberat, s\u0103 \u00eencap\u0103 serverul nostru al \u0219aselea, pe care dorim s\u0103-l ad\u0103ug\u0103m, \u0219i \u00eel ad\u0103ug\u0103m acolo.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8680e0cf023ce911b4d162e9102c0545.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDesigur, \u00een astfel de situa\u021bii, cheile se deplaseaz\u0103 \u0219i ele. Dar se deplaseaz\u0103 mult mai pu\u021bin dec\u00e2t \u00eenainte. \u0218i vedem c\u0103 primele noastre dou\u0103 chei au r\u0103mas pe serverele lor, iar serverul de cache s-a schimbat doar pentru ultima cheie. Acest sistem func\u021bioneaz\u0103 destul de eficient, iar dac\u0103 ad\u0103uga\u021bi noi gazde \u00een mod incremental, nu exist\u0103 o mare problem\u0103. Ad\u0103uga\u021bi pu\u021bin c\u00e2te pu\u021bin, a\u0219tepta\u021bi s\u0103 se umple din nou cache-ul \u0219i totul func\u021bioneaz\u0103 bine.<\/p>\n<p>Singura \u00eentrebare care r\u0103m\u00e2ne este \u00een cazul e\u0219ecurilor. S\u0103 presupunem c\u0103 avem o ma\u0219in\u0103 care a ie\u0219it din func\u021biune.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8e3301af782ce8983716c4bc9add79a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i nu ne-ar pl\u0103cea deloc s\u0103 regener\u0103m aceast\u0103 hart\u0103, s\u0103 invalid\u0103m o parte din cache \u0219i a\u0219a mai departe, dac\u0103, de exemplu, ma\u0219ina s-a repornit, iar noi trebuie cumva s\u0103 gestion\u0103m solicit\u0103rile. Pur \u0219i simplu p\u0103str\u0103m pe fiecare site un fotocache de rezerv\u0103, care \u00eendepline\u0219te rolul de substitut pentru orice ma\u0219in\u0103 care acum a ie\u0219it din func\u021biune. \u0218i dac\u0103 dintr-o dat\u0103 un server devine inaccesibil, traficul se \u00eendreapt\u0103 acolo. Evident, nu avem niciun cache acolo, adic\u0103 este rece, dar, cel pu\u021bin, solicit\u0103rile utilizatorilor sunt procesate. Dac\u0103 acesta este un interval scurt, trecem peste asta f\u0103r\u0103 probleme. Doar c\u0103 cre\u0219te \u00eenc\u0103rc\u0103tura pe storage. Dac\u0103 intervalul este lung, putem lua decizia \u2014 s\u0103 elimin\u0103m acest server din hart\u0103 sau nu, sau poate s\u0103-l \u00eenlocuim cu altul.<\/p>\n<p>Acesta este referitor la sistemul de caching. S\u0103 vedem rezultatele.<\/p>\n<p>Ar p\u0103rea c\u0103 nu este nimic complicat aici. Dar aceast\u0103 metod\u0103 de gestionare a cache-ului ne-a oferit o rat\u0103 de succes de aproximativ 98%. Adic\u0103, din cele 80 de mii de solicit\u0103ri pe secund\u0103, doar 1600 ajung la storage-uri, \u0219i aceasta este o \u00eenc\u0103rc\u0103tur\u0103 absolut normal\u0103, ele suport\u0103 cu u\u0219urin\u021b\u0103 acest lucru, avem \u00eentotdeauna un rezerv\u0103.<\/p>\n<p>Am instalat aceste servere \u00een trei dintre centrele noastre de date, ob\u021bin\u00e2nd astfel trei puncte de prezen\u021b\u0103 \u2014 Praga, Miami \u0219i Hong Kong.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/64eef492b65a014d8ba3c808b6579b41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA\u0219adar, acestea sunt situate relativ local fa\u021b\u0103 de fiecare dintre pie\u021bele noastre \u021bint\u0103.<\/p>\n<p>\u0218i ca un bonus pl\u0103cut, am ob\u021binut acest proxy de cache, pe care CPU \u00een realitate st\u0103 degeaba, pentru c\u0103 pentru livrarea con\u021binutului nu este at\u00e2t de necesar. \u0218i acolo, cu ajutorul NGINX+ Lua, am implementat foarte mult\u0103 logic\u0103 utilitar\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b65c609df5e1985240d04ee65a3e4f55.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe exemplu, putem experimenta cu webp sau jpeg progresiv (acestea sunt formate moderne \u0219i eficiente), putem observa cum afecteaz\u0103 traficul, putem lua anumite decizii, s\u0103 activ\u0103m pentru anumite \u021b\u0103ri etc.; putem efectua redimension\u0103ri sau crop-uri dinamice ale fotografiilor \u00een timp real.<\/p>\n<p>Este un bun caz de utilizare, c\u00e2nd de exemplu, ave\u021bi o aplica\u021bie mobil\u0103 care afi\u0219eaz\u0103 fotografii, iar aplica\u021bia mobil\u0103 nu vrea s\u0103 consume CPU-ul clientului pentru a solicita o fotografie mare \u0219i a o redimensiona apoi la o anumit\u0103 dimensiune, astfel \u00eenc\u00e2t s\u0103 o \u00eencadreze \u00een vizualizare. Putem pur \u0219i simplu s\u0103 specific\u0103m dinamic \u00een URL anumite parametrii \u00een UPort, iar cache-ul foto se va redimensiona singur fotografia. De obicei, acesta alegerea dimensiunea care ne este fizic disponibil\u0103 pe disc, c\u00e2t mai apropiat\u0103 de cea solicitat\u0103, \u0219i o va scala \u00een coordonatele specifice.<\/p>\n<blockquote><p>Apropo, am pus la dispozi\u021bie \u00een mod public \u00eenregistr\u0103rile video ale ultimilor cinci ani de conferin\u021be pentru dezvoltatori de sisteme de \u00eenalt\u0103 sarcin\u0103. <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex>. Uita\u021bi-v\u0103, explora\u021bi, \u00eemp\u0103rt\u0103\u0219i\u021bi \u0219i abona\u021bi-v\u0103 la <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/profyclub\">canalul YouTube<\/a><\/noindex>.<\/p><\/blockquote>\n<p>\nDe asemenea, putem ad\u0103uga mult\u0103 logic\u0103 de produs acolo. De exemplu, putem ad\u0103uga diferite watermark-uri pe baza parametrilor din URL, putem aplica blur fotografiilor, le putem estompa sau pixeliza. Acesta este momentul c\u00e2nd dorim s\u0103 ar\u0103t\u0103m fotografia unei persoane, dar nu dorim s\u0103-i ar\u0103t\u0103m fa\u021ba, ceea ce func\u021bioneaz\u0103 bine, totul este implementat aici.<\/p>\n<p>Ce am ob\u021binut? Am ob\u021binut trei puncte de prezen\u021b\u0103, un rate de succes bun, iar CPU-ul acestor ma\u0219ini nu este acum inactiv. Acum este, desigur, mai important dec\u00e2t \u00eenainte. Trebuie s\u0103 echip\u0103m ma\u0219inile cu mai mult\u0103 putere, dar merit\u0103.<\/p>\n<p>Aceasta este viziunea \u00een ceea ce prive\u0219te livrarea fotografiilor. Aici totul este destul de clar \u0219i evident. Cred c\u0103 nu am descoperit America, a\u0219a func\u021bioneaz\u0103 practic orice CDN.<\/p>\n<p>\u0218i, foarte probabil, ascult\u0103torul experimentat s-ar putea \u00eentreba: de ce s\u0103 nu schimb\u0103m totul cu CDN-ul? Ar fi cam acela\u0219i lucru, toate CD-urile moderne pot face asta. \u0218i aici sunt c\u00e2teva motive.<\/p>\n<p>Primul - acestea sunt fotografiile.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/592c10eb74d46191bfcedec120f68556.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste unul dintre aspectele cheie ale infrastructurii noastre \u0219i avem nevoie de c\u00e2t mai mult control asupra lor. Dac\u0103 este o solu\u021bie de la un furnizor extern \u0219i nu ave\u021bi nici o autoritate asupra acesteia, va fi destul de greu s\u0103 tr\u0103i\u021bi cu asta c\u00e2nd ave\u021bi un dataset mare \u0219i c\u00e2nd ave\u021bi un volum foarte mare de cereri din partea utilizatorilor.<\/p>\n<p>Voi da un exemplu. Acum, pe infrastructura noastr\u0103, putem, de exemplu, \u00een cazul unor probleme sau zgomote subterane, s\u0103 intr\u0103m pe ma\u0219in\u0103 \u0219i s\u0103 facem debugging acolo, a\u0219a, vorbind. Putem ad\u0103uga colectarea unor metrici care sunt doar pentru noi, putem experimenta \u00eentr-un fel, vedem cum afecteaz\u0103 graficele \u0219i a\u0219a mai departe. Acum se colecteaz\u0103 foarte multe statistici despre acest cluster de cache. \u0218i periodic ne uit\u0103m la ele \u0219i analiz\u0103m \u00eendelung anumite anomalii. Dac\u0103 ar fi fost pe partea CDN, ar fi fost mult mai greu de controlat. Sau, de exemplu, \u00een cazul unei avarii, \u0219tim ce s-a \u00eent\u00e2mplat, \u0219tim cum s\u0103 tr\u0103im cu asta \u0219i cum s\u0103 o dep\u0103\u0219im. Aceasta este prima concluzie.<\/p>\n<p>A doua concluzie este mai degrab\u0103 istoric\u0103, deoarece sistemul evolueaz\u0103 de mult timp, iar multe cerin\u021be de afaceri diferite au existat \u00een diferite etape, \u0219i departe de a se \u00eencadra \u00eentotdeauna \u00een conceptul CDN.<\/p>\n<p>\u0218i un punct care decurge din precedent \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/007cf3aed2f9cc12185fc3865bf9d196.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste c\u0103, pe fotocache-uri, avem mult\u0103 logic\u0103 specific\u0103, pe care nu \u00eentotdeauna o putem ad\u0103uga la cerere. Este pu\u021bin probabil ca vreun CDN s\u0103 adauge la cererea dvs. anumite lucruri personalizate. De exemplu, criptarea URL-urilor, dac\u0103 nu dori\u021bi ca clientul s\u0103 poat\u0103 schimba ceva. Dori\u021bi s\u0103 schimba\u021bi URL-ul pe server \u0219i s\u0103-l cripta\u021bi, iar apoi s\u0103 furniza\u021bi aici anumite parametri dinamici.<\/p>\n<p>Ce concluzie se impune? \u00cen cazul nostru, CDN-ul nu este o alternativ\u0103 prea bun\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/cfc2963cca2357cf6b0f63419a4dc436.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen cazul dvs., dac\u0103 ave\u021bi cerin\u021be specifice de afaceri, pute\u021bi implementa f\u0103r\u0103 probleme ceea ce v-am ar\u0103tat. \u0218i cu un profil de \u00eenc\u0103rcare similar, va func\u021biona excelent.<\/p>\n<p>Dar dac\u0103 ave\u021bi o solu\u021bie general\u0103 \u0219i sarcina nu este foarte specific\u0103, pute\u021bi s\u0103 folosi\u021bi cu \u00eencredere CDN. Sau dac\u0103 pentru dvs. timpul \u0219i resursele sunt mult mai importante dec\u00e2t controlul.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b76d25404918a5d0d8bf1d6644c8d873.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i CDN-urile moderne au practic tot ceea ce v-am povestit acum. Cu excep\u021bia c\u00e2torva func\u021bii mai mult sau mai pu\u021bin.<\/p>\n<p>Aceasta este \u00een leg\u0103tur\u0103 cu livrarea fotografiilor.<\/p>\n<p>Acum s\u0103 ne mut\u0103m pu\u021bin mai departe \u00een retrospectiva noastr\u0103 \u0219i s\u0103 vorbim despre stocare.<\/p>\n<p>Anul 2013 a trecut.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f218bfc899512041967842430c02aa9b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nServerele de caching s-au ad\u0103ugat, problemele cu performan\u021ba au disp\u0103rut. Totul este bine. Datasetul cre\u0219te. \u00cen anul 2013 aveam aproximativ 80 de servere conectate la stoc\u0103ri \u0219i aproximativ 40 de servere de caching \u00een fiecare centru de date. Asta \u00eenseamn\u0103 560 de terabytes de date \u00een fiecare centru de date, adic\u0103 \u00een jur de un petabyte \u00een total.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef741ba4a9164e6940f55e93dfb46ef0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOdat\u0103 cu cre\u0219terea datasetului, costurile opera\u021bionale au \u00eenceput s\u0103 creasc\u0103 semnificativ. \u00cen ce a constat aceasta?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6cf5e489a4e97bc6e26fc6d4d16505b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen aceast\u0103 schem\u0103, care este desenat\u0103 \u2013 cu SAN, cu ma\u0219inile conectate la acesta \u0219i cu cache-urile \u2013 exist\u0103 foarte multe puncte de e\u0219ec. Dac\u0103 am gestionat anterior e\u0219ecurile serverelor de caching, acolo totul era mai mult sau mai pu\u021bin previzibil \u0219i clar, pe partea de stocare situa\u021bia a fost mult mai grav\u0103.<\/p>\n<p>\u00cen primul r\u00e2nd, re\u021beaua de stocare SAN, care poate s\u0103 cedeze.<\/p>\n<p>\u00cen al doilea r\u00e2nd, este conectat\u0103 prin fibr\u0103 optic\u0103 la ma\u0219inile finale. Pot exista probleme cu cardurile optice \u0219i \u00eentrerup\u0103toarele.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6959b79284c5b1244a70a1d64f191893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDesigur, acestea nu sunt at\u00e2t de multe ca cele cu SAN, dar, cu toate acestea, sunt \u0219i ele puncte de e\u0219ec.<\/p>\n<p>Apoi, ma\u0219ina \u00eens\u0103\u0219i, care este conectat\u0103 la stocare. Ea poate, de asemenea, s\u0103 ias\u0103 din func\u021biune.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1801cb502663a4de14329a5e67dfed79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDeci avem trei puncte de e\u0219ec.<\/p>\n<p>\u00cen plus, \u00een afara punctelor de e\u0219ec, \u00eentre\u021binerea sistemelor de stocare este greoaie.<\/p>\n<p>Este un sistem complex, multi-component, \u0219i inginerii de sistem se confrunt\u0103 uneori cu dificult\u0103\u021bi \u00een utilizarea acestuia.<\/p>\n<p>\u0218i ultimul, cel mai important punct. Dac\u0103 \u00een oricare dintre aceste trei puncte apare un e\u0219ec, avem o probabilitate non-zero de a pierde datele utilizatorului, deoarece sistemul de fi\u0219iere poate fi corupt.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4bf8bc1c73a2beef74cb4ee0ee45679b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS\u0103 presupunem c\u0103 sistemul de fi\u0219iere s-a corupt. Restaurarea acestuia dureaz\u0103, \u00een primul r\u00e2nd, mult \u2013 poate dura o s\u0103pt\u0103m\u00e2n\u0103 pentru un volum mare de date. \u00cen al doilea r\u00e2nd, cel mai probabil vom ob\u021bine o mul\u021bime de fi\u0219iere neclare, pe care va trebui s\u0103 le potrivim \u00eentr-un fel cu fotografiile utilizatorilor. \u0218i risc\u0103m s\u0103 pierdem date. Riscurile sunt destul de mari. \u0218i cu c\u00e2t astfel de situa\u021bii apar mai des \u0219i cu c\u00e2t mai multe probleme apar \u00een \u00eentreaga aceast\u0103 lan\u021b, cu at\u00e2t riscurile cresc.<\/p>\n<p>Trebuia s\u0103 facem ceva \u00een leg\u0103tur\u0103 cu asta. \u0218i am decis c\u0103 trebuie s\u0103 rezerv\u0103m pur \u0219i simplu datele. Acesta este, de fapt, un solut evidenta \u0219i bun\u0103. Ce am f\u0103cut?<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f80ec2b65003c40bd2fabf88966b3e05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA\u0219a ar\u0103ta serverul nostru, care era conectat la stocare anterior. Acesta este o partajare principal\u0103, este practic un dispozitiv bloc care reprezint\u0103 un mount pentru stocare la distan\u021b\u0103 prin fibr\u0103 optic\u0103.<\/p>\n<p>Am ad\u0103ugat pur \u0219i simplu o a doua partajare.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d3dba75ef477269d92145cd69d587527.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAm plasat un al doilea storage l\u00e2ng\u0103 acesta (din fericire, nu este at\u00e2t de scump) \u0219i l-am numit sectiune de backup. Acesta este de asemenea conectat prin fibr\u0103 optic\u0103 \u0219i se afl\u0103 pe aceea\u0219i ma\u0219in\u0103. Dar trebuie s\u0103 sincroniz\u0103m cumva datele \u00eentre ele.<\/p>\n<p>Aici facem doar o coad\u0103 asincron\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/67bced2b45c589009cfb01a1c21398a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNu este foarte aglomerat\u0103. \u0218tim c\u0103 avem pu\u021bine \u00eenregistr\u0103ri. Coada este pur \u0219i simplu un tabel \u00een MySQL, \u00een care se scriu r\u00e2nduri de tipul \"trebuie s\u0103 fac backup pentru aceast\u0103 fotografie\". La orice modificare sau la upload, copiem din sectiunea principal\u0103 pe backup printr-un worker asincron sau pur \u0219i simplu un background worker.<\/p>\n<p>\u0218i astfel avem \u00eentotdeauna dou\u0103 sec\u021biuni consistente. Chiar dac\u0103 o parte a acestui sistem se defecteaz\u0103, putem schimba \u00eentotdeauna sectiunea principal\u0103 cu backup-ul, iar totul va continua s\u0103 func\u021bioneze.<\/p>\n<p>Dar din cauza aceasta, sarcina la citire cre\u0219te semnificativ, deoarece, pe l\u00e2ng\u0103 clien\u021bii care citesc din sectiunea principal\u0103, pentru c\u0103 ei se uit\u0103 \u00eent\u00e2i la fotografie acolo (este mai recent\u0103), apoi caut\u0103 pe backup dac\u0103 nu au g\u0103sit (dar acesta se face pur \u0219i simplu prin NGINX), acum \u0219i sistemul nostru de backup cite\u0219te din sectiunea principal\u0103. Nu c\u0103 ar fi un punct critic, dar nu am vrut s\u0103 cre\u0219tem sarcina, practic, f\u0103r\u0103 motiv.<\/p>\n<p>\u0218i am ad\u0103ugat un al treilea disk, care este un SSD mic \u0219i l-am numit buffer.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd35481822b4170087e5f670bf338dc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCum func\u021bioneaz\u0103 acum.<\/p>\n<p>Utilizatorul uploadeaz\u0103 o fotografie pe buffer, apoi este trimis un eveniment \u00een coad\u0103 c\u0103 trebuie copiat\u0103 \u00een cele dou\u0103 sectiuni. Aceasta este copiat\u0103, iar fotografia r\u0103m\u00e2ne un timp (s\u0103 spunem, o zi) pe buffer, dup\u0103 care este purjat\u0103. Aceasta \u00eembun\u0103t\u0103\u021be\u0219te foarte mult experien\u021ba utilizatorului, deoarece utilizatorul \u00eencarc\u0103 fotografia, iar, de obicei, imediat dup\u0103, \u00eencep s\u0103 vin\u0103 cereri, sau el \u00eensu\u0219i \u00ee\u0219i re\u00eemprosp\u0103teaz\u0103 pagina. Dar aceasta depinde de aplica\u021bia care face upload-ul.<\/p>\n<p>Sau, de exemplu, alte persoane, c\u0103rora le-o arat\u0103, trimit imediat cereri pentru aceast\u0103 fotografie. \u00cen cache \u00eenc\u0103 nu este, prima cerere se \u00eent\u00e2mpl\u0103 foarte repede. Practic, la fel ca \u00een cazul cache-ului pentru fotografii. Storage-ul lent nu particip\u0103 deloc \u00een acest proces. Iar c\u00e2nd dup\u0103 o zi va fi purjat, fie va fi deja \u00een cache pe stratul nostru de caching, fie, cel mai probabil, nu va mai fi necesar. A\u0219adar, experien\u021ba utilizatorului a crescut foarte mult datorit\u0103 acestor manevre simple.<\/p>\n<p>Ei bine, \u0219i cel mai important: am \u00eencetat s\u0103 mai pierdem date.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/526f549457dd0c438f32b0adb76df76c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAm spus a\u0219a, am \u00eencetat <em>poten\u021bial<\/em> a pierde date, pentru c\u0103 de fapt nu le-am pierdut niciodat\u0103. Dar pericolul a fost. Observ\u0103m c\u0103 aceast\u0103 solu\u021bie, desigur, este bun\u0103, dar seam\u0103n\u0103 pu\u021bin cu tratarea simptomelor problemei, \u00een loc s\u0103 o rezolv\u0103m complet. \u0218i unele probleme au r\u0103mas.<\/p>\n<p>\u00cen primul r\u00e2nd, exist\u0103 un punct de e\u0219ec \u00een form\u0103 de gazd\u0103 fizic\u0103, pe care \u00eentreaga ma\u0219in\u0103rie func\u021bioneaz\u0103, iar aceasta nu a disp\u0103rut.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0eb3d292655a7edf912793ed81e8931c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen al doilea r\u00e2nd, au r\u0103mas probleme cu SAN-urile, a r\u0103mas mentenan\u021ba lor complex\u0103 etc. Nu era neap\u0103rat un factor critic, dar am vrut s\u0103 \u00eencerc\u0103m s\u0103 tr\u0103im f\u0103r\u0103 acestea.<\/p>\n<p>\u0218i am f\u0103cut o a treia versiune (de fapt, a doua \u00een realitate) \u2013 versiunea de rezervare. Cum ar\u0103ta aceasta?<\/p>\n<p>Asta este ceea ce a fost \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8b1749b6feed200f8a64529ee2316c1a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPrincipalele probleme pe care le avem sunt cu gazda fizic\u0103.<\/p>\n<p>\u00cen primul r\u00e2nd, elimin\u0103m SAN-urile, pentru c\u0103 vrem s\u0103 experiment\u0103m, vrem s\u0103 \u00eencerc\u0103m pur \u0219i simplu cu discuri locale.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd0f5a8627d9179fcbc7097c1c18505f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste deja anul 2014-2015, iar \u00een acel moment situa\u021bia cu discurile \u0219i capacitatea lor pe o gazd\u0103 a devenit mult mai bun\u0103. Ne-am zis de ce s\u0103 nu \u00eencerc\u0103m.<\/p>\n<p>\u00cen continuare, pur \u0219i simplu lu\u0103m sec\u021biunea noastr\u0103 de backup \u0219i o mut\u0103m fizic pe o ma\u0219in\u0103 separat\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/456e00bc8557d3340b06efcd1dde8a08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAstfel, obtinem o schem\u0103 de acest gen. Avem dou\u0103 ma\u0219ini care stocheaz\u0103 seturi de date identice. Ele se rezerv\u0103 reciproc complet \u0219i sincronizeaz\u0103 datele prin re\u021bea printr-o coad\u0103 asincron\u0103 \u00een acela\u0219i MySQL.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d44cdb7b440ad4c58cc625123306a8c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe ce func\u021bioneaz\u0103 bine - pentru c\u0103 avem pu\u021bine \u00eenregistr\u0103ri. Adic\u0103, dac\u0103 \u00eenregistr\u0103rile ar fi echivalente cu citirile, am putea avea un anumit overhead de re\u021bea \u0219i probleme. Avem pu\u021bine \u00eenregistr\u0103ri, multe citiri - acest mod func\u021bioneaz\u0103 bine, adic\u0103 copiem destul de rar fotografiile \u00eentre aceste dou\u0103 servere.<\/p>\n<p>Cum func\u021bioneaz\u0103 acest lucru, dac\u0103 ne uit\u0103m pu\u021bin mai \u00een detaliu.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/071c11abb6ee1d7734c53052139ff04b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUpload. Balansatorul alegere pur \u0219i simplu gazde aleatorii cu o pereche \u0219i face upload pe acestea. \u00cen acela\u0219i timp, el face evident verific\u0103ri de s\u0103n\u0103tate, se uit\u0103 s\u0103 nu cad\u0103 ma\u0219ina. Adic\u0103, el face upload de poze doar pe serverul activ, iar apoi printr-o coad\u0103 asincron\u0103, totul este copiat pe colegul s\u0103u. Cu upload-ul totul este extrem de simplu.<\/p>\n<p>Cu sarcina este pu\u021bin mai complicat.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f494904aec823456e18b987a8c98bf56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAici ne-a ajutat Lua, deoarece pe NGINX-ul vanilla, uneori, este greu s\u0103 implement\u0103m o astfel de logic\u0103. \u00cencepem prin a face o cerere la primul server, verific\u0103m dac\u0103 fotografia exist\u0103 acolo, deoarece aceasta ar putea fi \u00eenc\u0103rcat\u0103, de exemplu, pe vecin, dar \u00eenc\u0103 nu a ajuns aici. Dac\u0103 fotografia este acolo, este bine. O oferim imediat clientului \u0219i, posibil, o cache-uim.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/de5f77e997bb049f4cfc1709da0f1788.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDac\u0103 nu este, facem pur \u0219i simplu o cerere c\u0103tre vecin \u0219i o ob\u021binem garantat de acolo.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/79aa5592acd28dfbc815261d0276c2e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA\u0219adar, \u00eenc\u0103 o dat\u0103 se poate spune: pot ap\u0103rea probleme cu performan\u021ba, deoarece acestea sunt cereri de tip round trip constante - s-a \u00eenc\u0103rcat fotografia, dar aici nu este, facem dou\u0103 cereri \u00een loc de una, ceea ce ar trebui s\u0103 func\u021bioneze lent.<\/p>\n<p>\u00cen situa\u021bia noastr\u0103, nu func\u021bioneaz\u0103 lent.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/52ca3902d80990f512201672cd5e6441.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nColect\u0103m o mul\u021bime de metrici pentru acest sistem, iar rata de hit a acestui mecanism este de aproximativ 95%. Asta \u00eenseamn\u0103 c\u0103 \u00eent\u00e2rzierea acestui backup este mic\u0103 \u0219i, datorit\u0103 acestui fapt, practic garantat, dup\u0103 ce fotografia a fost \u00eenc\u0103rcat\u0103, o ob\u021binem din prima \u0219i nu trebuie s\u0103 facem dou\u0103 drumuri.<\/p>\n<p>Astfel, ce altceva am ob\u021binut, \u0219i ce este foarte tare?<\/p>\n<p>\u00cen trecut, aveam un singur volum principal de backup \u0219i citeam secven\u021bial de pe acesta. Cu alte cuvinte, \u00eentotdeauna c\u0103utam mai \u00eent\u00e2i pe principal \u0219i apoi pe backup. Asta era o singur\u0103 cerere.<\/p>\n<p>Acum optimiz\u0103m citirea de pe dou\u0103 ma\u0219ini \u00een acela\u0219i timp. Distribuim cererile Round Robin. \u00centr-un procent mic de cazuri, facem dou\u0103 cereri. Dar, \u00een general, acum avem de dou\u0103 ori mai mult\u0103 capacitate de citire dec\u00e2t aveam \u00eenainte. \u0218i \u00eenc\u0103rc\u0103tura a sc\u0103zut semnificativ at\u00e2t pe ma\u0219inile de livrare, c\u00e2t \u0219i pe stocurile pe care le aveam la momentul respectiv.<\/p>\n<p>\u00cen ceea ce prive\u0219te rezilien\u021ba la defec\u021biuni. De fapt, pentru asta am luptat \u00een principal. Aici, rezilien\u021ba la defec\u021biuni s-a dovedit a fi fabuloas\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a030a477e60d6e1f3d0b4e3395013df5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nO ma\u0219in\u0103 cedeaz\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/42900b24e340c03ea642fd49f5b410ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNici o problem\u0103! Inginerul de sistem poate chiar s\u0103 nu se trezeasc\u0103 noaptea, va a\u0219tepta p\u00e2n\u0103 diminea\u021ba, nu va fi nimic grav.<\/p>\n<p>Chiar \u0219i \u00een cazul \u00een care, odat\u0103 cu e\u0219ecul acestei ma\u0219ini, coada a cedat, nici o problem\u0103, pur \u0219i simplu log-ul se va acumula mai \u00eent\u00e2i pe ma\u0219ina activ\u0103, iar apoi se va reconstrui \u00een coad\u0103, \u0219i abia apoi pe acea ma\u0219in\u0103 care va reintra \u00een func\u021biune dup\u0103 un timp.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef42eadaaf3e3ecbf70847e9f88c1582.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcela\u0219i lucru se aplic\u0103 \u0219i \u00eentre\u021binerii. Pur \u0219i simplu oprim una dintre ma\u0219ini, o scoatem din toate pool-urile, nu mai prime\u0219te trafic, facem o \u00eentre\u021binere, corect\u0103m ceva, dup\u0103 care o readucem \u00een operare, iar backup-ul este recuperat destul de rapid. Adic\u0103, dup\u0103 o zi de downtime pentru o ma\u0219in\u0103, se recupereaz\u0103 \u00een c\u00e2teva minute. Este realmente foarte pu\u021bin. Cu redundan\u021ba, repet, aici totul este grozav.<\/p>\n<p>Ce concluzii putem trasa din acest schem\u0103 de rezervare?<\/p>\n<p>Am ob\u021binut redundan\u021b\u0103.<\/p>\n<p>Exploatare simpl\u0103. Deoarece pe ma\u0219ini avem hard disk-uri locale, este mult mai convenabil din punct de vedere al exploat\u0103rii pentru inginerii care lucreaz\u0103 cu acestea.<\/p>\n<p>Am ob\u021binut un dublu surplus \u00een citiri.<\/p>\n<p>Acesta este un bonus foarte bun pe l\u00e2ng\u0103 redundan\u021b\u0103.<\/p>\n<p>Dar exist\u0103 \u0219i probleme. Acum avem o dezvoltare mult mai complicat\u0103 a unor func\u021bii legate de asta, deoarece sistemul a devenit 100% consistent \u00een mod eventual.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b650276a41730cc303180e8304c5dabb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTrebuie s\u0103 ne g\u00e2ndim, s\u0103 spunem, \u00een vreun background job: \u00abPe care server suntem acum?\u00bb \u00abEste aici cu adev\u0103rat o fotografie actualizat\u0103?\u00bb etc. Acestea, desigur, sunt toate \u00eencapsulate, iar pentru programatorul care scrie logica de afaceri, este transparent. Dar, cu toate acestea, a ap\u0103rut un strat complex mare. \u00cens\u0103 suntem preg\u0103ti\u021bi s\u0103 convie\u021buim cu asta \u00een schimbul beneficiilor pe care le-am ob\u021binut.<\/p>\n<p>\u0218i aici din nou apare un conflict.<\/p>\n<p>La \u00eenceput am spus c\u0103 a p\u0103stra totul pe hard disk-uri locale este r\u0103u. Acum spun c\u0103 ne-a pl\u0103cut.<\/p>\n<p>Da, \u00eentr-adev\u0103r, de-a lungul timpului situa\u021bia s-a schimbat mult, iar acum aceast\u0103 abordare are multe avantaje. \u00cen primul r\u00e2nd, ob\u021binem o exploatare mult mai simpl\u0103.<\/p>\n<p>\u00cen al doilea r\u00e2nd, este mai performant, deoarece nu mai avem acei controlere automate, conect\u0103ri la unit\u0103\u021bi de disc.<\/p>\n<p>Acolo este o ma\u0219in\u0103rie uria\u0219\u0103, iar aici sunt doar c\u00e2teva discuri, care sunt concret montate \u00een RAID pe ma\u0219in\u0103.<\/p>\n<p>Dar exist\u0103 \u0219i dezavantaje.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3c090e0801f1a686dc0d5fefce697c56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEste aproximativ de 1,5 ori mai scump dec\u00e2t utilizarea SAN-urilor chiar \u0219i la pre\u021burile de ast\u0103zi. De aceea, am decis s\u0103 nu convertim astfel f\u0103r\u0103 ezitare tot marele nostru cluster \u00een ma\u0219ini cu hard disk-uri locale \u0219i am decis s\u0103 p\u0103str\u0103m o solu\u021bie hibrid\u0103.<\/p>\n<p>Jum\u0103tate dintre ma\u0219ini func\u021bioneaz\u0103 cu hard disk-uri (de fapt, nu jum\u0103tate \u2013 cam 30%, probabil). Iar cealalt\u0103 parte sunt ma\u0219ini vechi, pe care era implementat primul sistem de rezervare. Pur \u0219i simplu le-am remontat, deoarece nu avem nevoie de date noi sau alte lucruri, doar am schimbat montajele de pe un gazd\u0103 fizic\u0103 pe dou\u0103.<\/p>\n<p>\u0218i am ob\u021binut o capacitate mare de citire, \u0219i am consolidat resursele. Dac\u0103 \u00eenainte montam un storage pe o singur\u0103 ma\u0219in\u0103, acum mont\u0103m patru pe o pereche, de exemplu. \u0218i asta func\u021bioneaz\u0103 foarte bine.<\/p>\n<p>Hai s\u0103 facem un rezumat scurt al ceea ce am realizat, ce am luptat pentru, \u0219i dac\u0103 a func\u021bionat.<\/p>\n<h3>Concluzii<\/h3>\n<p>\nAvem utilizatori \u2014 un total de 33 milioane.<\/p>\n<p>Avem trei puncte de prezen\u021b\u0103 \u2014 Praga, Miami, Hong Kong.<\/p>\n<p>\u00cen acestea se afl\u0103 un strat de caching, care const\u0103 \u00een ma\u0219ini cu discuri locale rapide (SSD), pe care func\u021bioneaz\u0103 o infrastructur\u0103 simpl\u0103 bazat\u0103 pe NGINX, cu access.log-uri \u0219i demoni pe Python care proceseaz\u0103 \u0219i gestioneaz\u0103 cache-ul.<\/p>\n<p>Dac\u0103 dori\u021bi, pute\u021bi \u00een proiectul dvs., dac\u0103 fotografiile nu sunt la fel de esen\u021biale pentru dvs. ca pentru noi, sau dac\u0103 trade-off-ul \u00eentre control \u0219i viteza dezvolt\u0103rii \u0219i costurile resurselor se \u00eenclin\u0103 \u00een favoarea altor aspecte, atunci pute\u021bi cu u\u0219urin\u021b\u0103 s\u0103-l \u00eenlocui\u021bi cu un CDN, deoarece CDN-urile moderne fac asta foarte bine.<\/p>\n<p>Apoi urmeaz\u0103 stratul de stocare, unde avem clustere de perechi de ma\u0219ini care se rezerv\u0103 \u00eentre ele, copierea asynchron\u0103 a fi\u0219ierelor de la unu la altul la orice modificare.<\/p>\n<p>\u00cen acela\u0219i timp, o parte dintre aceste ma\u0219ini func\u021bioneaz\u0103 cu hard disk-uri locale.<\/p>\n<p>O parte dintre aceste ma\u0219ini sunt conectate la SAN-uri.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5ddbc4f73d86aa1f83734885d8c9dea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u0218i, pe de o parte, este mai convenabil din punct de vedere al exploat\u0103rii \u0219i pu\u021bin mai performant, iar pe de alt\u0103 parte, este convenabil din perspectiva densit\u0103\u021bii de amplasare \u0219i pre\u021bului pe gigabyte.<\/p>\n<p>Aceasta este o scurt\u0103 prezentare a arhitecturii pe care am realizat-o \u0219i cum s-a dezvoltat totul.<\/p>\n<p>\u00cenc\u0103 c\u00e2teva sfaturi simple de la cap, foarte simple.<\/p>\n<p>\u00cen primul r\u00e2nd, dac\u0103 v\u0103 decide\u021bi c\u0103 trebuie s\u0103 \u00eembun\u0103t\u0103\u021bi\u021bi urgent \u00eentreaga infrastructur\u0103 a fotografiilor, m\u0103sura\u021bi mai \u00eent\u00e2i, deoarece, poate, nu este necesar s\u0103 \u00eembun\u0103t\u0103\u021bi\u021bi nimic.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7770f41d0b190eb78ae0d19f4c8182a6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVoi da un exemplu. Avem un cluster de ma\u0219ini care furnizeaz\u0103 fotografii din anexele de pe chat-uri, \u0219i acolo continu\u0103m s\u0103 folosim schema din 2009, \u0219i nimeni nu sufer\u0103 de pe urma asta. Toat\u0103 lumea este mul\u021bumit\u0103, tuturor le place.<\/p>\n<p>Pentru a m\u0103sura, mai \u00eent\u00e2i ad\u0103uga\u021bi o mul\u021bime de metrici, analiza\u021bi-le \u0219i apoi decide\u021bi ce anume nu v\u0103 mul\u021bume\u0219te \u0219i ce trebuie \u00eembun\u0103t\u0103\u021bit. Pentru a m\u0103sura aceasta, avem un instrument grozav numit Pinba.<\/p>\n<p>Acesta permite colectarea de statistici foarte detaliate de la NGINX pentru fiecare request, codurile de r\u0103spuns \u0219i distribu\u021bia timpilor \u2014 tot ce dori\u021bi. Are leg\u0103turi cu diferite sisteme de analiz\u0103, iar dumneavoastr\u0103 pute\u021bi vizualiza totul frumos.<\/p>\n<p>Mai \u00eent\u00e2i am m\u0103surat \u2014 apoi am \u00eembun\u0103t\u0103\u021bit.<\/p>\n<p>\u00cen continuare. Optimiz\u0103m citirea cu cache-ul, iar scrierea \u2014 cu shardingul, dar acesta este un punct evident.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f53a4777f1a2c7793eba4a72c94263a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen continuare. Dac\u0103 abia acum \u00eencepe\u021bi s\u0103 construi\u021bi sistemul dumneavoastr\u0103, este mult mai bine s\u0103 trata\u021bi fotografiile ca fi\u0219iere imutabile. Deoarece pierde\u021bi imediat o \u00eentreag\u0103 categorie de probleme legate de invalidarea cache-ului, de logica necesar\u0103 pentru a g\u0103si versiunea corect\u0103 a fotografiei \u0219i a\u0219a mai departe.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f345c59681275326cda1320b4f188ce9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS\u0103 presupunem c\u0103 a\u021bi \u00eenc\u0103rcat o sut\u0103, apoi a\u021bi rotit-o, asigura\u021bi-v\u0103 c\u0103 este un fi\u0219ier fizic diferit. Adic\u0103, nu trebuie s\u0103 v\u0103 g\u00e2ndi\u021bi: acum economisesc pu\u021bin spa\u021biu, voi scrie \u00een acela\u0219i fi\u0219ier, voi schimba versiunea. Aceasta nu func\u021bioneaz\u0103 bine, \u0219i ulterior apar multe dureri de cap.<\/p>\n<p>Urm\u0103torul punct. Despre redimensionarea \u00een timpul execu\u021biei.<\/p>\n<p>Anterior, c\u00e2nd utilizatorii \u00eenc\u0103rcau o fotografie, t\u0103iam imediat o mul\u021bime de dimensiuni pentru toate ocaziile, pentru diferi\u021bi clien\u021bi, \u0219i toate erau stocate pe disc. Acum am renun\u021bat la aceasta.<\/p>\n<p>Am p\u0103strat doar trei dimensiuni de baz\u0103: mic\u0103, medie \u0219i mare. Tot restul \u00eel redimension\u0103m din dimensiunea pe care o cere utilizatorul \u00een Uport, pur \u0219i simplu facem downsizing \u0219i \u00eel return\u0103m utilizatorului.<\/p>\n<p>CPU-ul stratului de cache devine mult mai ieftin dec\u00e2t dac\u0103 am regenera constant aceste dimensiuni pe fiecare storage. S\u0103 presupunem c\u0103 dorim s\u0103 ad\u0103ug\u0103m un nou format, aceasta ar dura o lun\u0103 \u2014 s\u0103 rul\u0103m un script peste tot pentru a face totul corect, f\u0103r\u0103 a c\u0103dea clusterele. Adic\u0103, dac\u0103 avem op\u021biunea de a alege acum, este mai bine s\u0103 facem c\u00e2t mai pu\u021bine dimensiuni fizice, dar s\u0103 existe totu\u0219i o anumit\u0103 distribu\u021bie, s\u0103 zicem, trei. Iar restul s\u0103 fie redimensionat \u00een timp real cu ajutorul modulelor disponibile. Acum toate acestea sunt foarte simple \u0219i accesibile.<\/p>\n<p>\u0218i backup-ul incremental asincron este o idee bun\u0103.<\/p>\n<p>A\u0219a cum a ar\u0103tat practica noastr\u0103, acest sistem func\u021bioneaz\u0103 foarte bine cu copierea \u00eent\u00e2rzierilor fi\u0219ierelor modificate.<\/p>\n<p><img decoding=\"async\" alt=\"Arhitectura de stocare \u0219i livrare a fotografiilor \u00een Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0e550721e838654e61e1fa4d08f9bb93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUltimul punct este, de asemenea, evident. Dac\u0103 \u00een infrastructura dumneavoastr\u0103 nu exist\u0103 acum astfel de probleme, dar exist\u0103 ceva care ar putea s\u0103 se defecteze, acesta se va defecta atunci c\u00e2nd va fi supus unei presiuni suplimentare. A\u0219adar, cel mai bine este s\u0103 v\u0103 g\u00e2ndi\u021bi la asta din timp \u0219i s\u0103 evita\u021bi astfel de probleme. Asta am avut de spus.<\/p>\n<h3>Contacte<\/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\/\">Blogul companiei Badoo<\/a><\/noindex><\/p>\n<blockquote><p>Aceast\u0103 prezentare este transcrierea uneia dintre cele mai bune prezent\u0103ri de la conferin\u021ba dezvoltatorilor de sisteme cu sarcini mari <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>. Mai pu\u021bin de o lun\u0103 p\u00e2n\u0103 la conferin\u021ba HighLoad++ 2017.<\/p>\n<p>Avem deja preg\u0103tit <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\">Programul conferin\u021bei<\/a><\/noindex>, iar acum se elaboreaz\u0103 activ programul.<\/p>\n<p>Anul acesta continu\u0103m s\u0103 explor\u0103m tema arhitecturilor \u0219i scal\u0103rii:<\/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\">Cum s\u0103 deservim un miliard de utilizatori \u0219i s\u0103 livr\u0103m terabi\u021bi de trafic<\/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\">Cum s\u0103 rescriem de la zero baza de date a mesajelor personale VKontakte \u0219i s\u0103 migr\u0103m la aceasta f\u0103r\u0103 timp de nefunc\u021bionare<\/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\">Moartea din v\u00e2nzare: cum Yandex.Money a \u00eencercat s\u0103 accelereze \u00eenainte de Black Friday \u0219i s\u0103 reziste<\/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\">Arhitectura rezistent\u0103 la erori a sistemului frontal al b\u0103ncii<\/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\">Arhitectura sistemului de plat\u0103: aproape enterprise<\/a><\/noindex> \/ \u0424\u0438\u043b\u0438\u043f\u043f \u0414\u0435\u043b\u044c\u0433\u044f\u0434\u043e<\/li>\n<\/ul>\n<p>\nDe asemenea, unele dintre aceste materiale sunt folosite de noi \u00een cursul nostru online de formare pentru dezvoltarea sistemelor cu sarcini mari <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> \u2014 este o serie de scrisori, articole, materiale \u0219i videoclipuri atent selectate. Deja avem \u00een manualul nostru peste 30 de materiale unice. Al\u0103tura\u021bi-v\u0103!\n<\/p><\/blockquote>\n<p>Sursa: <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.2.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\/ro\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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\udd47Arhitectura stoc\u0103rii \u0219i livr\u0103rii fotografiilor \u00een Badoo | ProHoster","description":"Artem Denisov (","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/55009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=55009"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/55009\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=55009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=55009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=55009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}