Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Um guia para entender os padrões de dimensionamento de banco de dados


Existem muitos artigos online descrevendo padrões de escalabilidade de banco de dados, mas na maioria são artigos dispersos – apenas técnicas que são definidas aleatoriamente sem muito contexto. Acho que eles não são definidos passo a passo e não discutem quando escolher qual opção de dimensionamento, quais opções de dimensionamento são viáveis ​​na prática e por quê.

Portanto, estou planejando discutir algumas das técnicas em detalhes em artigos futuros. Para começar, acho melhor discutir técnicas passo a passo com algum contexto à minha maneira. Este artigo é um artigo de alto nível - não discutirei técnicas de dimensionamento em detalhes aqui, mas fornecerei uma visão geral. Então vamos começar.

Um estudo de caso


Suponha que você tenha construído uma startup que oferece compartilhamento de carona a um custo barato. Inicialmente, quando você começa, você segmenta uma cidade e dificilmente tem dezenas de clientes após seu anúncio inicial.

Você salva todos os clientes, viagens, locais, dados de reservas e histórico de viagens de clientes no mesmo banco de dados ou provavelmente em uma única máquina física. Não há cache sofisticado ou pipeline de big data para resolver problemas, pois seu aplicativo é muito novo. Isso é perfeito para o seu caso de uso neste momento, pois há muito poucos clientes e seu sistema dificilmente reserva 1 viagem em 5 minutos, por exemplo.

Mas com o passar do tempo, mais pessoas começam a se inscrever em seu sistema, pois você é o serviço mais barato do mercado e graças à sua promoção e anúncios. Você começa a reservar, digamos, 10 reservas por minuto e, lentamente, o número aumenta para 20, 30 reservas por minuto.

Nesse momento, você percebe que o sistema começou a funcionar mal:a latência da API aumentou muito e algumas transações travam ou morrem de fome e, eventualmente, falham. Seu aplicativo está demorando mais para responder, causando insatisfação do cliente. O que você pode fazer para resolver o problema?

Padrão 1 - Otimização de consulta e implementação do pool de conexões:


A primeira solução que vem em mente é que o cache usa frequentemente dados não dinâmicos como histórico de reservas, histórico de pagamentos, perfis de usuários e assim por diante. Mas após esse cache de camada de aplicativo, você não pode resolver o problema de latência das APIs que expõem dados dinâmicos, como a localização do motorista atual ou os táxis mais próximos para um determinado cliente ou custo de viagem atual em um determinado momento após o início da viagem.

Você identifica que seu banco de dados provavelmente está fortemente normalizado, então você introduz algumas colunas redundantes (essas colunas aparecem frequentemente em WHERE ou JOIN ON cláusula em consultas) em tabelas muito usadas para fins de desnormalização. Isso reduz as consultas de junção, divide uma consulta grande em várias consultas menores e adiciona seus resultados na camada do aplicativo.

Outra otimização paralela que você pode fazer é ajustar as conexões de banco de dados. Bibliotecas cliente de banco de dados e bibliotecas externas estão disponíveis em quase todas as linguagens de programação. Você pode usar bibliotecas de conjuntos de conexões para armazenar em cache as conexões de banco de dados ou configurar o tamanho do conjunto de conexões no próprio sistema de gerenciamento de banco de dados.

Criar qualquer conexão de rede é caro, pois requer alguma comunicação entre cliente e servidor. O pool de conexões pode ajudá-lo a otimizar o número de conexões. As bibliotecas do pool de conexões podem ajudá-lo a multiplexar conexões — vários threads de aplicativos podem usar a mesma conexão de banco de dados. Verei se consigo explicar o pool de conexões em detalhes em um artigo separado posteriormente.

Sua latência de medição de suas APIs e encontrar provavelmente 20–50% ou mais de latência reduzida. Esta é uma boa otimização neste momento.

Agora você escalou seu negócio para mais uma cidade, mais cadastros de clientes, você lentamente começa a fazer 80 a 100 reservas por minuto. Seu sistema não é capaz de lidar com esta escala. Novamente, você vê que a latência da API aumentou, a camada de banco de dados desistiu, mas desta vez, nenhuma otimização de consulta está dando a você um ganho significativo de desempenho. Você verifica a métrica do sistema, descobre que o espaço em disco está quase cheio, a CPU está ocupada 80% do tempo, a RAM se enche muito rapidamente.

Padrão 2 - Dimensionamento vertical ou dimensionamento:


Depois de examinar todas as métricas do sistema, você sabe que não há outra solução fácil além de atualizar o hardware do sistema. Você atualiza o tamanho da RAM em 2 vezes, atualiza o espaço em disco em, digamos, 3 vezes ou mais. Isso é chamado de dimensionamento vertical ou dimensionamento de seu sistema. Você informa sua equipe de infraestrutura ou equipe de devops ou agentes de data center de terceiros para atualizar sua máquina.

Mas como você configura a máquina para dimensionamento vertical?

Você aloca uma máquina maior. Uma abordagem é não migrar dados manualmente da máquina antiga, em vez de definir a nova máquina como replica para a máquina existente (primary )-crie uma primary replica temporária configuração. Deixe a replicação acontecer naturalmente. Depois que a replicação estiver concluída, promova a nova máquina para primária e coloque a máquina mais antiga offline. Como se espera que a máquina maior atenda a todas as solicitações, todas as leituras/gravações acontecerão nesta máquina.

Frio. Seu sistema está funcionando novamente com maior desempenho.

Sua empresa está indo muito bem e você decide escalar para mais 3 cidades - agora você está operando em 5 cidades no total. O tráfego é 3x vezes maior do que antes, espera-se que você faça cerca de 300 reservas por minuto. Antes mesmo de atingir essa reserva de destino, você novamente atinge a crise de desempenho, o tamanho do índice do banco de dados está aumentando muito na memória, precisa de manutenção constante, a verificação de tabela com índice está ficando mais lenta do que nunca. Você calcula o custo de ampliar ainda mais a máquina, mas não se convence com o custo. O que você faz agora?

Padrão 3 - Segregação de responsabilidade de consulta de comando (CQRS):


Você identifica que a máquina grande não é capaz de lidar com todas as read/write solicitações de. Também na maioria dos casos, qualquer empresa precisa de capacidade transacional em write mas não em read operações. Você também está bem com um pouco de read inconsistente ou atrasada operações e sua empresa também não tem problemas com isso. Você vê uma oportunidade em que pode ser uma boa opção separar o read &write operações físicas da máquina. Ele criará escopo para máquinas individuais para lidar com mais read/write operações.

Agora você pega mais duas máquinas grandes e as configura como replica para a máquina atual. A replicação de banco de dados cuidará da distribuição de dados do primary máquina para replica máquinas. Você navega em todas as consultas de leitura (Consulta (Q ) em CQRS ) para as réplicas — qualquer replica pode atender a qualquer solicitação de leitura, você navega em todas as consultas de gravação (Command (C ) em CQRS ) para o primary . Pode haver pouco atraso na replicação, mas de acordo com seu caso de uso de negócios, tudo bem.

A maioria das startups de médio porte que atendem a algumas centenas de milhares de solicitações todos os dias pode sobreviver com a configuração de réplica primária, desde que arquivem dados mais antigos periodicamente.

Agora você dimensiona para mais 2 cidades, você vê que seu primary não é capaz de lidar com todas as write solicitações de. Muitos write solicitações estão tendo latência. Além disso, o atraso entre primary &replica às vezes afeta clientes e motoristas ex — quando a viagem termina, o cliente paga o motorista com sucesso, mas o motorista não consegue ver o pagamento, pois a atividade do cliente é write solicitação que vai para o primary , enquanto a atividade do motorista é uma read solicitação que vai para uma das réplicas. Seu sistema geral é tão lento que o motorista não consegue ver o pagamento por pelo menos meio minuto - frustrante tanto para o motorista quanto para o cliente. Como você resolve isso?

Padrão 4 - Replicação multiprimária


Você escalou muito bem com primary-replica configuração, mas agora você precisa de mais desempenho de gravação. Você pode estar pronto para comprometer um pouco em read solicitar desempenho. Por que não distribuir a solicitação de gravação para uma replica Além disso?

Em um multi-primary configuração, todas as máquinas podem funcionar como primary &replica . Você pode pensar em multi-primary como um círculo de máquinas dizem A->B->C->D->A . B pode replicar dados de A , C pode replicar dados de B , D pode replicar dados de C , A pode replicar dados de D . Você pode gravar dados em qualquer nó, enquanto lê os dados, você pode transmitir a consulta para todos os nós, quem responder retorna isso. Todos os nós terão o mesmo esquema de banco de dados, mesmo conjunto de tabelas, índice, etc. Portanto, você deve garantir que não haja colisão em id entre nós na mesma tabela, caso contrário, durante a transmissão, vários nós retornariam dados diferentes para o mesmo id .

Geralmente é melhor usar UUID ou GUID para identificação. Mais uma desvantagem desta técnica é — read as consultas podem ser ineficientes, pois envolvem a transmissão da consulta e a obtenção do resultado correto - basicamente, abordagem de coleta de dispersão.

Agora você escala para mais 5 cidades e seu sistema está com problemas novamente. Espera-se que você lide com aproximadamente 50 solicitações por segundo. Você precisa desesperadamente lidar com um grande número de solicitações simultâneas. Como você consegue isso?

Padrão 5 - Particionamento:


Você sabe que seu location banco de dados é algo que está ficando alto write &read tráfego. Provavelmente write:read proporção é 7:3 . Isso está colocando muita pressão sobre os bancos de dados existentes. O location as tabelas contêm poucos dados primários como longitude , latitude , timestamp , driver id , trip id etc. Não tem muito a ver com viagens do usuário, dados do usuário, dados de pagamento etc. Que tal separar o location tabelas em um esquema de banco de dados separado? Que tal colocar esse banco de dados em máquinas separadas com a primary-replica adequada ou multi-primary configuração?

Isso é chamado de particionamento de dados por funcionalidade. Diferentes bancos de dados podem hospedar dados categorizados por diferentes funcionalidades, se necessário, o resultado pode ser agregado na camada de back-end. Usando essa técnica, você pode se concentrar em dimensionar bem as funcionalidades que exigem alta read/write solicitações de. Embora o back-end ou a camada de aplicação tenha que assumir a responsabilidade de juntar os resultados quando necessário, resultando provavelmente em mais alterações de código.

Agora imagine que você expandiu seus negócios para um total de 20 cidades em seu país e planeja expandir para a Austrália em breve. Sua crescente demanda de aplicativo requer uma resposta mais rápida e rápida. Nenhum dos métodos acima pode ajudá-lo ao extremo agora. Você deve dimensionar seu sistema de forma que a expansão para outros países/regiões nem sempre precise que você faça alterações frequentes de engenharia ou arquitetura. Como você faz isso?

Padrão 6 - Escala horizontal:


Você pesquisa muito no Google, lê muito sobre como outras empresas resolveram o problema – e chega à conclusão de que precisa escalar horizontalmente. Você aloca, digamos, 50 máquinas - todas têm o mesmo esquema de banco de dados que, por sua vez, contém o mesmo conjunto de tabelas. Todas as máquinas guardam apenas uma parte dos dados.

Como todos os bancos de dados contêm o mesmo conjunto de tabelas, você pode projetar o sistema de tal forma que a localidade dos dados esteja lá, ou seja; todos os dados relacionados chegam à mesma máquina. Cada máquina pode ter suas próprias réplicas, as réplicas podem ser usadas na recuperação de falhas. Cada um dos bancos de dados é chamado de shard . Uma máquina física pode ter um ou vários shards - cabe ao seu design como você deseja. Você precisa decidir sobre a sharding key de forma que uma única sharding key sempre se refere à mesma máquina. Então você pode imaginar muitas máquinas, todas mantendo dados relacionados no mesmo conjunto de tabelas, read/write solicitações para a mesma linha ou mesmo conjunto de terrenos de recursos na mesma máquina de banco de dados.

A fragmentação é geralmente difícil – pelo menos engenheiros de diferentes empresas dizem isso. Mas quando você atende milhões ou bilhões de solicitações, você precisa tomar uma decisão tão difícil.

Vou discutir sharding em mais detalhes no meu próximo post, então segurando minha tentação de discutir mais neste post.

Agora, como você tem o sharding, está confiante de que pode escalar para muitos países. Seu negócio cresceu tanto que os investidores estão pressionando você para expandir o negócio em todos os continentes. Você novamente vê algum problema aqui. latência da API novamente. Seu serviço está hospedado nos EUA e as pessoas do Vietnã estão tendo dificuldades para reservar passeios. Por quê? O que você faz sobre isso?

Padrão 7 - Partição inteligente do data center:


Seu negócio está crescendo na América, Sul da Ásia e em alguns países da Europa. Você está fazendo milhões de reservas diariamente com bilhões de solicitações chegando ao seu servidor. Parabéns - este é um momento de pico para o seu negócio.

Mas como as solicitações do aplicativo precisam viajar por continentes por centenas ou milhares de servidores na Internet, surge a latência. E quanto à distribuição de tráfego entre data centers? Você pode configurar um data center em Cingapura que trata de todas as solicitações do sul da Ásia, um data center na Alemanha pode lidar com todas as solicitações de países europeus e um data center da Califórnia pode lidar com todas as solicitações dos EUA.

Além disso, você habilita a replicação entre data centers, o que ajuda na recuperação de desastres. Portanto, se o data center da Califórnia replicar para o data center de Cingapura, caso o data center da Califórnia falhe devido a problemas de eletricidade ou calamidade natural, todas as solicitações dos EUA podem retornar ao data center de Cingapura e assim por diante.

Essa técnica de dimensionamento é útil quando você tem milhões de clientes para atender em vários países e não pode acomodar nenhuma perda de dados, é necessário sempre manter a disponibilidade do sistema.

Estas são algumas técnicas gerais passo a passo para dimensionamento de banco de dados. Embora a maioria dos engenheiros não tenha chance suficiente de implementar essas técnicas, mas como um todo, é melhor ter uma ideia mais ampla sobre esse sistema, o que no futuro pode ajudá-lo a fazer um melhor projeto de sistema e arquitetura.

Nos meus próximos artigos, tentarei discutir alguns dos conceitos em detalhes. Sinta-se à vontade para fornecer feedback apropriado para este post, se houver.

O artigo foi publicado originalmente na conta de mídia do autor:https://medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522