Atingir Zero Downtime Deployment abordou o mesmo problema, mas preciso de alguns conselhos sobre uma estratégia que estou considerando.
Contexto
Um aplicativo baseado na Web com Apache / PHP para processamento no servidor e sistema de arquivos / banco de dados MySQL para persistência.
Atualmente, estamos construindo a infraestrutura. Todo o hardware de rede terá redundância e todos os cabos principais da rede serão usados em pares ligados para tolerância a falhas. Os servidores estão sendo configurados como pares de alta disponibilidade para tolerância a falhas de hardware e terão balanceamento de carga para tolerância a falhas de máquina virtual e desempenho geral.
É minha intenção que possamos aplicar atualizações ao aplicativo sem nenhum tempo de inatividade. Fiz um grande esforço ao projetar a infraestrutura para garantir que eu possa fornecer 100% de tempo de atividade; seria extremamente decepcionante ter 10 a 15 minutos de inatividade toda vez que uma atualização fosse aplicada. Isso é particularmente significativo, pois pretendemos ter um ciclo de lançamento muito rápido (às vezes, pode atingir um ou mais lançamentos por dia.
Topologia de rede
Este é um resumo da rede:
Load Balancer
|----------------------------|
/ / \ \
/ / \ \
| Web Server | DB Server | Web Server | DB Server |
|-------------------------|-------------------------|
| Host-1 | Host-2 | Host-1 | Host-2 |
|-------------------------|-------------------------|
Node A \ / Node B
| / |
| / \ |
|---------------------| |---------------------|
Switch 1 Switch 2
And onward to VRRP enabled routers and the internet
Nota: os servidores de banco de dados usam replicação master-master
Estratégia sugerida
Para conseguir isso, atualmente estou pensando em dividir os scripts de atualização do esquema do DB em duas partes. A atualização seria assim:
- O servidor da Web no nó A é retirado da rede; o tráfego continua sendo processado pelo servidor da web no nó B.
- Alterações de esquema de transição são aplicadas aos servidores de banco de dados
- Servidor da Web Uma base de código é atualizada, os caches são limpos e quaisquer outras ações de atualização são executadas.
- O servidor Web A é colocado online e o servidor B é colocado offline.
- A base de código do servidor Web B é atualizada, os caches são limpos e quaisquer outras ações de atualização são executadas.
- O servidor da Web B é colocado online.
- Alterações finais do esquema são aplicadas ao banco de dados
'Esquema de transição' seria projetado para estabelecer um banco de dados compatível com a versão cruzada. Isso usaria principalmente visualizações de tabela que simulam o esquema da versão antiga, enquanto a própria tabela seria alterada para o novo esquema. Isso permite que a versão antiga interaja com o banco de dados normalmente. Os nomes das tabelas incluiriam números de versão do esquema para garantir que não haja confusão sobre em qual tabela gravar.
'Esquema final' removeria a compatibilidade com versões anteriores e arrumaria o esquema.
Questão
Em suma, isso vai funcionar?
mais especificamente:
Haverá problemas devido ao potencial de gravações simultâneas no ponto específico da mudança de esquema de transição? Existe uma maneira de garantir que o grupo de consultas que modifica a tabela e cria a exibição compatível com versões anteriores seja executado consecutivamente? ou seja, com outras consultas sendo mantidas no buffer até que as alterações no esquema sejam concluídas, o que geralmente será de apenas milissegundos.
Existem métodos mais simples que fornecem esse grau de estabilidade e também permitem atualizações sem tempo de inatividade? Também é preferível evitar a estratégia de esquema "evolucionária", pois não desejo ficar preso à compatibilidade de esquemas com versões anteriores.