Arquitetura para armazenar e compartilhar fotos no Badoo

Arquitetura para armazenar e compartilhar fotos no Badoo

Artem Denisov ( bo0rsh201, Badoo)

O Badoo é o maior site de namoro do mundo. Atualmente temos cerca de 330 milhões de usuários registrados em todo o mundo. Mas o que é muito mais importante no contexto da nossa conversa de hoje é que armazenamos cerca de 3 petabytes de fotos de usuários. Todos os dias, nossos usuários carregam cerca de 3,5 milhões de novas fotos, e a carga de leitura é de cerca de 80 mil solicitações por segundo. Isso é bastante para o nosso back-end e às vezes há dificuldades com isso.

Arquitetura para armazenar e compartilhar fotos no Badoo

Falarei sobre o design desse sistema, que armazena e envia fotos em geral, e analisarei isso do ponto de vista de um desenvolvedor. Haverá uma breve retrospectiva de seu desenvolvimento, onde descreverei os principais marcos, mas apenas falarei mais detalhadamente sobre as soluções que estamos utilizando atualmente.

Agora vamos começar.


Como eu disse, esta será uma retrospectiva, e para começar por algum lado, vamos pegar o exemplo mais comum.

Arquitetura para armazenar e compartilhar fotos no Badoo

Temos uma tarefa comum, precisamos aceitar, armazenar e enviar fotos dos usuários. Neste formulário a tarefa é geral, podemos usar qualquer coisa:

  • armazenamento em nuvem moderno,
  • uma solução em caixa, da qual também existem muitas agora;
  • Podemos configurar várias máquinas em nosso data center e colocar grandes discos rígidos nelas e armazenar fotos lá.

Historicamente, o Badoo - tanto agora quanto naquela época (na época em que estava apenas em sua infância) - vive em seus próprios servidores, dentro de nossos próprios DCs. Portanto, esta opção foi ideal para nós.

Arquitetura para armazenar e compartilhar fotos no Badoo

Apenas pegamos várias máquinas, chamamos de “fotos”, e conseguimos um cluster que armazena fotos. Mas parece que algo está faltando. Para que tudo isso funcione, precisamos determinar de alguma forma em qual máquina armazenaremos quais fotos. E também aqui não há necessidade de abrir a América.

Arquitetura para armazenar e compartilhar fotos no Badoo

Adicionamos algum campo ao nosso armazenamento com informações sobre os usuários. Esta será a chave de fragmentação. No nosso caso, chamamos de place_id, e esse ID de local aponta para o local onde as fotos do usuário estão armazenadas. Fazemos mapas.

No primeiro estágio, isso pode até ser feito manualmente - dizemos que uma foto desse usuário com tal local irá parar em tal servidor. Graças a este mapa, sempre sabemos quando um usuário carrega uma foto, onde salvá-la e onde entregá-la.

Este é um esquema absolutamente trivial, mas tem vantagens bastante significativas. A primeira é que é simples, como eu disse, e a segunda é que com esta abordagem podemos facilmente escalar horizontalmente simplesmente entregando carros novos e adicionando-os ao mapa. Você não precisa fazer mais nada.

Foi assim para nós durante algum tempo.

Arquitetura para armazenar e compartilhar fotos no Badoo

Isso foi por volta de 2009. Eles entregaram carros, entregaram...

E em algum momento começamos a perceber que esse esquema tem algumas desvantagens. Quais são as desvantagens?

Em primeiro lugar, a capacidade é limitada. Não podemos colocar tantos discos rígidos em um servidor físico quanto gostaríamos. E isso se tornou um certo problema com o passar do tempo e com o crescimento do conjunto de dados.

E em segundo lugar. Esta é uma configuração atípica de máquinas, uma vez que tais máquinas são difíceis de reutilizar em alguns outros clusters; elas são bastante específicas, ou seja, eles devem ter desempenho fraco, mas ao mesmo tempo com um disco rígido grande.

Isto foi tudo para 2009, mas, em princípio, estes requisitos ainda são relevantes hoje. Temos uma retrospectiva, então em 2009 foi tudo completamente ruim com isso.

E o último ponto é o preço.

Arquitetura para armazenar e compartilhar fotos no Badoo

O preço era muito alto naquela época e precisávamos procurar algumas alternativas. Aqueles. precisávamos, de alguma forma, utilizar melhor tanto o espaço nos data centers quanto os servidores físicos nos quais tudo isso está localizado. E nossos engenheiros de sistema iniciaram um grande estudo no qual analisaram diversas opções diferentes. Eles também analisaram sistemas de arquivos em cluster, como PolyCeph e Lustre. Houve problemas de desempenho e operação bastante difícil. Eles recusaram. Tentamos montar todo o conjunto de dados via NFS em cada carro para aumentá-lo de alguma forma. A leitura também correu mal, tentamos soluções diferentes de fornecedores diferentes.

E no final decidimos usar a chamada Rede de Área de Armazenamento.

Arquitetura para armazenar e compartilhar fotos no Badoo

Esses são SHDs grandes projetados especificamente para armazenar grandes quantidades de dados. São prateleiras com discos que são montadas nas máquinas de saída óptica final. Que. temos uma espécie de pool de máquinas, bem pequeno, e esses SHDs, que são transparentes para nossa lógica de envio, ou seja, para nosso nginx ou qualquer outra pessoa atender solicitações dessas fotos.

Esta decisão teve vantagens óbvias. Isso é SHD. Destina-se a armazenar fotos. Isso sai mais barato do que simplesmente equipar as máquinas com discos rígidos.

Segunda vantagem.

Arquitetura para armazenar e compartilhar fotos no Badoo

Isto é que a capacidade tornou-se muito maior, ou seja, podemos acomodar muito mais armazenamento em um volume muito menor.

Mas também houve desvantagens que surgiram rapidamente. À medida que o número de usuários e a carga deste sistema cresciam, começaram a surgir problemas de desempenho. E o problema aqui é bastante óbvio - qualquer SHD projetado para armazenar muitas fotos em um volume pequeno, via de regra, sofre com leitura intensiva. Na verdade, isso é verdade para qualquer armazenamento em nuvem ou qualquer outra coisa. Agora não temos um armazenamento ideal que seja infinitamente escalável, você poderia colocar qualquer coisa nele e ele toleraria muito bem as leituras. Especialmente leituras casuais.

Arquitetura para armazenar e compartilhar fotos no Badoo

Como é o caso das nossas fotos, porque as fotos são solicitadas de forma inconsistente e isso afetará muito o seu desempenho.

Mesmo de acordo com os números de hoje, se conseguirmos algo acima de 500 RPS para fotos em uma máquina à qual o armazenamento está conectado, os problemas já começam. E já foi ruim para nós, porque o número de usuários está crescendo, as coisas só vão piorar. Isso precisa ser otimizado de alguma forma.

Para otimizar, decidimos naquele momento, obviamente, olhar o perfil de carga – o que, em geral, está acontecendo, o que precisa ser otimizado.

Arquitetura para armazenar e compartilhar fotos no Badoo

E aqui tudo joga a nosso favor.

Já falei no primeiro slide: temos 80 mil solicitações de leitura por segundo com apenas 3,5 milhões de uploads por dia. Ou seja, esta é uma diferença de três ordens de grandeza. É óbvio que a leitura precisa ser otimizada e está praticamente claro como.

Há mais um pequeno ponto. As especificidades do serviço são tais que uma pessoa se registra, carrega uma foto, então começa a olhar ativamente para outras pessoas, como elas, e é mostrada ativamente para outras pessoas. Aí ele encontra companheira ou não encontra, depende do que vai acontecer, e para de usar o serviço por um tempo. Nesse momento, quando ele usa, suas fotos estão muito em alta - são muito procuradas, muita gente as vê. Assim que ele para de fazer isso, rapidamente ele perde a mesma exposição a outras pessoas que tinha antes, e suas fotos quase nunca são solicitadas.

Arquitetura para armazenar e compartilhar fotos no Badoo

Aqueles. Temos um conjunto de dados quente muito pequeno. Mas ao mesmo tempo há muitos pedidos para ele. E uma solução completamente óbvia aqui é adicionar um cache.

Um cache com LRU resolverá todos os nossos problemas. O que estamos fazendo?

Arquitetura para armazenar e compartilhar fotos no Badoo

Adicionamos outro relativamente pequeno na frente do nosso grande cluster com armazenamento, que é chamado de photocaches. Este é essencialmente apenas um proxy de cache.

Como funciona por dentro? Aqui está nosso usuário, aqui está o armazenamento. Tudo está como antes. O que adicionamos no meio?

Arquitetura para armazenar e compartilhar fotos no Badoo

É apenas uma máquina com disco local físico, que é rápido. Isso ocorre com um SSD, por exemplo. E algum tipo de cache local é armazenado neste disco.

Com o que se parece? O usuário envia uma solicitação de foto. O NGINX procura primeiro no cache local. Caso contrário, basta proxy_pass para nosso armazenamento, baixar a foto de lá e entregá-la ao usuário.

Mas este é muito banal e não está claro o que está acontecendo lá dentro. Funciona mais ou menos assim.

Arquitetura para armazenar e compartilhar fotos no Badoo

O cache é logicamente dividido em três camadas. Quando digo “três camadas”, isso não significa que exista algum tipo de sistema complexo. Não, estes são condicionalmente apenas três diretórios no sistema de arquivos:

  1. Este é um buffer para onde vão as fotos recém-baixadas de um proxy.
  2. Este é um cache quente que armazena fotos atualmente solicitadas ativamente.
  3. E um cache frio, onde as fotos são gradualmente retiradas do cache quente quando menos solicitações chegam a elas.

Para que isso funcione, precisamos gerenciar de alguma forma esse cache, precisamos reorganizar as fotos nele, etc. Este também é um processo muito primitivo.

Arquitetura para armazenar e compartilhar fotos no Badoo

O Nginx simplesmente grava no access.log do RAMDisk para cada solicitação, no qual indica o caminho para a foto que ele serviu atualmente (caminho relativo, é claro) e qual partição foi servida. Aqueles. pode dizer “foto 1” e então um buffer, ou um cache quente, ou um cache frio, ou um proxy.

Dependendo disso, precisamos decidir de alguma forma o que fazer com a foto.

Temos um pequeno daemon rodando em cada máquina que lê constantemente esse log e armazena em sua memória estatísticas sobre o uso de determinadas fotografias.

Arquitetura para armazenar e compartilhar fotos no Badoo

Ele simplesmente coleta lá, guarda os contadores e periodicamente faz o seguinte. Ele move as fotos solicitadas ativamente, para as quais há muitas solicitações, para o cache quente, onde quer que estejam.

Arquitetura para armazenar e compartilhar fotos no Badoo

Fotos que são solicitadas raramente e que se tornaram solicitadas com menos frequência são gradualmente empurradas do cache quente para o cache frio.

Arquitetura para armazenar e compartilhar fotos no Badoo

E quando ficamos sem espaço no cache, simplesmente começamos a deletar tudo do cache frio indiscriminadamente. E por falar nisso, isso funciona bem.

Para que a foto seja salva imediatamente ao fazer proxy para o buffer, usamos a diretiva proxy_store e o buffer também é um RAMDisk, ou seja, para o usuário funciona muito rapidamente. Isto diz respeito ao interior do próprio servidor de cache.

A questão restante é como distribuir solicitações entre esses servidores.

Digamos que haja um cluster de vinte máquinas de armazenamento e três servidores de cache (foi assim que aconteceu).

Arquitetura para armazenar e compartilhar fotos no Badoo

Precisamos determinar de alguma forma quais solicitações são para quais fotos e onde colocá-las.

A opção mais comum é o Round Robin. Ou faz isso por acidente?

Isto obviamente tem uma série de desvantagens porque estaríamos usando o cache de forma muito ineficiente em tal situação. As solicitações chegarão a algumas máquinas aleatórias: aqui ela foi armazenada em cache, mas na próxima ela não está mais lá. E se tudo isso funcionar, será muito ruim. Mesmo com um pequeno número de máquinas no cluster.

Precisamos determinar de alguma forma inequivocamente qual servidor receberá qual solicitação.

Existe uma maneira banal. Pegamos o hash da URL ou o hash da nossa chave de sharding, que está na URL, e dividimos pelo número de servidores. Vai funcionar? Vai.

Arquitetura para armazenar e compartilhar fotos no Badoo

Aqueles. temos uma solicitação de 2%, por exemplo, para algum “example_url” ele sempre chegará ao servidor com índice “XNUMX”, e o cache será constantemente descartado da melhor maneira possível.

Mas há um problema com a refragmentação nesse esquema. Resharding - quero dizer alterar o número de servidores.

Vamos supor que nosso cluster de cache não aguenta mais e decidimos adicionar outra máquina.

Vamos adicionar.

Arquitetura para armazenar e compartilhar fotos no Badoo

Agora tudo é divisível não por três, mas por quatro. Assim, quase todas as chaves que tínhamos, quase todas as URLs agora residem em outros servidores. Todo o cache foi invalidado por um momento. Todas as solicitações caíram em nosso cluster de armazenamento, ele ficou indisposto, falha no serviço e usuários insatisfeitos. Eu não quero fazer isso.

Esta opção também não nos convém.

Que. o que deveríamos fazer? Devemos, de alguma forma, fazer uso eficiente do cache, enviar a mesma solicitação repetidamente ao mesmo servidor, mas ser resistentes à nova fragmentação. E existe essa solução, não é tão complicada. É chamado de hashing consistente.

Arquitetura para armazenar e compartilhar fotos no Badoo

O que parece?

Arquitetura para armazenar e compartilhar fotos no Badoo

Pegamos alguma função da chave de fragmentação e espalhamos todos os seus valores no círculo. Aqueles. no ponto 0, seus valores mínimo e máximo convergem. A seguir, colocamos todos os nossos servidores no mesmo círculo aproximadamente desta forma:

Arquitetura para armazenar e compartilhar fotos no Badoo

Cada servidor é definido por um ponto, e o setor que vai até ele no sentido horário, respectivamente, é atendido por este host. Quando as solicitações chegam até nós, vemos imediatamente que, por exemplo, a solicitação A - tem um hash aí - e é atendida pelo servidor 2. A solicitação B - pelo servidor 3. E assim por diante.

Arquitetura para armazenar e compartilhar fotos no Badoo

O que acontece nesta situação durante a nova fragmentação?

Arquitetura para armazenar e compartilhar fotos no Badoo

Não invalidamos todo o cache, como antes, e não deslocamos todas as chaves, mas deslocamos cada setor uma curta distância para que, relativamente falando, nosso sexto servidor, que queremos adicionar, caiba no espaço livre, e nós adicionamos lá.

Arquitetura para armazenar e compartilhar fotos no Badoo

É claro que, em tal situação, as chaves também se movem. Mas eles saem muito mais fracos do que antes. E vemos que nossas duas primeiras chaves permaneceram em seus servidores, e o servidor de cache mudou apenas para a última chave. Isso funciona de forma bastante eficiente e, se você adicionar novos hosts de forma incremental, não haverá grande problema aqui. Você adiciona e adiciona um pouco de cada vez, espera até que o cache fique cheio novamente e tudo funciona bem.

A única questão permanece com as recusas. Suponhamos que algum tipo de carro esteja com defeito.

Arquitetura para armazenar e compartilhar fotos no Badoo

E realmente não gostaríamos de regenerar este mapa neste momento, invalidar parte do cache e assim por diante, se, por exemplo, a máquina fosse reinicializada e precisássemos de alguma forma atender às solicitações. Simplesmente mantemos um cache de fotos de backup em cada site, que funciona como um substituto para qualquer máquina que esteja inoperante no momento. E se de repente um dos nossos servidores ficar indisponível, o tráfego vai para lá. Naturalmente, não temos nenhum cache lá, ou seja, está frio, mas pelo menos as solicitações dos usuários estão sendo processadas. Se este for um intervalo curto, então o vivenciamos com total calma. Há apenas mais carga no armazenamento. Se esse intervalo for longo, já podemos tomar uma decisão - remover ou não este servidor do mapa, ou talvez substituí-lo por outro.

Isto é sobre o sistema de cache. Vejamos os resultados.

Parece que não há nada complicado aqui. Mas esse método de gerenciamento do cache nos proporcionou uma taxa de truques de cerca de 98%. Aqueles. dessas 80 mil solicitações por segundo, apenas 1600 chegam ao armazenamento, e essa é uma carga completamente normal, eles suportam com calma, sempre temos uma reserva.

Colocamos esses servidores em três de nossos CDs e recebemos três pontos de presença – Praga, Miami e Hong Kong.

Arquitetura para armazenar e compartilhar fotos no Badoo

Que. eles estão localizados mais ou menos localmente em cada um dos nossos mercados-alvo.

E como um ótimo bônus, temos esse proxy de cache, no qual a CPU está realmente ociosa, porque não é tão necessária para servir conteúdo. E aí, usando NGINX+ Lua, implementamos muita lógica utilitária.

Arquitetura para armazenar e compartilhar fotos no Badoo

Por exemplo, podemos experimentar webp ou jpeg progressivo (estes são formatos modernos eficazes), ver como isso afeta o tráfego, tomar algumas decisões, habilitá-lo para determinados países, etc.; faça redimensionamento dinâmico ou recorte fotos instantaneamente.

Este é um bom caso de uso quando, por exemplo, você tem um aplicativo móvel que exibe fotos, e o aplicativo móvel não quer desperdiçar a CPU do cliente solicitando uma foto grande e depois redimensionando-a para um determinado tamanho para empurrá-la para a vista. Podemos simplesmente especificar dinamicamente alguns parâmetros no URL condicional do UPort, e o cache de fotos redimensionará a própria foto. Via de regra, ele selecionará o tamanho que temos fisicamente no disco, o mais próximo possível do solicitado, e fará o downsell em coordenadas específicas.

A propósito, disponibilizamos publicamente gravações de vídeo dos últimos cinco anos da conferência de desenvolvedores de sistemas de alta carga HighLoad ++. Assista, aprenda, compartilhe e inscreva-se Canal do Youtube.

Também podemos adicionar muita lógica de produto lá. Por exemplo, podemos adicionar diferentes marcas d'água usando parâmetros de URL, podemos desfocar, desfocar ou pixelizar fotos. É quando queremos mostrar a foto de uma pessoa, mas não queremos mostrar o rosto dele, funciona bem, está tudo implementado aqui.

O que conseguimos? Conseguimos três pontos de presença, uma boa taxa de truques e ao mesmo tempo não temos CPU ociosa nessas máquinas. Ele agora se tornou, é claro, mais importante do que antes. Precisamos nos dar carros mais fortes, mas vale a pena.

Trata-se da devolução de fotografias. Tudo aqui é bastante claro e óbvio. Acho que não descobri a América, quase qualquer CDN funciona assim.

E, muito provavelmente, um ouvinte sofisticado pode ter uma pergunta: por que não mudar tudo para CDN? Seria quase a mesma coisa; todas as CDNs modernas podem fazer isso. E há uma série de razões.

O primeiro são as fotografias.

Arquitetura para armazenar e compartilhar fotos no Badoo

Este é um dos pontos-chave da nossa infraestrutura e precisamos de tanto controle quanto possível. Se for algum tipo de solução de um fornecedor terceirizado e você não tiver nenhum poder sobre ela, será muito difícil conviver com ela quando tiver um grande conjunto de dados e um fluxo muito grande. de solicitações de usuários.

Deixe-me lhe dar um exemplo. Agora, com a nossa infraestrutura, podemos, por exemplo, em caso de algum problema ou batida subterrânea, ir até a máquina e mexer ali, relativamente falando. Podemos adicionar a coleção de algumas métricas que só precisamos, podemos experimentar de alguma forma, ver como isso afeta os gráficos e assim por diante. Agora, muitas estatísticas estão sendo coletadas neste cluster de cache. E periodicamente olhamos para isso e passamos muito tempo explorando algumas anomalias. Se estivesse do lado da CDN, seria muito mais difícil de controlar. Ou, por exemplo, se ocorrer algum tipo de acidente, sabemos o que aconteceu, sabemos como conviver e como superá-lo. Esta é a primeira conclusão.

A segunda conclusão também é bastante histórica, porque o sistema está em desenvolvimento há muito tempo e havia muitos requisitos de negócios diferentes em diferentes estágios, e nem sempre se enquadram no conceito de CDN.

E o ponto que segue do anterior é

Arquitetura para armazenar e compartilhar fotos no Badoo

Isso ocorre porque nos caches de fotos temos muitas lógicas específicas, que nem sempre podem ser adicionadas mediante solicitação. É improvável que qualquer CDN adicione alguns itens personalizados a seu pedido. Por exemplo, criptografar URLs se você não quiser que o cliente possa alterar alguma coisa. Você deseja alterar a URL no servidor e criptografá-la e, em seguida, enviar alguns parâmetros dinâmicos aqui.

Que conclusão isso sugere? No nosso caso, o CDN não é uma alternativa muito boa.

Arquitetura para armazenar e compartilhar fotos no Badoo

E no seu caso, se você tiver algum requisito de negócio específico, poderá implementar facilmente o que eu mesmo mostrei. E isso funcionará perfeitamente com um perfil de carga semelhante.

Mas se você tiver algum tipo de solução geral e a tarefa não for muito específica, você pode usar um CDN com segurança. Ou se o tempo e os recursos são mais importantes para você do que o controle.

Arquitetura para armazenar e compartilhar fotos no Badoo

E os CDNs modernos têm quase tudo o que falei agora. Com exceção de mais ou menos alguns recursos.

Trata-se de distribuir fotos.

Vamos agora avançar um pouco na nossa retrospectiva e falar sobre armazenamento.

2013 estava passando.

Arquitetura para armazenar e compartilhar fotos no Badoo

Servidores de cache foram adicionados e os problemas de desempenho desapareceram. Tudo está bem. O conjunto de dados está crescendo. Em 2013, tínhamos cerca de 80 servidores conectados ao armazenamento e cerca de 40 servidores de cache em cada DC. São 560 terabytes de dados em cada DC, ou seja, cerca de um petabyte no total.

Arquitetura para armazenar e compartilhar fotos no Badoo

E com o crescimento do conjunto de dados, os custos operacionais começaram a aumentar significativamente. O que isso significa?

Arquitetura para armazenar e compartilhar fotos no Badoo

Neste diagrama desenhado - com uma SAN, com máquinas e caches conectados a ela - há muitos pontos de falha. Se já havíamos lidado com a falha dos servidores de cache antes, tudo era mais ou menos previsível e compreensível, mas do lado do armazenamento tudo era muito pior.

Em primeiro lugar, a própria Storage Area Network (SAN), que pode falhar.

Em segundo lugar, ele é conectado via óptica às máquinas finais. Pode haver problemas com placas ópticas e velas de ignição.

Arquitetura para armazenar e compartilhar fotos no Badoo

É claro que não existem tantos deles como na própria SAN, mas, mesmo assim, esses também são pontos de falha.

A seguir vem a própria máquina, que está conectada ao armazenamento. Também pode falhar.

Arquitetura para armazenar e compartilhar fotos no Badoo

No total, temos três pontos de falha.

Além disso, além dos pontos de falha, há uma manutenção pesada do próprio armazenamento.

Este é um sistema complexo com vários componentes e os engenheiros de sistemas podem ter dificuldade em trabalhar com ele.

E o último e mais importante ponto. Se ocorrer uma falha em qualquer um desses três pontos, temos uma chance diferente de zero de perder dados do usuário porque o sistema de arquivos pode travar.

Arquitetura para armazenar e compartilhar fotos no Badoo

Digamos que nosso sistema de arquivos esteja quebrado. Em primeiro lugar, a sua recuperação leva muito tempo - pode demorar uma semana com uma grande quantidade de dados. E em segundo lugar, no final provavelmente acabaremos com um monte de arquivos incompreensíveis que precisarão ser combinados de alguma forma nas fotos do usuário. E corremos o risco de perder dados. O risco é bastante alto. E quanto mais essas situações acontecem, e quanto mais problemas surgem em toda essa cadeia, maior é o risco.

Algo tinha que ser feito sobre isso. E decidimos que só precisamos fazer backup dos dados. Na verdade, esta é uma solução óbvia e boa. O que nos fizemos?

Arquitetura para armazenar e compartilhar fotos no Badoo

Esta era a aparência do nosso servidor quando estava conectado ao armazenamento antes. Esta é uma seção principal, é apenas um dispositivo de bloco que na verdade representa uma montagem para armazenamento remoto via óptica.

Acabamos de adicionar uma segunda seção.

Arquitetura para armazenar e compartilhar fotos no Badoo

Colocamos um segundo armazenamento próximo a ele (felizmente, não é tão caro em termos de dinheiro) e o chamamos de partição de backup. Ele também está conectado via óptica e está localizado na mesma máquina. Mas precisamos sincronizar de alguma forma os dados entre eles.

Aqui simplesmente criamos uma fila assíncrona próxima.

Arquitetura para armazenar e compartilhar fotos no Badoo

Ela não está muito ocupada. Sabemos que não temos registros suficientes. Uma fila é apenas uma tabela no MySQL na qual estão escritas linhas como “você precisa fazer backup desta foto”. Com qualquer alteração ou upload, copiamos da partição principal para o backup de forma assíncrona ou simplesmente por algum tipo de trabalho em segundo plano.

E assim temos sempre duas seções consistentes. Mesmo que uma parte deste sistema falhe, podemos sempre alterar a partição principal com um backup e tudo continuará funcionando.

Mas por causa disso, a carga de leitura aumenta muito, porque... além dos clientes que leem a seção principal, porque primeiro olham a foto lá (lá é mais recente), e depois procuram no backup, caso não tenham encontrado (mas o NGINX só faz isso), nosso sistema também é um backup adicional que agora lê a partir da partição principal. Não é que isso fosse um gargalo, mas eu não queria aumentar a carga, essencialmente, assim mesmo.

E adicionamos um terceiro disco, que é um pequeno SSD, e o chamamos de buffer.

Arquitetura para armazenar e compartilhar fotos no Badoo

Como funciona agora.

O usuário carrega uma foto no buffer e, em seguida, um evento é lançado na fila indicando que ela precisa ser copiada em duas seções. Ela é copiada e a foto permanece no buffer por algum tempo (digamos, um dia) e só então é eliminada de lá. Isso melhora muito a experiência do usuário, pois o usuário carrega uma foto, via de regra, as solicitações começam imediatamente a seguir, ou ele mesmo atualizou a página e a atualizou. Mas tudo depende do aplicativo que faz o upload.

Ou, por exemplo, outras pessoas a quem ele começou a se mostrar enviam imediatamente pedidos após esta foto. Ainda não está no cache; a primeira solicitação ocorre muito rapidamente. Essencialmente o mesmo que um cache de fotos. O armazenamento lento não está envolvido nisso. E quando, um dia depois, ele for eliminado, ele já estará armazenado em cache em nossa camada de cache ou, provavelmente, ninguém mais precisará dele. Aqueles. A experiência do usuário aqui cresceu muito bem devido a manipulações tão simples.

Bem, e o mais importante: paramos de perder dados.

Arquitetura para armazenar e compartilhar fotos no Badoo

Digamos que paramos potencialmente perder dados, porque realmente não os perdemos. Mas havia perigo. Vemos que esta solução é, obviamente, boa, mas é um pouco como atenuar os sintomas do problema, em vez de o resolver completamente. E alguns problemas permanecem aqui.

Em primeiro lugar, este é um ponto de falha na forma do próprio hospedeiro físico sobre o qual funciona toda esta maquinaria; ele não desapareceu.

Arquitetura para armazenar e compartilhar fotos no Badoo

Em segundo lugar, ainda existem problemas com SANs, sua manutenção pesada, etc. Não que fosse um fator crítico, mas eu queria tentar de alguma forma viver sem ele.

E fizemos a terceira versão (na verdade, a segunda na verdade) - a versão reserva. O que isso se parece?

Isso é o que era -

Arquitetura para armazenar e compartilhar fotos no Badoo

Nossos principais problemas são o fato de se tratar de um host físico.

Em primeiro lugar, estamos removendo SANs porque queremos experimentar, queremos experimentar apenas discos rígidos locais.

Arquitetura para armazenar e compartilhar fotos no Badoo

Já estamos em 2014-2015, e naquela época a situação dos discos e sua capacidade em um host ficou muito melhor. Decidimos por que não tentar.

E então simplesmente pegamos nossa partição de backup e a transferimos fisicamente para uma máquina separada.

Arquitetura para armazenar e compartilhar fotos no Badoo

Assim, obtemos este diagrama. Temos dois carros que armazenam os mesmos conjuntos de dados. Eles fazem backup completo e sincronizam os dados na rede por meio de uma fila assíncrona no mesmo MySQL.

Arquitetura para armazenar e compartilhar fotos no Badoo

O motivo pelo qual isso funciona bem é porque temos poucos registros. Aqueles. se a escrita fosse comparável à leitura, talvez teríamos algum tipo de sobrecarga e problemas de rede. Há pouca escrita, muita leitura - este método funciona bem, ou seja, Raramente copiamos fotos entre esses dois servidores.

Como isso funciona, se você olhar um pouco mais detalhadamente.

Arquitetura para armazenar e compartilhar fotos no Badoo

Carregar. O balanceador simplesmente seleciona hosts aleatórios com um par e faz upload para eles. Ao mesmo tempo, ele naturalmente faz exames de saúde e garante que o carro não caia. Aqueles. ele envia fotos apenas para um servidor ativo e, em seguida, por meio de uma fila assíncrona, tudo é copiado para seu vizinho. Com o upload tudo é extremamente simples.

A tarefa é um pouco mais difícil.

Arquitetura para armazenar e compartilhar fotos no Badoo

Lua nos ajudou aqui, porque pode ser difícil fazer essa lógica no Vanilla NGINX. Primeiro fazemos uma solicitação ao primeiro servidor, para ver se a foto está lá, porque potencialmente ela poderia ser carregada, por exemplo, para um vizinho, mas ainda não chegou aqui. Se a foto estiver lá, isso é bom. Nós imediatamente o entregamos ao cliente e, possivelmente, o armazenamos em cache.

Arquitetura para armazenar e compartilhar fotos no Badoo

Se não estiver, basta fazer um pedido ao vizinho e temos a garantia de recebê-lo de lá.

Arquitetura para armazenar e compartilhar fotos no Badoo

Que. novamente podemos dizer: pode haver problemas de desempenho, pois há constantes idas e vindas - a foto foi carregada, não está aqui, estamos fazendo duas solicitações em vez de uma, isso deve funcionar lentamente.

Na nossa situação, isso não funciona lentamente.

Arquitetura para armazenar e compartilhar fotos no Badoo

Coletamos várias métricas neste sistema, e a taxa inteligente condicional desse mecanismo é de cerca de 95%. Aqueles. O lag desse backup é pequeno, e por isso temos quase certeza de que, após o upload da foto, iremos tirá-la pela primeira vez e não teremos que ir a lugar nenhum duas vezes.

Então, o que mais temos de realmente legal?

Anteriormente, tínhamos a partição de backup principal e lemos nelas sequencialmente. Aqueles. Sempre procuramos primeiro no principal e depois no backup. Foi um movimento.

Agora utilizamos a leitura de duas máquinas ao mesmo tempo. Distribuímos solicitações usando Round Robin. Numa pequena percentagem de casos fazemos dois pedidos. Mas, no geral, temos agora o dobro do stock de leitura do que tínhamos antes. E a carga foi bastante reduzida tanto nas máquinas de envio quanto diretamente nas máquinas de armazenamento, que também tínhamos naquela época.

Quanto à tolerância a falhas. Na verdade, foi por isso que lutamos principalmente. Com tolerância a falhas, tudo deu certo aqui.

Arquitetura para armazenar e compartilhar fotos no Badoo

Um carro quebra.

Arquitetura para armazenar e compartilhar fotos no Badoo

Sem problemas! Um engenheiro de sistemas pode nem acordar à noite, ele vai esperar até de manhã, nada de ruim vai acontecer.

Se mesmo que esta máquina falhe, a fila esteja fora de ordem, também não haja problemas, o log será simplesmente acumulado primeiro na máquina viva, e depois será adicionado à fila, e depois no carro que irá entrar em operação depois de algum tempo.

Arquitetura para armazenar e compartilhar fotos no Badoo

A mesma coisa com manutenção. Simplesmente desligamos uma das máquinas, retiramos manualmente de todos os pools, ela para de receber tráfego, fazemos algum tipo de manutenção, editamos algo, depois colocamos de volta em serviço, e esse backup é atualizado rapidamente. Aqueles. por dia, o tempo de inatividade de um carro aumenta em alguns minutos. Isso é realmente muito pouco. Com tolerância a falhas, repito, tudo é legal aqui.

Que conclusões podem ser tiradas deste esquema de redundância?

Temos tolerância a falhas.

Fácil de usar. Como as máquinas possuem discos rígidos locais, isso é muito mais conveniente do ponto de vista operacional para os engenheiros que trabalham com elas.

Recebemos um subsídio de leitura duplo.

Este é um bônus muito bom além da tolerância a falhas.

Mas também existem problemas. Agora temos um desenvolvimento muito mais complexo de algumas funcionalidades relacionadas a isso, pois o sistema acabou se tornando 100% consistente.

Arquitetura para armazenar e compartilhar fotos no Badoo

Devemos, digamos, em algum trabalho em segundo plano, pensar constantemente: “Em que servidor estamos rodando agora?”, “Existe realmente uma foto atual aqui?” etc. É claro que tudo isso está encerrado e, para o programador que escreve lógica de negócios, é transparente. Mesmo assim, essa grande camada complexa apareceu. Mas estamos dispostos a aturar isso em troca dos benefícios que recebemos dele.

E aqui novamente surge algum conflito.

Eu disse no início que armazenar tudo em discos rígidos locais é ruim. E agora digo que gostamos.

Sim, de facto, ao longo do tempo a situação mudou muito e agora esta abordagem tem muitas vantagens. Em primeiro lugar, temos uma operação muito mais simples.

Em segundo lugar, é mais produtivo porque não temos esses controladores automáticos ou conexões com prateleiras de disco.

Há uma quantidade enorme de máquinas lá, e esses são apenas alguns discos que são montados aqui na máquina em um ataque.

Mas há desvantagens.

Arquitetura para armazenar e compartilhar fotos no Badoo

Isso é aproximadamente 1,5 vezes mais caro do que usar SANs, mesmo com os preços atuais. Portanto, decidimos não converter corajosamente todo o nosso grande cluster em carros com discos rígidos locais e decidimos deixar uma solução híbrida.

Metade de nossas máquinas funciona com discos rígidos (bem, nem metade – provavelmente 30%). E o resto são carros antigos que tinham o primeiro esquema de reserva. Simplesmente os remontamos, pois não precisávamos de novos dados ou qualquer outra coisa, simplesmente movemos as montagens de um host físico para dois.

E agora temos um grande estoque de leitura e ampliamos. Se antes montávamos um armazenamento em uma máquina, agora montamos quatro, por exemplo, em um par. E funciona bem.

Vamos fazer um breve resumo do que realizamos, pelo que lutamos e se conseguimos.

Resultados de

Temos usuários - até 33 milhões.

Temos três pontos de presença – Praga, Miami, Hong Kong.

Eles contêm uma camada de cache, que consiste em carros com discos locais rápidos (SSDs), nos quais rodam máquinas simples do NGINX, seus daemons access.log e Python, que processam tudo isso e gerenciam o cache.

Se desejar, você está em seu projeto, se as fotos não são tão críticas para você quanto são para nós, ou se o equilíbrio entre controle versus velocidade de desenvolvimento e custos de recursos está na outra direção para você, então você pode substituí-lo com segurança com um CDN, os CDNs modernos funcionam bem.

Em seguida vem a camada de armazenamento, na qual temos clusters de pares de máquinas que fazem backup uns dos outros, os arquivos são copiados de forma assíncrona de um para outro sempre que mudam.

Além disso, algumas dessas máquinas funcionam com discos rígidos locais.

Algumas dessas máquinas estão conectadas a SANs.

Arquitetura para armazenar e compartilhar fotos no Badoo

E, por um lado, é mais prático de usar e um pouco mais produtivo, por outro lado, é conveniente em termos de densidade de colocação e preço por gigabyte.

Esta é uma breve visão geral da arquitetura do que obtivemos e como tudo se desenvolveu.

Mais algumas dicas do capitão, muito simples.

Primeiro, se de repente você decidir que precisa melhorar urgentemente tudo em sua infraestrutura fotográfica, meça primeiro, porque talvez nada precise ser melhorado.

Arquitetura para armazenar e compartilhar fotos no Badoo

Deixe-me lhe dar um exemplo. Temos um aglomerado de máquinas que enviam fotos de anexos em chats, e o esquema funciona lá desde 2009, e ninguém está sofrendo com isso. Todo mundo está bem, todo mundo gosta de tudo.

Para medir, primeiro pendure um monte de métricas, observe-as e então decida com o que você está insatisfeito e o que precisa ser melhorado. Para medir isso, temos uma ferramenta bacana chamada Pinba.

Ele permite que você colete estatísticas muito detalhadas do NGINX para cada código de solicitação e resposta e distribuição de tempos - o que você quiser. Ele tem ligações para todos os tipos de sistemas analíticos diferentes, e então você pode ver tudo lindamente.

Primeiro medimos, depois melhoramos.

Avançar. Otimizamos a leitura com cache, a escrita com sharding, mas este é um ponto óbvio.

Arquitetura para armazenar e compartilhar fotos no Badoo

Avançar. Se você está começando a construir seu sistema agora, é muito melhor transformar as fotos em arquivos imutáveis. Porque você perde imediatamente toda uma classe de problemas com invalidação de cache, como a lógica deve encontrar a versão correta da foto e assim por diante.

Arquitetura para armazenar e compartilhar fotos no Badoo

Digamos que você carregou cem, depois girou-o, tornando-o um arquivo fisicamente diferente. Aqueles. não precisa pensar: agora vou economizar um pouco de espaço, gravar no mesmo arquivo, mudar a versão. Isso sempre não funciona bem e causa muitas dores de cabeça depois.

Próximo ponto. Sobre redimensionar em tempo real.

Anteriormente, quando os usuários carregavam uma foto, cortávamos imediatamente vários tamanhos para todas as ocasiões, para diferentes clientes, e todos ficavam no disco. Agora abandonamos isso.

Deixamos apenas três tamanhos principais: pequeno, médio e grande. Simplesmente reduzimos todo o resto do tamanho que está por trás daquele que nos foi solicitado no Uport, simplesmente fazemos o downscale e entregamos ao usuário.

A CPU da camada de cache aqui acaba sendo muito mais barata do que se regenerarmos constantemente esses tamanhos em cada armazenamento. Digamos que queremos adicionar um novo, isso levará um mês - execute um script em qualquer lugar que faça tudo isso perfeitamente, sem destruir o cluster. Aqueles. Se você tiver a oportunidade de escolher agora, é melhor fazer o menor número possível de tamanhos físicos, mas de forma que pelo menos alguma distribuição seja, digamos, três. E todo o resto pode ser simplesmente redimensionado em tempo real usando módulos prontos. Agora é tudo muito fácil e acessível.

E o backup assíncrono incremental é bom.

Como nossa prática mostrou, esse esquema funciona muito bem com cópia atrasada de arquivos alterados.

Arquitetura para armazenar e compartilhar fotos no Badoo

O último ponto também é óbvio. Se a sua infraestrutura não tem esses problemas agora, mas há algo que pode quebrar, com certeza irá quebrar quando aumentar um pouco mais. Portanto, é melhor pensar nisso com antecedência e não ter problemas com isso. Isso é tudo que eu queria dizer.

contatos

» bo0rsh201
» Blog do Badoo

Este relatório é uma transcrição de um dos melhores discursos na conferência de desenvolvedores de sistemas de alta carga HighLoad ++. Falta menos de um mês para a conferência HighLoad++ 2017.

Já temos isso pronto Programa da conferência, o cronograma agora está sendo formado ativamente.

Este ano continuamos a explorar o tópico de arquiteturas e dimensionamento:

Também usamos alguns desses materiais em nosso curso de treinamento on-line sobre desenvolvimento de sistemas de alta carga. Guia HighLoad é uma cadeia de cartas, artigos, materiais e vídeos especialmente selecionados. Nosso livro já contém mais de 30 materiais exclusivos. Conectar!

Fonte: habr.com

Adicionar um comentário