Como o Badoo conseguiu enviar 200 mil fotos por segundo

Como o Badoo conseguiu enviar 200 mil fotos por segundo

A web moderna é quase impensável sem conteúdo de mídia: quase todas as avós têm um smartphone, todos estão nas redes sociais e o tempo de inatividade na manutenção custa caro para as empresas. Aqui está uma transcrição da história da empresa Badoo sobre como ela organizou a entrega das fotos usando uma solução de hardware, quais problemas de desempenho ela encontrou no processo, o que os causou e como esses problemas foram resolvidos usando uma solução de software baseada em Nginx, garantindo tolerância a falhas em todos os níveis (vídeo). Agradecemos aos autores da história de Oleg Sannis Efimova e Alexandra Dymova, que compartilharam sua experiência na conferência Tempo de atividade dia 4.

— Vamos começar com uma pequena introdução sobre como armazenamos e armazenamos fotos em cache. Temos uma camada onde as armazenamos e uma camada onde armazenamos as fotos em cache. Ao mesmo tempo, se quisermos atingir uma alta taxa de truques e reduzir a carga de armazenamento, é importante para nós que cada foto de um usuário individual esteja em um servidor de cache. Caso contrário, teríamos que instalar tantos discos quanto mais servidores tivéssemos. Nossa taxa de truque está em torno de 99%, ou seja, estamos reduzindo em 100 vezes a carga do nosso armazenamento, e para isso, há 10 anos, quando tudo isso estava sendo construído, tínhamos 50 servidores. Assim, para servir essas fotos, precisávamos essencialmente de 50 domínios externos que esses servidores atendem.

Naturalmente, surgiu imediatamente a questão: se um dos nossos servidores cair e ficar indisponível, que parte do tráfego perderemos? Olhamos o que havia no mercado e decidimos comprar um hardware para que resolvesse todos os nossos problemas. A escolha recaiu sobre a solução da empresa da rede F5 (que, aliás, comprou recentemente a NGINX, Inc): BIG-IP Local Traffic Manager.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

O que esse hardware (LTM) faz: é um roteador de ferro que faz redundância de ferro de suas portas externas e permite rotear o tráfego com base na topologia da rede, em algumas configurações, e faz verificações de integridade. Era importante para nós que esta peça de hardware pudesse ser programada. Assim, poderíamos descrever a lógica de como as fotografias de um usuário específico foram veiculadas a partir de um cache específico. Com o que se parece? Existe um hardware que analisa a Internet em um domínio, um IP, descarrega SSL, analisa solicitações http, seleciona um número de cache do IRule, para onde ir e deixa o tráfego ir para lá. Ao mesmo tempo, faz verificações de integridade e, caso alguma máquina fique indisponível, naquele momento fizemos com que o tráfego fosse para um servidor de backup. Do ponto de vista da configuração existem, claro, algumas nuances, mas em geral tudo é bastante simples: cadastramos um cartão, corresponde um determinado número ao nosso IP na rede, dizemos que vamos escutar nas portas 80 e 443, dizemos que se o servidor estiver indisponível, então é necessário enviar tráfego para o servidor de backup, neste caso o 35º, e descrevemos um monte de lógica sobre como essa arquitetura deve ser desmontada. O único problema era que a linguagem em que o hardware foi programado era Tcl. Se alguém se lembra disso... esta linguagem é mais somente escrita do que uma linguagem conveniente para programação:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

O que conseguimos? Recebemos um hardware que garante alta disponibilidade de nossa infraestrutura, roteia todo o nosso tráfego, traz benefícios à saúde e simplesmente funciona. Além disso, funciona há bastante tempo: nos últimos 10 anos não houve reclamações sobre isso. No início de 2018, já enviávamos cerca de 80 mil fotos por segundo. Isso representa algo em torno de 80 gigabits de tráfego de ambos os nossos data centers.

Mas…

No início de 2018, vimos um quadro feio nas paradas: o tempo de envio das fotos havia claramente aumentado. E isso parou de nos servir. O problema é que esse comportamento era visível apenas nos horários de pico de trânsito - para nossa empresa é na noite de domingo para segunda. Mas no resto do tempo o sistema se comportou normalmente, sem sinais de falha.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

No entanto, o problema precisava ser resolvido. Identificamos possíveis gargalos e começamos a eliminá-los. Em primeiro lugar, é claro, expandimos os uplinks externos, conduzimos uma auditoria completa dos uplinks internos e encontramos todos os gargalos possíveis. Mas tudo isso não deu um resultado óbvio, o problema não desapareceu.

Outro possível gargalo foi o desempenho dos próprios caches de fotos. E decidimos que talvez o problema seja deles. Bem, expandimos o desempenho - principalmente portas de rede em caches de fotos. Mas, novamente, nenhuma melhoria óbvia foi observada. No final, prestamos muita atenção ao desempenho do próprio LTM, e aqui vimos uma imagem triste nos gráficos: a carga em todas as CPUs começa a fluir suavemente, mas de repente chega a um patamar. Ao mesmo tempo, o LTM para de responder adequadamente às verificações de integridade e aos uplinks e começa a desligá-los aleatoriamente, o que leva a uma grave degradação do desempenho.

Ou seja, identificamos a origem do problema, identificamos o gargalo. Resta decidir o que faremos.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

A primeira e mais óbvia coisa que poderíamos fazer é modernizar de alguma forma o próprio LTM. Mas há algumas nuances aqui, porque esse hardware é bastante único, você não vai ao supermercado mais próximo e compra. Este é um contrato separado, um contrato de licença separado e levará muito tempo. A segunda opção é começar a pensar por si mesmo, criar sua própria solução utilizando seus próprios componentes, de preferência utilizando um programa de acesso aberto. Resta decidir o que exatamente escolheremos para isso e quanto tempo gastaremos para resolver esse problema, pois os usuários não estavam recebendo fotos suficientes. Portanto, precisamos de fazer tudo isto muito, muito rapidamente, pode-se dizer, ontem.

Como a tarefa parecia “fazer algo o mais rápido possível e usando o hardware que temos”, a primeira coisa que pensamos foi simplesmente remover algumas máquinas não muito poderosas da frente, colocar lá o Nginx, com o qual sabemos como fazer trabalhe e tente implementar a mesma lógica que o hardware costumava fazer. Ou seja, na verdade, deixamos o nosso hardware, instalamos mais 4 servidores que tivemos que configurar, criamos domínios externos para eles, semelhante a como era há 10 anos... Perdemos um pouco em disponibilidade se essas máquinas caíssem, mas menos ainda, resolveram o problema dos nossos usuários localmente.

Assim, a lógica permanece a mesma: instalamos o Nginx, ele pode fazer descarregamento de SSL, podemos de alguma forma programar a lógica de roteamento, verificar a integridade nas configurações e simplesmente duplicar a lógica que tínhamos antes.

Vamos sentar para escrever as configurações. A princípio parecia que tudo era muito simples, mas, infelizmente, é muito difícil encontrar manuais para cada tarefa. Portanto, não recomendamos simplesmente pesquisar “como configurar o Nginx para fotos” no Google: é melhor consultar a documentação oficial, que mostrará quais configurações devem ser alteradas. Mas é melhor escolher você mesmo o parâmetro específico. Bom, então tudo é simples: descrevemos os servidores que temos, descrevemos os certificados... Mas o mais interessante é, na verdade, a própria lógica de roteamento.

A princípio pareceu-nos que estávamos simplesmente descrevendo a nossa localização, combinando o número do nosso cache de fotos nela contido, usando as mãos ou um gerador para descrever quantos upstreams precisamos, em cada upstream indicamos o servidor para o qual o tráfego deve go, e um servidor de backup - se o servidor principal não estiver disponível:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Mas, provavelmente, se tudo fosse tão simples, simplesmente iríamos para casa e não diríamos nada. Infelizmente, com as configurações padrão do Nginx, que, em geral, foram feitas ao longo de muitos anos de desenvolvimento e não são totalmente adequadas para este caso... a configuração fica assim: se algum servidor upstream apresentar um erro de solicitação ou tempo limite, o Nginx sempre muda o tráfego para o próximo. Além disso, após a primeira falha, em 10 segundos o servidor também será desligado, tanto por engano quanto por timeout - isso nem pode ser configurado de forma alguma. Ou seja, se removermos ou redefinirmos a opção de tempo limite na diretiva upstream, então, embora o Nginx não processe essa solicitação e responda com algum erro não muito bom, o servidor será desligado.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Para evitar isso, fizemos duas coisas:

a) eles proibiram o Nginx de fazer isso manualmente - e, infelizmente, a única maneira de fazer isso é simplesmente definir as configurações de falha máxima.

b) lembramos que em outros projetos utilizamos um módulo que nos permite fazer verificações de antecedentes - portanto, fizemos verificações de saúde bastante frequentes para que o tempo de inatividade em caso de acidente fosse mínimo.

Infelizmente, isso também não é tudo, porque literalmente as primeiras duas semanas de operação desse esquema mostraram que a verificação de integridade do TCP também não é confiável: no servidor upstream pode não ser Nginx, ou Nginx no estado D, e em neste caso o kernel aceitará a conexão, a verificação de integridade será aprovada, mas não funcionará. Portanto, imediatamente substituímos isso pelo health-check http, fizemos um específico, que, se retornar 200, então tudo funciona neste script. Você pode fazer lógica adicional - por exemplo, no caso de servidores de cache, verifique se o sistema de arquivos está montado corretamente:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

E isso nos serviria, exceto que no momento o circuito repetiu completamente o que o hardware fez. Mas queríamos fazer melhor. Anteriormente, tínhamos um servidor de backup, e isso provavelmente não é muito bom, porque se você tiver cem servidores, quando vários falharem ao mesmo tempo, é improvável que um servidor de backup consiga lidar com a carga. Portanto, decidimos distribuir a reserva por todos os servidores: simplesmente fizemos outro upstream separado, escrevemos todos os servidores lá com determinados parâmetros de acordo com a carga que podem atender, adicionamos as mesmas verificações de integridade que tínhamos antes:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Como é impossível ir para outro upstream dentro de um upstream, foi necessário ter certeza de que se o upstream principal, no qual simplesmente gravamos o cache de fotos correto e necessário, não estivesse disponível, simplesmente passamos pela error_page para retornar, de onde fomos para o backup upstream:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

E adicionando literalmente quatro servidores, obtivemos isso: substituímos parte da carga - removemos do LTM para esses servidores, implementamos a mesma lógica lá, usando hardware e software padrão, e imediatamente recebemos o bônus que esses servidores podem ser dimensionados, porque podem simplesmente ser fornecidos tanto quanto necessário. Bem, o único aspecto negativo é que perdemos alta disponibilidade para usuários externos. Mas naquele momento tivemos que sacrificar isso, porque era preciso resolver o problema imediatamente. Então, removemos parte da carga, era cerca de 40% naquele momento, o LTM parecia bom e, literalmente, duas semanas após o início do problema, começamos a enviar não 45 mil solicitações por segundo, mas 55 mil. Na verdade, crescemos 20% - esse é claramente o tráfego que não entregamos ao usuário. E depois disso começaram a pensar em como resolver o problema restante - garantir alta acessibilidade externa.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Tivemos uma pausa, durante a qual discutimos qual solução usaríamos para isso. Houve propostas para garantir a confiabilidade usando DNS, com a ajuda de alguns scripts escritos em casa, protocolos de roteamento dinâmico... havia muitas opções, mas já ficou claro que para uma entrega de fotos verdadeiramente confiável, é necessário introduzir outra camada que irá monitorar isso. Chamamos essas máquinas de diretores fotográficos. O software em que confiamos foi o Keepalived:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Para começar, em que consiste o Keepalived? O primeiro é o protocolo VRRP, amplamente conhecido pelos networkers, localizado em equipamentos de rede que fornece tolerância a falhas no endereço IP externo ao qual os clientes se conectam. A segunda parte é o IPVS, servidor virtual IP, para balanceamento entre roteadores fotográficos e garantia de tolerância a falhas nesse nível. E terceiro – exames de saúde.

Vamos começar com a primeira parte: VRRP – como é? Existe um determinado IP virtual, que possui uma entrada no dns badoocdn.com, onde os clientes se conectam. Em algum momento, temos um endereço IP em um servidor. Pacotes Keepalived são executados entre servidores usando o protocolo VRRP e, se o mestre desaparecer do radar - o servidor foi reinicializado ou algo mais, o servidor de backup coleta automaticamente esse endereço IP - nenhuma ação manual é necessária. A diferença entre master e backup é principalmente prioritária: quanto maior for, maior será a chance da máquina se tornar master. Uma vantagem muito grande é que você não precisa configurar endereços IP no próprio servidor, basta descrevê-los na configuração, e se os endereços IP precisarem de algumas regras de roteamento customizadas, isso é descrito diretamente na configuração, usando o mesma sintaxe descrita no pacote VRRP. Você não encontrará coisas desconhecidas.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Como é isso na prática? O que acontece se um dos servidores falhar? Assim que o master desaparece, nosso backup deixa de receber anúncios e automaticamente se torna um master. Depois de algum tempo, reparamos o master, reinicializamos, aumentamos o Keepalived - os anúncios chegam com prioridade maior que o backup, e o backup volta automaticamente, remove endereços IP, nenhuma ação manual precisa ser feita.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Assim, garantimos a tolerância a falhas do endereço IP externo. A próxima parte é equilibrar de alguma forma o tráfego do endereço IP externo para os roteadores fotográficos que já o estão encerrando. Tudo fica bem claro com os protocolos de balanceamento. Este é um round-robin simples ou coisas um pouco mais complexas, wrr, conexão de lista e assim por diante. Isso está basicamente descrito na documentação, não há nada de especial. Mas o método de entrega... Aqui veremos mais de perto porque escolhemos um deles. Estes são NAT, Roteamento Direto e TUN. O fato é que planejamos entregar imediatamente 100 gigabits de tráfego dos sites. Se você estimar, precisará de placas de 10 gigabits, certo? 10 placas gigabit em um servidor já estão além do escopo, pelo menos, do nosso conceito de “equipamento padrão”. E então lembramos que não distribuímos apenas tráfego, mas distribuímos fotos.

O que há de especial? — Enorme diferença entre tráfego de entrada e saída. O tráfego de entrada é muito pequeno, o tráfego de saída é muito grande:

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Se você olhar esses gráficos, verá que no momento o diretor está recebendo cerca de 200 MB por segundo, este é um dia muito comum. Devolvemos 4,500 MB por segundo, nossa proporção é de aproximadamente 1/22. Já está claro que para fornecer totalmente o tráfego de saída para 22 servidores de trabalho, precisamos apenas de um que aceite esta conexão. É aqui que o algoritmo de roteamento direto vem em nosso auxílio.

Com o que se parece? Nosso diretor fotográfico, de acordo com sua tabela, transmite conexões para roteadores fotográficos. Mas os roteadores fotográficos enviam o tráfego de retorno diretamente para a Internet, enviam para o cliente, ele não volta pelo diretor fotográfico, assim, com um número mínimo de máquinas, garantimos total tolerância a falhas e bombeamento de todo o tráfego. Nas configurações fica assim: especificamos o algoritmo, no nosso caso é um rr simples, fornecemos o método de roteamento direto e então começamos a listar todos os servidores reais, quantos deles temos. O que determinará esse tráfego. Se tivermos mais um ou dois servidores lá, ou vários servidores, surge essa necessidade - apenas adicionamos esta seção à configuração e não nos preocupamos muito. Do lado dos servidores reais, do lado do roteador fotográfico, este método requer a configuração mínima, está perfeitamente descrito na documentação e não há armadilhas aí.

O que é especialmente interessante é que tal solução não implica uma reformulação radical da rede local; isto foi importante para nós; tivemos que resolver isto com custos mínimos. Se você olhar Saída do comando de administração IPVS, então veremos como fica. Aqui temos um determinado servidor virtual, na porta 443, escuta, aceita a conexão, todos os servidores em funcionamento estão listados, e você pode ver que a conexão é, mais ou menos, a mesma. Se olharmos as estatísticas no mesmo servidor virtual, temos pacotes de entrada, conexões de entrada, mas absolutamente nenhuma de saída. As conexões de saída vão diretamente para o cliente. Ok, conseguimos desequilibrá-lo. Agora, o que acontece se um de nossos roteadores fotográficos falhar? Afinal, ferro é ferro. Pode entrar em pânico no kernel, pode quebrar, a fonte de alimentação pode queimar. Qualquer coisa. É por isso que exames de saúde são necessários. Eles podem ser tão simples quanto verificar como a porta está aberta, ou algo mais complexo, até alguns scripts escritos em casa que irão até mesmo verificar a lógica de negócios.

Paramos em algum lugar no meio: temos uma solicitação https para um local específico, o script é chamado, se responder com a 200ª resposta, acreditamos que está tudo bem com este servidor, que ele está ativo e pode ser ligado bastante facilmente.

Como isso, novamente, parece na prática? Vamos desligar o servidor para manutenção - atualizando o BIOS, por exemplo. Nos logs temos imediatamente um timeout, vemos a primeira linha, depois de três tentativas ela é marcada como “com falha” e é simplesmente removida da lista.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Uma segunda opção de comportamento também é possível, quando o VS é simplesmente definido como zero, mas se a foto for retornada, isso não funciona bem. O servidor surge, o Nginx inicia aí, o exame de saúde entende imediatamente que a conexão está funcionando, que está tudo bem, e o servidor aparece na nossa lista, e a carga imediatamente começa a ser aplicada a ele. Nenhuma ação manual é necessária do administrador de plantão. O servidor foi reiniciado à noite - o departamento de monitoramento não nos liga sobre isso à noite. Eles informam que isso aconteceu, está tudo bem.

Assim, de uma forma bastante simples, com a ajuda de um pequeno número de servidores, resolvemos o problema de tolerância a falhas externas.

Resta dizer que tudo isto, evidentemente, precisa de ser monitorizado. Separadamente, deve-se notar que o Keepalivede, como software escrito há muito tempo, possui várias maneiras de monitorá-lo, ambas usando verificações via DBus, SMTP, SNMP e Zabbix padrão. Além disso, ele mesmo sabe escrever cartas para quase todos os espirros e, para ser sincero, em algum momento até pensamos em desligá-lo, porque ele escreve muitas cartas para qualquer mudança de tráfego, ativação, para cada conexão IP, e assim por diante . Claro, se houver muitos servidores, você poderá se sobrecarregar com essas cartas. Monitoramos o nginx em roteadores fotográficos usando métodos padrão, e o monitoramento de hardware não desapareceu. Aconselhamos, claro, mais duas coisas: em primeiro lugar, verificações externas de saúde e disponibilidade, porque mesmo que tudo funcione, de facto, talvez os utilizadores não recebam fotos devido a problemas com fornecedores externos ou algo mais complexo. Sempre vale a pena manter em algum lugar de outra rede, na Amazon ou em outro lugar, uma máquina separada que possa executar ping em seus servidores de fora, e também vale a pena usar detecção de anomalias, para quem sabe fazer aprendizado de máquina complicado, ou monitoramento simples , pelo menos para saber se as solicitações caíram drasticamente ou, pelo contrário, aumentaram. Também pode ser útil.

Vamos resumir: de fato, substituímos a solução rígida, que em algum momento deixou de nos servir, por um sistema bastante simples que faz tudo igual, ou seja, fornece terminação de tráfego HTTPS e posterior roteamento inteligente com o exames de saúde necessários. Aumentamos a estabilidade desse sistema, ou seja, ainda temos alta disponibilidade para cada camada, além disso temos o bônus de que é bastante fácil escalar tudo em cada camada, pois é hardware padrão com software padrão, ou seja , simplificamos o diagnóstico de possíveis problemas.

Com o que acabamos? Tivemos um problema durante as férias de janeiro de 2018. Nos primeiros seis meses enquanto colocamos esse esquema em operação, expandimos para todo o tráfego a fim de retirar todo o tráfego do LTM, crescemos apenas no tráfego em um data center de 40 gigabits para 60 gigabits, e ao mesmo tempo para durante todo o ano de 2018 conseguimos enviar quase três vezes mais fotos por segundo.

Como o Badoo conseguiu enviar 200 mil fotos por segundo

Fonte: habr.com

Adicionar um comentário