{"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\/fr\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","title":{"rendered":"Architecture de stockage et de partage de photos sur Badoo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur 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 est le plus grand site de rencontres au monde. Actuellement, nous avons environ 330 millions d'utilisateurs enregistr\u00e9s dans le monde entier. Mais ce qui est encore plus important dans le cadre de notre discussion aujourd'hui, c'est que nous stockons environ 3 p\u00e9taoctets de photos d'utilisateurs. Chaque jour, nos utilisateurs t\u00e9l\u00e9chargent environ 3,5 millions de nouvelles photos, et la charge de lecture est d'environ <b>80 000 requ\u00eates par seconde<\/b>. C'est d\u00e9j\u00e0 beaucoup pour notre backend, et il arrive que cela pose des probl\u00e8mes.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4e4690f9b0d95bd76fbbc1cd6805c26c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe vais parler de la conception de ce syst\u00e8me qui stocke et fournit les photos dans l'ensemble, et je donnerai un aper\u00e7u de son \u00e9volution du point de vue du d\u00e9veloppeur. Il y aura un bref retour d'exp\u00e9rience, o\u00f9 je marquerai les principales \u00e9tapes, mais je parlerai plus en d\u00e9tail des solutions que nous utilisons actuellement.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nEt maintenant, commen\u00e7ons.<\/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=\"Lire la vid\u00e9o\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nComme je l'ai d\u00e9j\u00e0 dit, ce sera un retour d'exp\u00e9rience, et pour commencer, prenons l'exemple le plus banal.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/22b9627cda7ccadd9869b64e9d043d89.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous avons une t\u00e2che g\u00e9n\u00e9rale, nous devons recevoir, stocker et fournir les photos des utilisateurs. Dans cette formulation, la t\u00e2che est g\u00e9n\u00e9rale, nous pouvons utiliser n'importe quoi :<\/p>\n<ul>\n<li>un stockage cloud moderne,<\/li>\n<li>une solution cl\u00e9 en main, d'ailleurs, il y en a beaucoup en ce moment ;<\/li>\n<li>nous pouvons configurer plusieurs machines dans notre centre de donn\u00e9es et y installer de grands disques durs pour y stocker les photos.<\/li>\n<\/ul>\n<p>\nBadoo vit historiquement - et maintenant, comme \u00e0 l'\u00e9poque o\u00f9 cela a \u00e9t\u00e9 cr\u00e9\u00e9 - sur ses propres serveurs, \u00e0 l'int\u00e9rieur de nos propres centres de donn\u00e9es. Donc, pour nous, cette option \u00e9tait optimale.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9434fbabada15670297c551066ad7e71.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous avons simplement pris plusieurs machines, les avons appel\u00e9es \u00ab photos \u00bb, et nous avons cr\u00e9\u00e9 un cluster qui stocke les photos. Mais il semble qu'il manque quelque chose. Pour que tout cela fonctionne, il faut d'une mani\u00e8re ou d'une autre d\u00e9terminer sur quelle machine quelles photos nous allons stocker. Et l\u00e0 aussi, pas besoin de r\u00e9inventer la roue.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/36258e7107fd8c60f7e9e563a2cb681c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous ajoutons \u00e0 notre stockage avec les informations sur les utilisateurs un champ. Ce sera la cl\u00e9 de partitionnement. Dans notre cas, nous l'avons appel\u00e9 place_id, et cet id de lieu indique o\u00f9 sont stock\u00e9es les photos des utilisateurs. Nous \u00e9tablissons des cartes.<\/p>\n<p>Au d\u00e9but, cela peut m\u00eame se faire manuellement : nous disons que la photo de cet utilisateur avec cet emplacement sera enregistr\u00e9e sur ce serveur. Gr\u00e2ce \u00e0 cette carte, nous savons toujours quand un utilisateur t\u00e9l\u00e9charge une photo, o\u00f9 la sauvegarder, et d'o\u00f9 la d\u00e9livrer.<\/p>\n<p>C'est un sch\u00e9ma absolument trivial, mais il pr\u00e9sente suffisamment d'avantages. D'abord, c'est simple, comme je l'ai d\u00e9j\u00e0 mentionn\u00e9, et ensuite, avec cette approche, nous pouvons facilement \u00e9voluer horizontalement, simplement en ajoutant de nouveaux serveurs et en les int\u00e9grant \u00e0 la carte. Il n'est pas n\u00e9cessaire de faire autre chose.<\/p>\n<p>Et c'est rest\u00e9 comme \u00e7a pendant un certain temps.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3effb442702f162f7bad9c18ec54392e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'\u00e9tait vers 2009. Nous avons livr\u00e9 des machines, livr\u00e9...<\/p>\n<p>Et \u00e0 un certain moment, nous avons commenc\u00e9 \u00e0 remarquer que ce sch\u00e9ma avait certains inconv\u00e9nients. Quels inconv\u00e9nients ?<\/p>\n<p>Tout d'abord, c'est une capacit\u00e9 limit\u00e9e. Nous ne pouvons pas mettre autant de disques durs que nous le souhaiterions sur un seul serveur physique. Avec le temps et la croissance du dataset, cela est devenu un probl\u00e8me.<\/p>\n<p>Et deuxi\u00e8mement. C'est une configuration atypique de machines, car il est difficile de les r\u00e9utiliser dans d'autres clusters, elles sont assez sp\u00e9cifiques, c'est-\u00e0-dire qu'elles doivent \u00eatre peu performantes, mais en m\u00eame temps avoir un grand disque dur.<\/p>\n<p>Tout cela \u00e9tait valable en 2009, mais en principe, ces exigences sont toujours d'actualit\u00e9 aujourd'hui. Nous avons une r\u00e9trospective, donc en 2009, tout cela \u00e9tait d\u00e9j\u00e0 probl\u00e9matique.<\/p>\n<p>Et le dernier point - c'est le prix.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e49010eaeab139199d8fe010caa65bf0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00c0 l'\u00e9poque, le prix \u00e9tait tr\u00e8s \u00e9lev\u00e9, et nous devions chercher des alternatives. C'est-\u00e0-dire que nous devions mieux utiliser \u00e0 la fois l'espace dans les centres de donn\u00e9es et les serveurs physiques sur lesquels tout cela \u00e9tait h\u00e9berg\u00e9. Nos ing\u00e9nieurs syst\u00e8mes ont entrepris une grande \u00e9tude, o\u00f9 ils ont r\u00e9\u00e9valu\u00e9 de nombreuses options. Ils ont examin\u00e9 des syst\u00e8mes de fichiers en cluster, comme PolyCeph et Lustre. Il y avait des probl\u00e8mes de performance et une exploitation assez complexe. Ils ont abandonn\u00e9 cette id\u00e9e. Ils ont essay\u00e9 de monter l'ensemble du dataset via NFS sur chaque machine, afin de tenter de le mettre \u00e0 l'\u00e9chelle. La lecture n'a pas bien fonctionn\u00e9 non plus, ils ont essay\u00e9 diff\u00e9rentes solutions de diff\u00e9rents fournisseurs.<\/p>\n<p>Et finalement, nous avons d\u00e9cid\u00e9 d'utiliser ce qu'on appelle un Storage Area Network.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/e99402fa641f3bd5fc8d57a9f8995642.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCe sont de grands syst\u00e8mes de stockage de donn\u00e9es (SHD) qui sont sp\u00e9cialement con\u00e7us pour le stockage de volumes importants de donn\u00e9es. Ils se composent de racks avec des disques mont\u00e9s sur des machines de sortie finales via fibre optique. Ainsi, nous avons un certain pool de machines, relativement petit, et ces SHD, qui sont transparents pour notre logique de sortie, c'est-\u00e0-dire pour notre nginx ou tout autre service, traitent les requ\u00eates concernant ces photos.<\/p>\n<p>Cette solution pr\u00e9sente des avantages \u00e9vidents. Il s'agit de SHD. Elle est orient\u00e9e vers le stockage de photos. Cela revient moins cher que d'\u00e9quiper simplement des machines avec des disques durs.<\/p>\n<p>Le deuxi\u00e8me avantage. <\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7fd2e7d629cc239096b14c68be5f76bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est que la capacit\u00e9 est devenue beaucoup plus grande, c'est-\u00e0-dire que nous pouvons maintenant h\u00e9berger beaucoup plus de stockage dans un volume beaucoup plus petit.<\/p>\n<p>Mais il y avait aussi des inconv\u00e9nients qui se sont rapidement manifest\u00e9s. Avec l'augmentation du nombre d'utilisateurs et la charge sur ce syst\u00e8me, des probl\u00e8mes de performance ont commenc\u00e9 \u00e0 appara\u00eetre. Et le probl\u00e8me est assez \u00e9vident : tout SHD destin\u00e9 \u00e0 stocker de nombreuses photos dans un petit volume souffre g\u00e9n\u00e9ralement d'intensit\u00e9 de lecture. Cela est en fait valable pour tout stockage cloud, et peu importe quoi. Actuellement, nous n'avons pas de stockage id\u00e9al qui soit infiniment \u00e9volutif, dans lequel nous pourrions mettre tout ce que nous voulons, et qui supporterait tr\u00e8s bien les lectures, en particulier les lectures al\u00e9atoires.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/566e836e2fe13a2a3d040ae3fa865d6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComme dans le cas de nos photos, car les photos sont demand\u00e9es de mani\u00e8re non s\u00e9quentielle, ce qui affecte fortement leur performance.<\/p>\n<p>M\u00eame avec les chiffres d'aujourd'hui, si nous d\u00e9passons environ 500 RPS pour les photos sur la machine \u00e0 laquelle le stockage est connect\u00e9, des probl\u00e8mes commencent d\u00e9j\u00e0 \u00e0 appara\u00eetre. Et c'\u00e9tait un probl\u00e8me pour nous, car le nombre d'utilisateurs augmente, tout ne peut que s'aggraver. Nous devons optimiser cela d'une mani\u00e8re ou d'une autre.<\/p>\n<p>Pour optimiser, \u00e0 l'\u00e9poque, nous avons d\u00e9cid\u00e9, \u00e9videmment, d'examiner le profil de charge - que se passe-t-il, ce qui doit \u00eatre optimis\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d67310e6b90c4ee1337065790576c9a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEt ici, tout joue en notre faveur.<\/p>\n<p>J'ai d\u00e9j\u00e0 dit dans ma premi\u00e8re diapositive : nous avons 80 000 requ\u00eates par seconde en lecture pour seulement 3,5 millions de t\u00e9l\u00e9chargements par jour. Donc, il y a une diff\u00e9rence de trois ordres de grandeur. Il est clair qu'il faut optimiser la lecture et c'est pratiquement compr\u00e9hensible comment.<\/p>\n<p>Il y a aussi un petit d\u00e9tail. La sp\u00e9cificit\u00e9 du service est telle qu'une personne s'inscrit, t\u00e9l\u00e9charge une photo, puis commence \u00e0 consulter activement d'autres personnes, \u00e0 les liker, et elle est montr\u00e9e \u00e0 d'autres utilisateurs. Ensuite, elle trouve ou ne trouve pas de partenaire, cela d\u00e9pend, et pour un certain temps, elle arr\u00eate d'utiliser le service. \u00c0 ce moment-l\u00e0, lorsque son utilisation est active, ses photos sont tr\u00e8s demand\u00e9es - elles sont vues par beaucoup de gens. D\u00e8s qu'elle arr\u00eate, elle sort rapidement de ces affichages intensifs, comme avant, et ses photos sont pratiquement moins demand\u00e9es.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/dcc7e306055d8f2b0895f24679bfc3e2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est-\u00e0-dire que nous avons un tr\u00e8s petit dataset actif. Mais il y a en m\u00eame temps beaucoup de demandes \u00e0 son \u00e9gard. Il s'impose donc de mani\u00e8re \u00e9vidente d'ajouter un cache.<\/p>\n<p>Un cache avec LRU r\u00e9soudra tous nos probl\u00e8mes. Que faisons-nous ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/2bd0c88a97d928f386db21549fc02500.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous ajoutons devant notre grand cluster de stockage un autre cluster relativement petit, que nous appelons les photok\u00e9shes (photoscache). C'est en fait juste un proxy de mise en cache.<\/p>\n<p>Comment cela fonctionne-t-il de l'int\u00e9rieur ? Voici notre utilisateur, voici le stockage. Tout est comme avant. Que rajoutons-nous entre eux ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7b7b5f102f1c012b2aef8f02ec731fac.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est simplement une machine avec un disque local physique qui est rapide. C'est avec un SSD, par exemple. Et sur ce disque, il y a un cache local.<\/p>\n<p>\u00c0 quoi cela ressemble-t-il ? L'utilisateur envoie une demande pour une photo. NGINX la cherche d'abord dans le cache local. Si ce n'est pas l\u00e0, il fait simplement un proxy_pass vers notre stockage, t\u00e9l\u00e9charge la photo de l\u00e0-bas et la donne \u00e0 l'utilisateur.<\/p>\n<p>Mais c'est tr\u00e8s banal et il n'est pas clair ce qui se passe \u00e0 l'int\u00e9rieur. Cela fonctionne plus ou moins comme \u00e7a.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/46be24df171d1008e2a9099b7e4c9be6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe cache est logiquement divis\u00e9 en trois couches. Quand je dis \u00ab trois couches \u00bb, cela ne signifie pas qu'il y a un syst\u00e8me complexe. Non, ce sont simplement trois r\u00e9pertoires dans le syst\u00e8me de fichiers :<\/p>\n<ol>\n<li>C'est un buffer o\u00f9 atterrissent les photos nouvellement t\u00e9l\u00e9charg\u00e9es du proxy.<\/li>\n<li>C'est un cache chaud, o\u00f9 se trouvent les photos qui sont actuellement activement demand\u00e9es.<\/li>\n<li>Et un cache froid, o\u00f9 les photos sont progressivement pouss\u00e9es hors du chaud lorsque le nombre de requ\u00eates diminue.<\/li>\n<\/ol>\n<p>\nPour que cela fonctionne, nous devons g\u00e9rer ce cache, remettre les photos dans celui-ci, etc. C'est aussi un processus tr\u00e8s primitif.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/9b16fe3e99a5f88f06169f6e5eedf2b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNginx \u00e9crit simplement sur le RAMDisk access.log pour chaque requ\u00eate, indiquant le chemin de la photo qu'il sert actuellement (un chemin relatif, bien s\u00fbr), ainsi que le segment qui l'a servi. Par exemple, il pourrait \u00eatre \u00e9crit \u00ab photo 1 \u00bb et ensuite soit le tampon, soit le cache chaud, soit le cache froid, soit un proxy.<\/p>\n<p>En fonction de cela, nous devons prendre une d\u00e9cision sur ce qu'il faut faire avec la photo.<\/p>\n<p>Sur chaque machine, un petit d\u00e9mon fonctionne en permanence, lisant ce log et stockant dans sa m\u00e9moire des statistiques sur l'utilisation de certaines photos.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0dceda5e5ff432d1609520f0c152f152.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIl collecte simplement ces donn\u00e9es, maintient des compteurs et effectue p\u00e9riodiquement les actions suivantes. Les photographies tr\u00e8s demand\u00e9es, qui re\u00e7oivent de nombreuses requ\u00eates, sont d\u00e9plac\u00e9es vers le cache chaud, peu importe o\u00f9 elles se trouvent.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/941c13ecfea88372f3a7eb62d81b0c4e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLes photos qui sont rarement demand\u00e9es et qui ont commenc\u00e9 \u00e0 \u00eatre moins demand\u00e9es sont progressivement pouss\u00e9es du cache chaud vers le cache froid.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a07235246995ad2fa4e6aeccae23a629.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEt quand l'espace dans notre cache est \u00e9puis\u00e9, nous commen\u00e7ons simplement \u00e0 supprimer tout du cache froid sans discernement. Et cela, d'ailleurs, fonctionne assez bien.<\/p>\n<p>Pour que la photo soit imm\u00e9diatement enregistr\u00e9e lors du proxy dans le tampon, nous utilisons la directive proxy_store, et le tampon est \u00e9galement un RAMDisk, c'est-\u00e0-dire que pour l'utilisateur, cela fonctionne tr\u00e8s rapidement. C'est en ce qui concerne les entrailles du serveur de cache lui-m\u00eame.<\/p>\n<p>Il reste la question de savoir comment r\u00e9partir les requ\u00eates entre ces serveurs.<\/p>\n<p>Disons qu'il y a un cluster de vingt machines de stockage et trois serveurs de cache (c'est ainsi que les choses se sont pass\u00e9es).<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6bc970b687701f3b6d57e153e3abed18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous devons trouver un moyen de d\u00e9terminer quelles requ\u00eates concernent quelles photos et o\u00f9 les diriger.<\/p>\n<p>La mani\u00e8re la plus simple serait de faire un Round Robin. Ou de le faire au hasard ?<\/p>\n<p>Cela pr\u00e9sente \u00e9videmment un certain nombre d'inconv\u00e9nients, car nous allons utiliser le cache de mani\u00e8re tr\u00e8s inefficace dans cette situation. Les requ\u00eates seront dirig\u00e9es vers des machines al\u00e9atoires : ici, elle est en cache, mais sur la machine voisine, elle n'y est d\u00e9j\u00e0 plus. Et tout cela, si cela fonctionne, fonctionnera tr\u00e8s mal, m\u00eame avec un petit nombre de machines dans le cluster.<\/p>\n<p>Nous devons n\u00e9cessairement d\u00e9terminer sur quel serveur diriger chaque requ\u00eate.<\/p>\n<p>Il existe une m\u00e9thode simple. Nous prenons le hachage de l'URL ou le hachage de notre cl\u00e9 de partitionnement, qui se trouve dans l'URL, et nous le divisons par le nombre de serveurs. Cela fonctionnera-t-il ? Oui.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/794a82ac1268b651ab936f0225b802a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est-\u00e0-dire qu'il y a toujours un request \u00e0 100 % pour une \u00ab example_url \u00bb qui atterrit sur le serveur avec l'index \u00ab 2 \u00bb, et le cache est constamment utilis\u00e9 de mani\u00e8re optimale.<\/p>\n<p>Mais un probl\u00e8me survient avec le resharding dans ce sch\u00e9ma. Par resharding, j'entends le changement du nombre de serveurs.<\/p>\n<p>Supposons que notre cluster de cache ne parvienne plus \u00e0 suivre, et que nous avons d\u00e9cid\u00e9 d'ajouter une machine suppl\u00e9mentaire.<\/p>\n<p>Ajoutons-en une.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5f2fcba4c4f267c069811c3677bd0213.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous avons d\u00e9sormais tout divis\u00e9 non plus par trois, mais par quatre. Ainsi, presque toutes les cl\u00e9s que nous avions auparavant, presque toutes les URL, se trouvent d\u00e9sormais sur d'autres serveurs. Tout le cache a \u00e9t\u00e9 invalid\u00e9 instantan\u00e9ment. Toutes les requ\u00eates se sont dirig\u00e9es vers notre cluster de stockage, il a commenc\u00e9 \u00e0 avoir des probl\u00e8mes, avec des pannes de service et des utilisateurs m\u00e9contents. Nous ne voulons vraiment pas que cela se produise.<\/p>\n<p>Cette option ne nous convient pas non plus.<\/p>\n<p>Donc, que devons-nous faire ? Nous devons d'une mani\u00e8re ou d'une autre utiliser le cache efficacement, atterrissant constamment une requ\u00eate sur le m\u00eame serveur, tout en restant r\u00e9silients au resharding. Et il existe une solution, qui n'est pas si compliqu\u00e9e. Elle s'appelle le consistent hashing.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1380758686274df9755a7ebf7d1c8753.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00c0 quoi cela ressemble-t-il ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/44f97abfac46fa9f361055548819e8a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous prenons une certaine fonction de la cl\u00e9 de sharding et \u00e9talons toutes ses valeurs sur un cercle. Autrement dit, au point 0, nous avons ses valeurs minimales et maximales qui se rejoignent. Ensuite, nous pla\u00e7ons tous nos serveurs sur ce m\u00eame cercle de mani\u00e8re \u00e0 ce que :<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d470ec615a789913a6baa2726b05acea.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nChaque serveur est d\u00e9termin\u00e9 par un point, et le secteur qui m\u00e8ne jusqu'\u00e0 lui dans le sens horaire est donc g\u00e9r\u00e9 par cet h\u00f4te. Lorsque nous recevons des requ\u00eates, nous voyons imm\u00e9diatement que, par exemple, la requ\u00eate A a un hash comme celui-ci \u2014 et elle est trait\u00e9e par le serveur 2. La requ\u00eate B \u2014 par le serveur 3. Et ainsi de suite.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fcdbd1caa9f1162cf02e8b0a1c79cb74.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nQue se passe-t-il dans cette situation lors du resharding ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7386cda826e9419d5f8a9a0d6d6703c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous n'invalidons pas tout le cache, comme auparavant, et nous ne d\u00e9pla\u00e7ons pas toutes les cl\u00e9s, mais nous d\u00e9pla\u00e7ons chaque secteur sur une courte distance de telle sorte que l'espace lib\u00e9r\u00e9, pour ainsi dire, puisse accueillir notre sixi\u00e8me serveur que nous voulons ajouter, et nous l'ajoutons l\u00e0.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8680e0cf023ce911b4d162e9102c0545.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBien s\u00fbr, dans une telle situation, les cl\u00e9s sont \u00e9galement affect\u00e9es. Mais elles le sont beaucoup moins qu'auparavant. Nous voyons que nos deux premi\u00e8res cl\u00e9s sont rest\u00e9es sur leurs serveurs, et que seul le serveur de mise en cache a chang\u00e9 pour la derni\u00e8re cl\u00e9. Cela fonctionne assez efficacement, et si vous ajoutez progressivement de nouveaux h\u00f4tes, il n'y a pas de gros probl\u00e8me ici. Vous ajoutez petit \u00e0 petit, attendez que le cache se remplisse \u00e0 nouveau, et tout fonctionne correctement.<\/p>\n<p>Une seule question demeure en cas de pannes. Supposons qu'une de nos machines soit tomb\u00e9e en panne.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8e3301af782ce8983716c4bc9add79a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEt nous pr\u00e9f\u00e9rerions ne pas avoir \u00e0 r\u00e9g\u00e9n\u00e9rer cette carte \u00e0 ce moment-l\u00e0, \u00e0 invalider une partie du cache, etc., si, par exemple, la machine red\u00e9marre, et que nous devons traiter les requ\u00eates. Nous maintenons simplement un cache photo de secours sur chaque site, qui joue le r\u00f4le de remplacement pour toute machine qui est actuellement hors service. Et si soudainement un de nos serveurs devient indisponible, le trafic est redirig\u00e9 vers celui-ci. Bien entendu, il n'y a pas de cache l\u00e0-bas, c'est-\u00e0-dire qu'il est froid, mais au moins les requ\u00eates des utilisateurs sont trait\u00e9es. Si c'est un court intervalle, nous le g\u00e9rons tr\u00e8s bien. Il y a juste une charge accrue sur le stockage. Si l'intervalle est long, nous pouvons alors d\u00e9cider de retirer ce serveur de la carte ou non, ou peut-\u00eatre de le remplacer par un autre.<\/p>\n<p>C'est concernant le syst\u00e8me de mise en cache. Voyons les r\u00e9sultats.<\/p>\n<p>Il semblerait qu'il n'y ait rien de compliqu\u00e9 ici. Mais cette m\u00e9thode de gestion du cache nous a donn\u00e9 un taux de r\u00e9ussite d'environ 98 %. C'est-\u00e0-dire que sur ces 80 000 requ\u00eates par seconde, seulement 1600 atteignent les stockages, et cela repr\u00e9sente une charge tout \u00e0 fait normale, qu'ils g\u00e8rent sans souci, nous avons toujours une marge.<\/p>\n<p>Nous avons plac\u00e9 ces serveurs dans trois de nos DC, et nous avons obtenu trois points de pr\u00e9sence - Prague, Miami et Hong Kong.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/64eef492b65a014d8ba3c808b6579b41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAinsi, ils sont plus ou moins situ\u00e9s localement par rapport \u00e0 chacun de nos march\u00e9s cibles.<\/p>\n<p>Et en bonus, nous avons obtenu ce proxy de mise en cache, dont le CPU est en fait sous-utilis\u00e9, car pour la restitution du contenu, il n'est pas si n\u00e9cessaire. Et l\u00e0, gr\u00e2ce \u00e0 NGINX + Lua, nous avons r\u00e9alis\u00e9 beaucoup de logique utilitaire.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b65c609df5e1985240d04ee65a3e4f55.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPar exemple, nous pouvons exp\u00e9rimenter avec le webp ou le jpeg progressif (ce sont des formats modernes et efficaces), observer comment cela affecte le trafic, prendre des d\u00e9cisions, les activer pour certains pays, etc. ; effectuer un redimensionnement dynamique ou un recadrage des photos \u00e0 la vol\u00e9e.<\/p>\n<p>C'est un bon cas d'utilisation, lorsque vous avez par exemple une application mobile qui affiche des photos, et l'application mobile ne veut pas utiliser le CPU du client pour demander une grande photo et la redimensionner ensuite \u00e0 une certaine taille pour l'ins\u00e9rer dans la vue. Nous pouvons simplement sp\u00e9cifier dynamiquement certains param\u00e8tres dans l'URL, disons dans UPort, et le cache des photos redimensionnera la photo lui-m\u00eame. En r\u00e8gle g\u00e9n\u00e9rale, il choisira la taille qui est physiquement disponible sur le disque, la plus proche de celle demand\u00e9e, et la r\u00e9duira dans des coordonn\u00e9es sp\u00e9cifiques.<\/p>\n<blockquote><p>Au fait, nous avons rendu publiques les vid\u00e9os des cinq derni\u00e8res ann\u00e9es des conf\u00e9rences sur les syst\u00e8mes \u00e0 forte charge. <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex>. Regardez, \u00e9tudiez, partagez et abonnez-vous \u00e0 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/profyclub\">la cha\u00eene YouTube.<\/a><\/noindex>.<\/p><\/blockquote>\n<p>\nNous pouvons \u00e9galement y ajouter beaucoup de logique produit. Par exemple, nous pouvons ajouter diff\u00e9rents filigranes selon les param\u00e8tres de l'URL, nous pouvons flouter les photos, les rendre floues ou pixelis\u00e9es. C'est quand nous voulons montrer la photo d'une personne, mais nous ne voulons pas montrer son visage, cela fonctionne tr\u00e8s bien, tout cela est impl\u00e9ment\u00e9 ici.<\/p>\n<p>Qu'avons-nous obtenu ? Nous avons obtenu trois points de pr\u00e9sence, un bon taux de r\u00e9ussite, et en m\u00eame temps, notre CPU sur ces machines ne reste pas inactif. Il est d\u00e9sormais, bien s\u00fbr, plus important qu'auparavant. Nous devons mettre en place des machines plus puissantes, mais cela en vaut la peine.<\/p>\n<p>En ce qui concerne la distribution des photos, tout cela est assez clair et \u00e9vident. Je pense que je ne fais pas d\u00e9couvrir l'Am\u00e9rique, cela fonctionne pratiquement avec n'importe quel CDN.<\/p>\n<p>Et, probablement, l'auditeur averti pourrait se demander : pourquoi ne pas simplement tout remplacer par un CDN ? Cela donnerait \u00e0 peu pr\u00e8s le m\u00eame r\u00e9sultat, tous les CDN modernes savent faire cela. Et ici, plusieurs raisons sont \u00e0 consid\u00e9rer.<\/p>\n<p>La premi\u00e8re concerne les photos.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/592c10eb74d46191bfcedec120f68556.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est l'un des points cl\u00e9s de notre infrastructure, et nous avons besoin d'un maximum de contr\u00f4le sur elles. Si c'est une solution d'un vendeur tiers, et que vous n'avez aucun pouvoir sur celle-ci, cela va \u00eatre assez difficile \u00e0 g\u00e9rer lorsque vous avez un grand ensemble de donn\u00e9es et un tr\u00e8s grand volume de requ\u00eates utilisateurs.<\/p>\n<p>Je vais donner un exemple. Actuellement, sur notre infrastructure, nous pouvons, par exemple, en cas de probl\u00e8mes ou de vibrations souterraines, acc\u00e9der \u00e0 la machine, faire un d\u00e9bogage, pour ainsi dire. Nous pouvons ajouter la collecte de certaines m\u00e9triques qui ne nous concernent que, nous pouvons exp\u00e9rimenter d'une mani\u00e8re ou d'une autre, voir comment cela affecte les graphiques, et ainsi de suite. Aujourd'hui, beaucoup de statistiques sont collect\u00e9es sur ce cluster de mise en cache. Nous les examinons p\u00e9riodiquement et \u00e9tudions en profondeur certaines anomalies. Si cela se passait du c\u00f4t\u00e9 du CDN, ce serait beaucoup plus difficile \u00e0 contr\u00f4ler. Ou, par exemple, en cas d'accident, nous savons ce qui s'est pass\u00e9, nous savons comment y faire face et comment y rem\u00e9dier. Voici la premi\u00e8re conclusion.<\/p>\n<p>La deuxi\u00e8me conclusion est plut\u00f4t historique, car le syst\u00e8me \u00e9volue depuis longtemps, et de nombreuses exigences commerciales ont exist\u00e9 \u00e0 diff\u00e9rentes \u00e9tapes, et elles ne correspondent pas toujours \u00e0 la conception du CDN.<\/p>\n<p>Et le point qui d\u00e9coule de ce qui pr\u00e9c\u00e8de \u2013<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/007cf3aed2f9cc12185fc3865bf9d196.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est que sur les caches photo, nous avons beaucoup de logiques sp\u00e9cifiques, que l'on ne peut pas toujours ajouter sur demande. Il est peu probable qu'un CDN ajoute des choses personnalis\u00e9es \u00e0 votre demande. Par exemple, le cryptage des URLs, si vous ne voulez pas que le client puisse modifier quoi que ce soit. Vous souhaitez changer l'URL sur le serveur et la crypter, puis passer ici certains param\u00e8tres dynamiques.<\/p>\n<p>Quelle conclusion s'impose ? Dans notre cas, le CDN n'est pas une tr\u00e8s bonne alternative.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/cfc2963cca2357cf6b0f63419a4dc436.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEt dans votre cas, si vous avez des exigences commerciales sp\u00e9cifiques, vous pouvez tout \u00e0 fait mettre en \u0153uvre ce que je vous ai montr\u00e9. Et cela fonctionnera tr\u00e8s bien avec un profil de charge similaire.<\/p>\n<p>Mais si vous avez une solution g\u00e9n\u00e9rale, et que le probl\u00e8me n'est pas tr\u00e8s particulier, vous pouvez tout \u00e0 fait opter pour un CDN. Ou si pour vous, le temps et les ressources sont bien plus importants que le contr\u00f4le.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b76d25404918a5d0d8bf1d6644c8d873.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEt les CDN modernes ont pratiquement tout ce dont je vous ai parl\u00e9 maintenant. \u00c0 l'exception de plus ou moins certaines fonctionnalit\u00e9s.<\/p>\n<p>Cela concerne la livraison des photographies.<\/p>\n<p>Passons maintenant un peu plus loin dans notre r\u00e9trospective et parlons du stockage.<\/p>\n<p>L'ann\u00e9e 2013 avan\u00e7ait.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f218bfc899512041967842430c02aa9b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLes serveurs de cache ont \u00e9t\u00e9 ajout\u00e9s, les probl\u00e8mes de performance ont disparu. Tout va bien. Le dataset augmente. En 2013, nous avions environ 80 serveurs connect\u00e9s aux syst\u00e8mes de stockage, et environ 40 serveurs de cache dans chaque centre de donn\u00e9es. Cela repr\u00e9sente 560 t\u00e9raoctets de donn\u00e9es par centre de donn\u00e9es, soit environ un p\u00e9taoctet au total.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef741ba4a9164e6940f55e93dfb46ef0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAvec la croissance du dataset, les co\u00fbts op\u00e9rationnels ont \u00e9galement commenc\u00e9 \u00e0 augmenter consid\u00e9rablement. Comment cela se manifestait-il ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6cf5e489a4e97bc6e26fc6d4d16505b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDans ce sch\u00e9ma, qui est illustr\u00e9 \u2014 avec le SAN, les machines connect\u00e9es \u00e0 celui-ci et les caches \u2014 il y a de nombreux points de d\u00e9faillance. Si nous avons d\u00e9j\u00e0 r\u00e9ussi \u00e0 g\u00e9rer les d\u00e9faillances des serveurs de cache, qui sont plut\u00f4t pr\u00e9visibles et compr\u00e9hensibles, la situation du c\u00f4t\u00e9 du stockage \u00e9tait beaucoup plus probl\u00e9matique.<\/p>\n<p>Tout d'abord, le Storage Area Network (SAN) lui-m\u00eame peut tomber en panne.<\/p>\n<p>Deuxi\u00e8mement, il est connect\u00e9 par fibre optique aux machines finales. Il peut y avoir des probl\u00e8mes avec les cartes optiques et les commutateurs.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/6959b79284c5b1244a70a1d64f191893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBien s\u00fbr, il n'y en a pas autant qu'avec le SAN lui-m\u00eame, mais ce sont tout de m\u00eame des points de d\u00e9faillance.<\/p>\n<p>Ensuite, il y a la machine elle-m\u00eame, qui est connect\u00e9e au stockage. Elle peut \u00e9galement tomber en panne.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/1801cb502663a4de14329a5e67dfed79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous avons donc un total de trois points de d\u00e9faillance.<\/p>\n<p>En plus des points de d\u00e9faillance, il y a la gestion lourde des syst\u00e8mes de stockage.<\/p>\n<p>C'est un syst\u00e8me complexe multi-composants, et il est difficile pour les ing\u00e9nieurs syst\u00e8mes d'y faire face.<\/p>\n<p>Et enfin, le point le plus important. Si l'une de ces trois points rencontre une d\u00e9faillance, nous avons une probabilit\u00e9 non nulle de perdre des donn\u00e9es utilisateur, car le syst\u00e8me de fichiers peut \u00eatre endommag\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/4bf8bc1c73a2beef74cb4ee0ee45679b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSupposons que notre syst\u00e8me de fichiers ait \u00e9t\u00e9 endommag\u00e9. Sa r\u00e9cup\u00e9ration prend, tout d'abord, beaucoup de temps \u2014 cela peut prendre une semaine avec un grand volume de donn\u00e9es. Et ensuite, nous obtiendrons probablement un tas de fichiers incompr\u00e9hensibles, qu'il faudra d'une mani\u00e8re ou d'une autre faire correspondre aux photos des utilisateurs. Et nous risquons de perdre des donn\u00e9es. Le risque est suffisamment \u00e9lev\u00e9. Plus de telles situations se produisent souvent, et plus il y a de probl\u00e8mes dans toute cette cha\u00eene, plus ce risque augmente.<\/p>\n<p>Il fallait faire quelque chose. Et nous avons d\u00e9cid\u00e9 qu'il fallait simplement sauvegarder les donn\u00e9es. C'est en fait une solution \u00e9vidente et bonne. Que avons-nous fait ?<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f80ec2b65003c40bd2fabf88966b3e05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVoici \u00e0 quoi ressemblait notre serveur, qui \u00e9tait connect\u00e9 au stockage auparavant. C'est une seule partition principale, c'est simplement un dispositif de bloc qui repr\u00e9sente en fait un montage sur un stockage distant par fibre optique.<\/p>\n<p>Nous avons simplement ajout\u00e9 une seconde partition.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d3dba75ef477269d92145cd69d587527.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous avons install\u00e9 un deuxi\u00e8me stockage \u00e0 c\u00f4t\u00e9 (heureusement, ce n'est pas si co\u00fbteux), et nous l'avons appel\u00e9 section de sauvegarde. Il est \u00e9galement connect\u00e9 par fibre optique, sur la m\u00eame machine. Mais nous devons somehow synchroniser les donn\u00e9es entre eux.<\/p>\n<p>Ici, nous cr\u00e9ons simplement une file d'attente asynchrone \u00e0 c\u00f4t\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/67bced2b45c589009cfb01a1c21398a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nElle n'est pas tr\u00e8s charg\u00e9e. Nous savons que nous avons peu d'enregistrements. La file d'attente est simplement un tableau dans MySQL, o\u00f9 s'\u00e9crivent des lignes du type \u00abil faut sauvegarder cette photo\u00bb. \u00c0 chaque changement ou lors d'un upload, nous copions de la section principale vers la sauvegarde avec un worker asynchrone ou simplement un worker d'arri\u00e8re-plan.<\/p>\n<p>Et ainsi, nous avons toujours deux sections coh\u00e9rentes. M\u00eame si une partie de ce syst\u00e8me tombe en panne, nous pouvons toujours \u00e9changer la section principale avec la sauvegarde, et tout continue de fonctionner.<\/p>\n<p>Mais \u00e0 cause de cela, la charge de lecture augmente consid\u00e9rablement, car en plus des clients qui lisent \u00e0 partir de la section principale, puisque d'abord ils regardent la photo l\u00e0 (elle est plus r\u00e9cente), puis ils cherchent sur la sauvegarde, si ils ne la trouvent pas (mais c'est simplement NGINX qui le fait), notre syst\u00e8me de sauvegarde lit \u00e9galement \u00e0 partir de la section principale. Ce n'est pas une goulot d'\u00e9tranglement, mais nous ne voulions pas augmenter la charge, simplement pour rien.<\/p>\n<p>Et nous avons ajout\u00e9 un troisi\u00e8me disque, qui est un petit SSD, et nous l'avons appel\u00e9 buffer.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd35481822b4170087e5f670bf338dc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComment cela fonctionne maintenant.<\/p>\n<p>L'utilisateur upload une photo sur le buffer, ensuite un \u00e9v\u00e9nement est envoy\u00e9 dans la file d'attente disant qu'il faut la copier sur les deux sections. Elle est copi\u00e9e, et la photo vit un certain temps (disons, un jour) sur le buffer, puis est purg\u00e9e. Cela am\u00e9liore consid\u00e9rablement l'exp\u00e9rience utilisateur, car g\u00e9n\u00e9ralement, apr\u00e8s avoir t\u00e9l\u00e9charg\u00e9 la photo, les requ\u00eates commencent \u00e0 arriver imm\u00e9diatement, ou il actualise la page lui-m\u00eame. Mais cela d\u00e9pend de l'application qui effectue l'upload.<\/p>\n<p>Ou, par exemple, d'autres personnes qui commencent \u00e0 la voir envoient imm\u00e9diatement des requ\u00eates pour cette photo. Elle n'est pas encore en cache, la premi\u00e8re requ\u00eate se produit tr\u00e8s rapidement. En fait, c'est la m\u00eame chose qu'avec le cache photo. Le stockage lent n'est pas du tout impliqu\u00e9. Et quand elle sera purg\u00e9e apr\u00e8s un jour, elle sera soit d\u00e9j\u00e0 mise en cache sur notre couche de mise en cache, soit elle n'est probablement plus n\u00e9cessaire. C'est-\u00e0-dire que l'exp\u00e9rience utilisateur ici s'est consid\u00e9rablement am\u00e9lior\u00e9e gr\u00e2ce \u00e0 ces simples manipulations.<\/p>\n<p>Eh bien, et surtout : nous avons cess\u00e9 de perdre des donn\u00e9es.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/526f549457dd0c438f32b0adb76df76c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDisons simplement que nous avons cess\u00e9 <em>potentiellement<\/em> perdre des donn\u00e9es, car nous ne les avons pas vraiment perdues. Mais le risque \u00e9tait l\u00e0. Nous voyons que cette solution, bien qu'elle soit \u00e9vidente, ressemble un peu \u00e0 un simple apaisement des sympt\u00f4mes du probl\u00e8me, au lieu de le r\u00e9soudre compl\u00e8tement. Et il reste encore certains probl\u00e8mes ici.<\/p>\n<p>Tout d'abord, il y a le point de d\u00e9faillance du serveur physique sur lequel tout ce mat\u00e9riel fonctionne, il n'a pas disparu.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0eb3d292655a7edf912793ed81e8931c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDeuxi\u00e8mement, il y a encore des probl\u00e8mes avec les SAN, leur maintenance lourde, etc. Ce n'\u00e9tait pas un facteur critique, mais nous voulions essayer de vivre sans cela.<\/p>\n<p>Et nous avons fait une troisi\u00e8me version (en r\u00e9alit\u00e9, c'est la deuxi\u00e8me version) \u2014 une version de sauvegarde. \u00c0 quoi cela ressemblait-il ?<\/p>\n<p>C'est ce qui \u00e9tait -<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/8b1749b6feed200f8a64529ee2316c1a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNos principaux probl\u00e8mes viennent du fait que c'est un h\u00f4te physique.<\/p>\n<p>Tout d'abord, nous \u00e9liminons les SAN, car nous voulons exp\u00e9rimenter, essayer simplement avec des disques durs locaux.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/fd0f5a8627d9179fcbc7097c1c18505f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est d\u00e9j\u00e0 en 2014-2015, et \u00e0 ce moment-l\u00e0, la situation avec les disques et leur capacit\u00e9 dans un h\u00f4te est devenue bien meilleure. Nous avons d\u00e9cid\u00e9, pourquoi ne pas essayer.<\/p>\n<p>Ensuite, nous prenons simplement notre partition de sauvegarde et la transf\u00e9rons physiquement sur une machine distincte.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/456e00bc8557d3340b06efcd1dde8a08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAinsi, nous obtenons ce sch\u00e9ma. Nous avons deux machines qui stockent les m\u00eames ensembles de donn\u00e9es. Elles se sauvegardent compl\u00e8tement mutuellement et synchronisent les donn\u00e9es via un r\u00e9seau \u00e0 travers une file d'attente asynchrone dans le m\u00eame MySQL.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/d44cdb7b440ad4c58cc625123306a8c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPourquoi cela fonctionne bien \u2014 parce que nous avons peu d'\u00e9critures. Autrement dit, si l'\u00e9criture \u00e9tait \u00e9quivalente \u00e0 la lecture, nous aurions probablement rencontr\u00e9 une certaine surcharge r\u00e9seau et des probl\u00e8mes. Peu d'\u00e9critures, beaucoup de lectures \u2014 cette m\u00e9thode fonctionne bien, c'est-\u00e0-dire que nous copions assez rarement des photos entre ces deux serveurs.<\/p>\n<p>Comment cela fonctionne, si nous regardons un peu plus en d\u00e9tail.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/071c11abb6ee1d7734c53052139ff04b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUpload. L'\u00e9quilibreur de charge choisit simplement des h\u00f4tes al\u00e9atoires avec une paire et effectue un t\u00e9l\u00e9chargement sur celui-ci. En m\u00eame temps, il fait naturellement des v\u00e9rifications de sant\u00e9, s'assurant que la machine ne tombe pas. C'est-\u00e0-dire qu'il t\u00e9l\u00e9charge des photos uniquement sur un serveur actif, puis via une file d'attente asynchrone, tout cela est copi\u00e9 chez son voisin. Le t\u00e9l\u00e9chargement est tr\u00e8s simple.<\/p>\n<p>La t\u00e2che est un peu plus complexe.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f494904aec823456e18b987a8c98bf56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIci, Lua nous a aid\u00e9s, car il est parfois difficile de mettre en place une telle logique avec NGINX en version vanilla. Nous envoyons d'abord une requ\u00eate au premier serveur pour voir s'il y a une photo l\u00e0-bas, car elle peut potentiellement avoir \u00e9t\u00e9 upload\u00e9e, par exemple, chez un voisin, et ne pas \u00eatre encore arriv\u00e9e ici. Si la photo est l\u00e0, c'est bon. Nous la transmettons imm\u00e9diatement au client et, peut-\u00eatre, nous la mettons en cache.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/de5f77e997bb049f4cfc1709da0f1788.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS'il n'y en a pas, nous faisons simplement une requ\u00eate au voisin et nous l'obtenons l\u00e0-bas de mani\u00e8re garantie.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/79aa5592acd28dfbc815261d0276c2e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAinsi, on peut de nouveau dire : il peut y avoir des probl\u00e8mes de performance, car les allers-retours constants \u2014 la photo a \u00e9t\u00e9 upload\u00e9e, elle n'est pas ici, nous faisons deux requ\u00eates au lieu d'une, cela devrait fonctionner lentement.<\/p>\n<p>Dans notre situation, cela ne fonctionne pas lentement.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/52ca3902d80990f512201672cd5e6441.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous collectons une tonne de m\u00e9triques sur ce syst\u00e8me, et le taux de r\u00e9ussite conditionnel de ce m\u00e9canisme est d'environ 95 %. Autrement dit, le temps d'attente de cette sauvegarde est minime, et gr\u00e2ce \u00e0 cela, nous r\u00e9cup\u00e9rons pratiquement toujours la photo d\u00e8s la premi\u00e8re demande et nous ne faisons pas deux fois le trajet.<\/p>\n<p>Ainsi, qu'avons-nous encore obtenu, et c'est tr\u00e8s int\u00e9ressant ?<\/p>\n<p>Auparavant, nous avions une principale partition de sauvegarde, et nous lisions \u00e0 partir de celle-ci de mani\u00e8re s\u00e9quentielle. Autrement dit, nous cherchions toujours d'abord sur le principal, puis sur la sauvegarde. C'\u00e9tait un seul passage.<\/p>\n<p>Maintenant, nous utilisons la lecture de deux machines \u00e0 la fois. Nous r\u00e9partissons les demandes en Round Robin. Dans un petit pourcentage de cas, nous faisons deux demandes. Mais au total, nous avons maintenant deux fois plus de capacit\u00e9 de lecture que nous avions auparavant. Et la charge a consid\u00e9rablement diminu\u00e9, tant sur les machines de livraison que sur les stockages qui \u00e9taient aussi disponibles \u00e0 ce moment-l\u00e0.<\/p>\n<p>En ce qui concerne la tol\u00e9rance aux pannes. C'est ce pour quoi nous nous sommes principalement battus. La tol\u00e9rance aux pannes ici a tr\u00e8s bien fonctionn\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/a030a477e60d6e1f3d0b4e3395013df5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUne machine tombe en panne.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/42900b24e340c03ea642fd49f5b410ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPas de probl\u00e8me ! L'ing\u00e9nieur syst\u00e8me peut m\u00eame ne pas se r\u00e9veiller la nuit, il peut attendre le matin, il n'y aura rien de grave.<\/p>\n<p>M\u00eame si, lors de la panne de cette machine, la file d'attente s'est arr\u00eat\u00e9e, ce n'est pas non plus un probl\u00e8me \u2013 le journal sera d'abord accumul\u00e9 sur la machine fonctionnelle, puis il ira dans la file d'attente, pour enfin \u00eatre trait\u00e9 par la machine qui red\u00e9marrera apr\u00e8s un certain temps.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/ef42eadaaf3e3ecbf70847e9f88c1582.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIl en va de m\u00eame pour la maintenance. Nous \u00e9teignons simplement une des machines, la retirons manuellement de tous les pools, elle ne re\u00e7oit plus de trafic, nous effectuons une sorte de maintenance, nous apportons des modifications, puis nous la remettons en service et cette sauvegarde se rattrape assez rapidement. En d'autres termes, le temps d'arr\u00eat d'une machine est compens\u00e9 en quelques minutes au maximum sur une journ\u00e9e. C'est vraiment tr\u00e8s peu. Concernant la r\u00e9silience, je le r\u00e9p\u00e8te, tout fonctionne tr\u00e8s bien ici.<\/p>\n<p>Quels peuvent \u00eatre les conclusions tir\u00e9es de ce sch\u00e9ma de redondance ?<\/p>\n<p>Nous avons obtenu la r\u00e9silience.<\/p>\n<p>Exploitation simplifi\u00e9e. \u00c9tant donn\u00e9 que les machines ont des disques durs locaux, cela est beaucoup plus pratique du point de vue des ing\u00e9nieurs qui travaillent avec \u00e7a.<\/p>\n<p>Nous avons obtenu une double capacit\u00e9 de lecture.<\/p>\n<p>C'est un tr\u00e8s bon bonus en plus de la r\u00e9silience.<\/p>\n<p>Mais il y a aussi des probl\u00e8mes. Maintenant, le d\u00e9veloppement de certaines fonctionnalit\u00e9s li\u00e9es \u00e0 cela est beaucoup plus complexe, car le syst\u00e8me est devenu 100 % \u00e9ventuellement coh\u00e9rent.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/b650276a41730cc303180e8304c5dabb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous devons, par exemple, dans un job d'arri\u00e8re-plan, constamment penser : \u00ab Sur quel serveur sommes-nous actuellement ? \u00bb, \u00ab Y a-t-il vraiment ici une photo \u00e0 jour ? \u00bb, etc. Cela, bien s\u00fbr, est envelopp\u00e9 dans des abstractions et pour le d\u00e9veloppeur qui \u00e9crit la logique m\u00e9tier, c'est transparent. N\u00e9anmoins, cela a ajout\u00e9 une couche complexe. Mais nous sommes pr\u00eats \u00e0 vivre avec cela en \u00e9change des avantages que nous en avons tir\u00e9s.<\/p>\n<p>Et ici encore, un certain conflit appara\u00eet.<\/p>\n<p>J'ai d'abord dit qu'il \u00e9tait mauvais de tout stocker sur des disques durs locaux. Et maintenant je dis que nous avons aim\u00e9 cela.<\/p>\n<p>Oui, au fil du temps, la situation a beaucoup chang\u00e9 et maintenant cette approche a de nombreux avantages. D'une part, nous avons une exploitation beaucoup plus simple.<\/p>\n<p>D'autre part, c'est plus performant, car nous n'avons pas ces contr\u00f4leurs automatiques, les connexions aux baies de disques.<\/p>\n<p>Il y a une \u00e9norme machinerie l\u00e0-bas, alors que ce ne sont que quelques disques qui sont sp\u00e9cifiquement assembl\u00e9s ici en RAID.<\/p>\n<p>Mais il y a aussi des inconv\u00e9nients.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/3c090e0801f1a686dc0d5fefce697c56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC'est environ 1,5 fois plus cher que d'utiliser des SAN m\u00eame avec les prix d'aujourd'hui. C'est pourquoi nous n'avons pas d\u00e9cid\u00e9 de convertir notre grand cluster en machines avec des disques durs locaux et avons d\u00e9cid\u00e9 de garder une solution hybride.<\/p>\n<p>La moiti\u00e9 de nos machines fonctionne avec des disques durs (en fait, pas tout \u00e0 fait la moiti\u00e9 \u2013 peut-\u00eatre 30 %). L'autre partie est constitu\u00e9e de vieux appareils qui \u00e9taient auparavant utilis\u00e9s pour le premier sch\u00e9ma de sauvegarde. Nous les avons simplement remont\u00e9s, car nous n'avons besoin ni de nouvelles donn\u00e9es ni de quoi que ce soit d'autre, nous avons juste d\u00e9plac\u00e9 les montages d'un h\u00f4te physique \u00e0 deux.<\/p>\n<p>Nous avons donc une grande capacit\u00e9 de lecture, et nous avons agrandi nos ressources. Auparavant, nous montions un seul stockage par machine, maintenant nous en montons quatre par paire, par exemple. Et cela fonctionne tr\u00e8s bien.<\/p>\n<p>Faisons un bref r\u00e9sum\u00e9 de ce que nous avons obtenu, de nos objectifs, et si nous avons r\u00e9ussi.<\/p>\n<h3>R\u00e9sultats<\/h3>\n<p>\nNous avons des utilisateurs \u2013 pas moins de 33 millions.<\/p>\n<p>Nous avons trois points de pr\u00e9sence \u2013 Prague, Miami, Hong Kong.<\/p>\n<p>Ils contiennent un niveau de cache, constitu\u00e9 de machines avec des disques locaux rapides (SSD), sur lequel fonctionne une architecture simple avec NGINX, son access.log et des d\u00e9mons Python qui g\u00e8rent tout cela et g\u00e8rent le cache.<\/p>\n<p>Si vous le souhaitez, dans votre projet, si les photos ne sont pas aussi critiques pour vous que pour nous, ou si le compromis entre le contr\u00f4le et la vitesse de d\u00e9veloppement de vos ressources penche dans l'autre sens, alors vous pouvez facilement le remplacer par un CDN, les CDN modernes le font tr\u00e8s bien.<\/p>\n<p>Ensuite, il y a le niveau de stockage, o\u00f9 nous avons des clusters de paires de machines qui se sauvegardent mutuellement, copiant des fichiers de l'un \u00e0 l'autre de mani\u00e8re asynchrone \u00e0 chaque modification.<\/p>\n<p>Certaines de ces machines fonctionnent avec des disques durs locaux.<\/p>\n<p>D'autres machines sont connect\u00e9es \u00e0 des SAN.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/5ddbc4f73d86aa1f83734885d8c9dea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nD'une part, c'est plus pratique en termes d'exploitation et l\u00e9g\u00e8rement plus performant, d'autre part, c'est avantageux en termes de densit\u00e9 de placement et de co\u00fbt par gigaoctet.<\/p>\n<p>C'est un aper\u00e7u rapide de l'architecture que nous avons obtenue et de son \u00e9volution.<\/p>\n<p>Encore quelques conseils du chef, tr\u00e8s simples.<\/p>\n<p>Tout d'abord, si vous d\u00e9cidez soudainement que vous devez absolument am\u00e9liorer votre infrastructure de photos, commencez par mesurer, car il se peut que rien ne doive \u00eatre am\u00e9lior\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/7770f41d0b190eb78ae0d19f4c8182a6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe vais donner un exemple. Nous avons un cluster de machines qui d\u00e9livre des photos depuis des pi\u00e8ces jointes dans des discussions, et le sch\u00e9ma fonctionne toujours comme en 2009, et personne ne souffre de cela. Tout le monde est content, tout le monde aime \u00e7a.<\/p>\n<p>Pour commencer, d\u00e9finissez un ensemble de m\u00e9triques, examinez-les puis d\u00e9cidez ce qui vous d\u00e9pla\u00eet et ce qui doit \u00eatre am\u00e9lior\u00e9. Pour mesurer cela, nous avons un excellent outil appel\u00e9 Pinba.<\/p>\n<p>Il permet de collecter des statistiques d\u00e9taill\u00e9es depuis NGINX pour chaque requ\u00eate, y compris les codes de r\u00e9ponse et la r\u00e9partition des temps \u2014 tout ce dont vous avez besoin. Il dispose de liaisons avec divers syst\u00e8mes d'analyse et vous pouvez visualiser toutes ces donn\u00e9es de mani\u00e8re claire.<\/p>\n<p>D'abord nous mesurons \u2014 ensuite nous am\u00e9liorons.<\/p>\n<p>Ensuite. Nous optimisons la lecture avec un cache, et l'\u00e9criture avec du sharding, mais c'est un point \u00e9vident.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f53a4777f1a2c7793eba4a72c94263a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPar ailleurs, si vous commencez \u00e0 construire votre syst\u00e8me, il est bien pr\u00e9f\u00e9rable de traiter les photographies comme des fichiers immuables. Cela \u00e9limine imm\u00e9diatement toute une s\u00e9rie de probl\u00e8mes li\u00e9s \u00e0 l'invalidation du cache, \u00e0 la mani\u00e8re dont la logique doit retrouver la bonne version de la photographie, etc.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/f345c59681275326cda1320b4f188ce9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSupposons que vous ayez t\u00e9l\u00e9charg\u00e9 une centaine de fichiers, puis que vous les ayez retourn\u00e9s, faites en sorte qu'il s'agisse d'un fichier physiquement diff\u00e9rent. C'est-\u00e0-dire qu'il ne faut pas penser : 'Je vais \u00e9conomiser un peu d'espace en r\u00e9\u00e9crivant dans le m\u00eame fichier, en changeant la version.' Cela ne fonctionne g\u00e9n\u00e9ralement pas bien et engendre beaucoup de maux de t\u00eate par la suite.<\/p>\n<p>Le point suivant. Concernant le redimensionnement \u00e0 la vol\u00e9e.<\/p>\n<p>Auparavant, lorsque les utilisateurs t\u00e9l\u00e9chargeaient une photo, nous g\u00e9n\u00e9rions d'embl\u00e9e de nombreux formats pour tous les cas de figure, pour diff\u00e9rents clients, qui \u00e9taient tous stock\u00e9s sur le disque. Nous avons maintenant abandonn\u00e9 \u00e7a.<\/p>\n<p>Nous avons seulement conserv\u00e9 trois tailles principales : petite, moyenne et grande. Tout le reste est simplement diminu\u00e9 \u00e0 partir de la taille derri\u00e8re celle demand\u00e9e dans Uport, nous faisons juste un redimensionnement et remettons le tout \u00e0 l\u2019utilisateur.<\/p>\n<p>Le co\u00fbt des CPU pour la couche de cache est bien plus bas que si nous r\u00e9g\u00e9n\u00e9rions constamment ces tailles sur chaque stockage. Supposons que nous voulions en ajouter un nouveau, cela prendrait un mois \u2014 ex\u00e9cuter un script partout pour g\u00e9rer cela soigneusement sans faire tomber le cluster. Donc, s'il est possible de choisir, il vaut mieux faire le moins de tailles physiques possible, tout en ayant un certain degr\u00e9 de r\u00e9partition, disons trois. Et tout le reste peut simplement \u00eatre redimensionn\u00e9 \u00e0 la vol\u00e9e \u00e0 l'aide de modules pr\u00eats \u00e0 l'emploi. C'est tr\u00e8s facile et accessible aujourd'hui.<\/p>\n<p>Et une sauvegarde incr\u00e9mentale asynchrone, c'est une bonne chose.<\/p>\n<p>Comme le montre notre exp\u00e9rience, ce type de sch\u00e9ma fonctionne tr\u00e8s bien avec la sauvegarde diff\u00e9r\u00e9e des fichiers modifi\u00e9s.<\/p>\n<p><img decoding=\"async\" alt=\"Architecture de stockage et de partage de photos sur Badoo\" src=\"\/wp-content\/uploads\/2020\/01\/0e550721e838654e61e1fa4d08f9bb93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe dernier point est \u00e9galement \u00e9vident. Si votre infrastructure ne pr\u00e9sente pas de probl\u00e8mes pour le moment, mais qu'il y a quelque chose qui pourrait tomber en panne, cela se produira n\u00e9cessairement lorsque la charge augmentera l\u00e9g\u00e8rement. Il est donc pr\u00e9f\u00e9rable d'y r\u00e9fl\u00e9chir \u00e0 l'avance et d'\u00e9viter de rencontrer des difficult\u00e9s. C'est tout pour moi.<\/p>\n<h3>Contacts<\/h3>\n<p>\n\u00bb <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/users\/bo0rsh201\/\" class=\"user_link\">bo0rsh201<\/a><\/noindex> <br \/>\n\u00bb <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/company\/badoo\/\">Blog de l'entreprise Badoo<\/a><\/noindex><\/p>\n<blockquote><p>Ce rapport est la transcription d'une des meilleures pr\u00e9sentations lors de la conf\u00e9rence des d\u00e9veloppeurs de syst\u00e8mes \u00e0 forte charge <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>. Il reste moins d'un mois avant la conf\u00e9rence HighLoad++ 2017.<\/p>\n<p>Nous avons d\u00e9j\u00e0 pr\u00e9par\u00e9 <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2017\/abstracts\">Programme de la conf\u00e9rence<\/a><\/noindex>, le programme est actuellement en cours d'\u00e9laboration.<\/p>\n<p>Cette ann\u00e9e, nous continuons \u00e0 explorer le th\u00e8me des architectures et de la mise \u00e0 l'\u00e9chelle :<\/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\">Comment servir un milliard d'utilisateurs et fournir un trafic de t\u00e9raoctets<\/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\">Comment r\u00e9\u00e9crire de z\u00e9ro la base de donn\u00e9es des messages priv\u00e9s de VKontakte et migrer vers celle-ci sans temps d'arr\u00eat<\/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\">Mort par promotion : comment Yandex.Money a tent\u00e9 de se pr\u00e9parer pour le Black Friday et de r\u00e9sister<\/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\">Architecture r\u00e9siliente du syst\u00e8me frontal de la banque<\/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\">Architecture du syst\u00e8me de paiement : presque enterprise<\/a><\/noindex> \/ \u0424\u0438\u043b\u0438\u043f\u043f \u0414\u0435\u043b\u044c\u0433\u044f\u0434\u043e<\/li>\n<\/ul>\n<p>\nCertains de ces mat\u00e9riaux sont \u00e9galement utilis\u00e9s dans notre cours en ligne sur le d\u00e9veloppement de syst\u00e8mes \u00e0 forte charge <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 c'est une s\u00e9rie de lettres, articles, ressources et vid\u00e9os soigneusement s\u00e9lectionn\u00e9es. Notre manuel contient d\u00e9j\u00e0 plus de 30 mat\u00e9riaux uniques. Rejoignez-nous !\n<\/p><\/blockquote>\n<p>Source : <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 - 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\/fr\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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\udd47Architecture de stockage et de distribution des photos dans Badoo | ProHoster","description":"Artem Denisov (","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/arhitektura-hraneniya-i-otdachi-fotografij-v-badoo","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/55009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=55009"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/55009\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=55009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=55009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=55009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}