Lograr la implementación del tiempo de inactividad cero tocó el mismo problema, pero necesito algunos consejos sobre una estrategia que estoy considerando.
Contexto
Una aplicación basada en la web con Apache / PHP para el procesamiento del lado del servidor y MySQL DB / sistema de archivos para la persistencia.
Actualmente estamos construyendo la infraestructura. Todo el hardware de red tendrá redundancia y todos los cables de red principales se utilizarán en pares unidos para tolerancia a fallas. Los servidores se están configurando como pares de alta disponibilidad para la tolerancia a fallos de hardware y se equilibrarán en carga tanto para la tolerancia a fallos de la máquina virtual como para el rendimiento general.
Es mi intención que podamos aplicar actualizaciones a la aplicación sin ningún tiempo de inactividad. Me he esforzado mucho al diseñar la infraestructura para garantizar que pueda proporcionar un tiempo de actividad del 100%; Sería extremadamente decepcionante tener un tiempo de inactividad de 10-15 minutos cada vez que se aplica una actualización. Esto es particularmente significativo ya que pretendemos tener un ciclo de liberación muy rápido (a veces puede alcanzar una o más emisiones por día.
Topología de la red
Este es un resumen de la red:
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: los servidores de base de datos utilizan la replicación maestro-maestro
Estrategia sugerida
Para lograr esto, actualmente estoy pensando en dividir los scripts de actualización del esquema DB en dos partes. La actualización se vería así:
- El servidor web en el nodo A se desconecta; el tráfico continúa siendo procesado por el servidor web en el nodo B.
- Los cambios de esquema de transición se aplican a los servidores de base de datos
- Servidor web Se actualiza una base de código, se borran las memorias caché y se toman otras acciones de actualización.
- El servidor web A se pone en línea y el servidor web B se desconecta.
- La base de código del servidor web B se actualiza, los cachés se borran y se toman otras acciones de actualización.
- El servidor web B se pone en línea.
- Los cambios finales del esquema se aplican a la base de datos
El 'esquema de transición' se diseñaría para establecer una base de datos compatible con versiones cruzadas. Esto utilizaría principalmente vistas de tabla que simulan el esquema de la versión anterior, mientras que la tabla misma se modificaría al nuevo esquema. Esto permite que la versión anterior interactúe con el DB de manera normal. Los nombres de las tablas incluirían números de versión de esquema para garantizar que no haya ninguna confusión sobre a qué tabla escribir.
'Esquema final' eliminaría la compatibilidad con versiones anteriores y ordenaría el esquema.
Pregunta
En resumen, ¿funcionará esto?
más específicamente:
¿Habrá problemas debido al potencial de escrituras concurrentes en el punto específico del cambio de esquema de transición? ¿Hay alguna manera de asegurarse de que el grupo de consultas que modifican la tabla y crean la vista compatible con versiones anteriores se ejecutan consecutivamente? es decir, con cualquier otra consulta retenida en el búfer hasta que se completen los cambios de esquema, que generalmente solo serán milisegundos.
¿Existen métodos más simples que brinden este grado de estabilidad y que también permitan actualizaciones sin tiempo de inactividad? También se prefiere evitar la estrategia de esquema 'evolutivo' ya que no deseo quedar bloqueado en la compatibilidad con esquemas anteriores.