Como escalar de 1 a 100.000 usuários
Muitas startups passaram por isso: multidões de novos usuários sĂŁo registrados todos os dias, e a equipe de desenvolvimento está lutando para apoiar o trabalho do serviço.Esse Ă© um problema agradável, mas há poucas informações claras na Web sobre como dimensionar com precisĂŁo um aplicativo Web de zero a centenas de milhares de usuários. Geralmente, existem soluções de incĂŞndio ou a eliminação de gargalos (e geralmente ambos). Portanto, as pessoas usam truques bastante estereotipados para dimensionar seu projeto amador em algo realmente sĂ©rio.Vamos tentar filtrar as informações e anotar a fĂłrmula principal. Vamos escalar passo a passo nosso novo site de compartilhamento de fotos Graminsta de 1 a 100.000 usuários.Anotaremos quais ações especĂficas precisam ser feitas ao aumentar o pĂşblico para 10, 100, 1000, 10 000 e 100 000 pessoas.1 usuário: 1 carro
Quase todo aplicativo, seja um site ou aplicativo mĂłvel, possui trĂŞs componentes principais:- API
- base de dados
- cliente (aplicativo para celular ou site)
O banco de dados armazena dados persistentes. A API atende solicitações e em torno desses dados. O cliente transfere os dados para o usuário.Cheguei Ă conclusĂŁo de que Ă© muito mais fácil falar sobre dimensionar um aplicativo se, do ponto de vista da arquitetura, as entidades clientes e as APIs estiverem completamente separadas.Quando começamos a criar um aplicativo, todos os trĂŞs componentes podem ser executados no mesmo servidor. De certa forma, isso nos lembra nosso ambiente de desenvolvimento: um engenheiro executa o banco de dados, a API e o cliente no mesmo computador.Teoricamente, poderĂamos implantá-lo na nuvem em uma instância do DigitalOcean Droplet ou AWS EC2, como mostrado abaixo:Com isso dito, se o site tiver mais de um usuário, quase sempre faz sentido destacar o nĂvel do banco de dados.10 usuários: levando o banco de dados para um nĂvel separado
A divisĂŁo de um banco de dados em serviços gerenciados, como o Amazon RDS ou o Digital Ocean Managed Database, nos servirá bem por um longo tempo. Isso Ă© um pouco mais caro do que a auto-hospedagem em uma Ăşnica máquina ou em uma instância do EC2, mas com esses serviços vocĂŞ obtĂ©m muitas extensões Ăşteis que serĂŁo Ăşteis no futuro: backups em várias regiões, rĂ©plicas de leitura, rĂ©plicas de leitura, backups automáticos e muito mais.É assim que o sistema agora parece:100 usuários: levando o cliente a um nĂvel separado
Felizmente, nosso aplicativo realmente gostou dos primeiros usuários. O tráfego está se tornando mais estável, entĂŁo Ă© hora de mover o cliente para um nĂvel separado. Deve-se notar que a separação de entidades Ă© um aspecto essencial da criação de um aplicativo escalável. Como uma parte do sistema recebe mais tráfego, podemos dividi-lo para controlar o dimensionamento do serviço com base em padrões de tráfego especĂficos.É por isso que gosto de representar o cliente separadamente da API. Isso facilita muito o desenvolvimento de várias plataformas: Web, Web mĂłvel, iOS, Android, aplicativos de desktop, serviços de terceiros etc. Todos eles sĂŁo apenas clientes que usam a mesma API.Por exemplo, agora nossos usuários geralmente solicitam o lançamento de um aplicativo mĂłvel. A separação de entidades clientes e APIs facilita isso.Aqui está a aparĂŞncia do sistema:1000 usuários: adicionar balanceador de carga
As coisas estĂŁo indo bem. Os usuários do Graminsta estĂŁo carregando mais e mais fotos. O nĂşmero de registros tambĂ©m está crescendo. Nosso servidor API solitário tem dificuldade em gerenciar todo o tráfego. Precisa de mais ferro!O balanceador de carga Ă© um conceito muito poderoso. A idĂ©ia principal Ă© colocar o balanceador na frente da API e distribuir o tráfego entre instâncias de serviço individuais. Essa Ă© a maneira do dimensionamento horizontal, ou seja, adicionamos mais servidores com o mesmo cĂłdigo, aumentando o nĂşmero de solicitações que podemos processar.Vamos colocar balanceadores de carga separados na frente do cliente web e na frente da API. Isso significa que vocĂŞ pode executar várias instâncias que executam o cĂłdigo da API e o cĂłdigo do cliente da web. O balanceador de carga encaminhará solicitações para o servidor que estiver menos carregado.Aqui temos outra vantagem importante - redundância. Quando uma instância falha (possivelmente sobrecarrega ou trava), ainda temos outras que ainda respondem a solicitações recebidas. Se uma Ăşnica instância funcionasse, no caso de uma falha, todo o sistema cairia.O balanceador de carga tambĂ©m fornece dimensionamento automático. Podemos configurá-lo para aumentar o nĂşmero de instâncias antes do pico de carregamento e reduzir quando todos os usuários dormem.Com um balanceador de carga, o nĂvel da API pode ser escalado para o infinito, apenas adicionamos novas instâncias Ă medida que o nĂşmero de solicitações aumenta.. , PaaS, Heroku Elastic Beanstalk AWS ( ). Heroku , - API. , Heroku — .
10 000 : CDN
Talvez devesse ter sido feito desde o começo. Processar solicitações e tirar novas fotos estĂŁo começando a carregar muito nossos servidores.Nesta fase, vocĂŞ precisa usar um serviço de nuvem para armazenar conteĂşdo estático - imagens, vĂdeos e muito mais (AWS S3 ou Digital Ocean Spaces). Em geral, nossa API deve evitar processar coisas como o upload de imagens e o upload de imagens para um servidor.Outra vantagem da hospedagem na nuvem Ă© sua CDN (na AWS, esse complemento Ă© chamado Cloudfront, mas muitos serviços de armazenamento na nuvem o oferecem imediatamente). A CDN armazena em cache automaticamente nossas imagens em vários data centers ao redor do mundo.Embora nosso centro de dados principal possa estar localizado em Ohio, mas se alguĂ©m solicitar uma imagem do JapĂŁo, o provedor de nuvem fará uma cĂłpia e salvará em seu centro de dados japonĂŞs. A prĂłxima pessoa a solicitar esta imagem no JapĂŁo receberá muito mais rapidamente. Isso Ă© importante quando trabalhamos com arquivos grandes, como fotos ou vĂdeos, que levam muito tempo para serem carregados e transmitidos por todo o planeta.100.000 usuários: escala no nĂvel de dados
A CDN realmente ajudou: o tráfego está crescendo a toda velocidade. O famoso video blogueiro, Maid Mobrick, acaba de se registrar conosco e postar sua histĂłria, como eles dizem. Graças ao balanceador de carga, o nĂvel de CPU e uso de memĂłria nos servidores da API Ă© mantido baixo (dez instâncias da API estĂŁo em execução), mas estamos começando a receber muitos tempos limite para solicitações ... de onde vieram esses atrasos?ApĂłs uma pequena escavação nas mĂ©tricas, vemos que a CPU no servidor de banco de dados está carregada de 80 a 90%. Estamos no limite.Escalar a camada de dados Ă© provavelmente a parte mais difĂcil da equação. Os servidores de API atendem solicitações sem estado, portanto, apenas adicionamos mais instâncias de API. Mas com maisbancos de dados nĂŁo sĂŁo bem-sucedidos. Discutiremos os populares sistemas de gerenciamento de banco de dados relacional (PostgreSQL, MySQL, etc.).Armazenamento em cache
Uma das maneiras mais fáceis de aumentar o desempenho do nosso banco de dados Ă© introduzir um novo componente: o nĂvel do cache. O mĂ©todo mais comum de armazenamento em cache Ă© armazenar registros de valores-chave na RAM, como Redis ou Memcached. A maioria das nuvens possui uma versĂŁo gerenciada desses serviços: Elasticache na AWS e Memorystore no Google Cloud.O cache Ă© Ăştil quando um serviço faz muitas chamadas repetidas para o banco de dados para obter as mesmas informações. De fato, acessamos o banco de dados apenas uma vez, salvamos as informações no cache - e nĂŁo tocamos mais nele.Por exemplo, em nosso serviço Graminsta, toda vez que alguĂ©m acessa a página de perfil do Mobric star, o servidor da API solicita informações de seu perfil no banco de dados. Isso acontece repetidamente. Como as informações de perfil da Mobrick nĂŁo mudam a cada solicitação, elas sĂŁo Ăłtimas para armazenar em cache.Armazenaremos em cache os resultados do banco de dados no Redis por chave, user:id
com um perĂodo de validade de 30 segundos. Agora, quando alguĂ©m entra no perfil de Mobrick, primeiro verificamos o Redis e, se os dados estiverem lá, simplesmente transferimos diretamente do Redis. Agora, as consultas ao perfil mais popular do site praticamente nĂŁo carregam nosso banco de dados.Outra vantagem da maioria dos serviços de cache Ă© que eles sĂŁo mais fáceis de dimensionar do que os servidores de banco de dados. O Redis possui um modo de cluster Redis Cluster interno. Como um balanceador de carga1 1, permite distribuir o cache Redis em várias máquinas (em milhares de servidores, se necessário).Quase todos os aplicativos de larga escala usam cache; essa Ă© uma parte absolutamente integrante da API rápida. Processamento de solicitação mais rápido e cĂłdigo mais produtivo - tudo isso Ă© importante, mas sem um cache Ă© quase impossĂvel dimensionar o serviço para milhões de usuários.Lendo rĂ©plicas
Quando o nĂşmero de consultas ao banco de dados aumentou significativamente, podemos fazer mais uma coisa: adicionar rĂ©plicas de leitura no sistema de gerenciamento de banco de dados. Usando os serviços gerenciados descritos acima, isso pode ser feito com um clique. A rĂ©plica de leitura permanecerá relevante no banco de dados principal e está disponĂvel para instruções SELECT.Aqui está o nosso sistema agora:Ações futuras
Ă€ medida que o aplicativo continua em escala, continuaremos a separar os serviços para escalá-los independentemente. Por exemplo, se começarmos a usar Websockets, faz sentido extrair o cĂłdigo de processamento dos Websockets para um serviço separado. Podemos colocá-lo em novas instâncias atrás de nosso prĂłprio balanceador de carga, que pode ser ampliado ou diminuĂdo dependendo das conexões abertas dos Websockets e independentemente do nĂşmero de solicitações HTTP.TambĂ©m continuamos a lutar contra as restrições no nĂvel do banco de dados. É nesta fase que chegou a hora de estudar o particionamento e o sharding do banco de dados. Ambas as abordagens exigem sobrecarga adicional, mas permitem que vocĂŞ dimensione o banco de dados quase atĂ© o infinito.TambĂ©m queremos instalar um serviço de monitoramento e análise como New Relic ou Datadog. Isso identificará consultas lentas e entenderá onde Ă© necessário melhorar. Ă€ medida que escalamos, queremos nos concentrar em encontrar gargalos e resolvĂŞ-los - geralmente usando algumas idĂ©ias das seções anteriores.Fontes
Esta postagem foi inspirada em uma das minhas postagens favoritas de alta escalabilidade . Eu queria concretizar um pouco o artigo para as etapas iniciais dos projetos e desatá-lo de um fornecedor. Certifique-se de ler se você está interessado neste tópico.Notas de rodapé
- Apesar das semelhanças em termos de balanceamento de carga em várias instâncias, a implementação básica do cluster Redis é muito diferente do balanceador de carga. [para retornar]

Source: https://habr.com/ru/post/undefined/
All Articles