Estoy tratando de lograr implementaciones de tiempo de inactividad cero para poder implementar menos durante las horas libres y más durante las horas "más lentas", o en cualquier momento, en teoría.
Mi configuración actual, algo simplificada:
- Servidor web A (aplicación .NET)
- Servidor web B (aplicación .NET)
- Servidor de bases de datos (SQL Server)
Mi proceso de implementación actual:
- "Detener" los sitios en el servidor web A y B
- Actualice el esquema de la base de datos para la versión de la aplicación que se está implementando
- Actualizar el servidor web A
- Actualizar el servidor web B
- Vuelva a poner todo en línea
Problema actual
Esto lleva a una pequeña cantidad de tiempo de inactividad cada mes, aproximadamente 30 minutos. Hago esto durante las horas libres, por lo que no es un gran problema, pero es algo de lo que me gustaría escapar.
Además, no hay forma de volver realmente 'atrás'. Por lo general, no hago scripts de DB de reversión, solo scripts de actualización.
Aprovechando el equilibrador de carga
Me encantaría poder actualizar un servidor web a la vez. Saque el servidor web A del equilibrador de carga, actualícelo, vuelva a ponerlo en línea y luego repita para el servidor web B.
El problema es la base de datos. Cada versión de mi software deberá ejecutarse en una versión diferente de la base de datos, por lo que estoy "atascado".
Solución posible
Una solución actual que estoy considerando es adoptar las siguientes reglas:
- Nunca elimine una tabla de base de datos.
- Nunca elimine una columna de base de datos.
- Nunca cambie el nombre de una columna de base de datos.
- Nunca reordene una columna.
- Todos los procedimientos almacenados deben ser versionados.
- Significado: 'spFindAllThings' se convertirá en 'spFindAllThings_2' cuando se edite.
- Luego se convierte en 'spFindAllThings_3' cuando se edita nuevamente.
- La misma regla se aplica a las vistas.
Si bien, esto parece un poco extremo, creo que resuelve el problema. Cada versión de la aplicación llegará a la base de datos de manera ininterrumpida. El código espera ciertos resultados de las vistas / procedimientos almacenados, y esto mantiene válido ese 'contrato'. El problema es que simplemente parece descuidado. Sé que puedo limpiar viejos procedimientos almacenados después de que la aplicación se implemente por un tiempo, pero se siente sucia. Además, depende de que todos los desarrolladores sigan estas reglas, lo que sucederá principalmente, pero imagino que alguien cometerá un error.
Finalmente: mi pregunta
- ¿Es esto descuidado o hacky?
- ¿Alguien más lo está haciendo de esta manera?
- ¿Cómo están resolviendo este problema otras personas?
fuente
Respuestas:
Este es un enfoque muy pragmático para las actualizaciones de software respaldadas por bases de datos. Fue descrito por Martin Fowler y Pramod Sadalage en 2003 y posteriormente escrito en Refactoring Databases: Evolutionary Database Design .
Puedo ver lo que quieres decir cuando dices que parece descuidado, pero cuando se hace intencionalmente y con previsión, y tomándote el tiempo para refactorizar las estructuras no utilizadas de la base de código y la base de datos cuando ya no se usan, es mucho más robusto que Soluciones más simples basadas en scripts de actualización y reversión.
fuente
El "tiempo de inactividad cero" es solo una de las muchas razones posibles para este tipo de enfoque. Mantener un modelo de datos compatible con versiones anteriores de esta manera le ayuda a lidiar con muchos problemas diferentes:
Si tiene muchos paquetes de software accediendo a su base de datos, no tendrá que verificarlos todos si un cambio de esquema los afecta (en organizaciones más grandes con múltiples equipos que escriben programas que acceden a la misma base de datos, los cambios de esquema pueden ser muy difíciles)
si es necesario, puede consultar una versión anterior de uno de sus programas y probablemente se ejecutará contra una base de datos más nueva (siempre y cuando no espere que el programa anterior maneje correctamente las columnas más nuevas)
Importar / exportar datos archivados a la versión actual de la base de datos es mucho más fácil
Aquí hay una regla adicional para su lista
(esto asegura que incluso los programas más antiguos que no conocen las nuevas columnas no rompan nada cuando crean nuevos registros en su base de datos).
Por supuesto, este enfoque tiene un inconveniente real: la calidad de su modelo de datos puede degradarse con el tiempo. Y si tiene control total sobre todas las aplicaciones que acceden a su base de datos, y puede refactorizar todas esas aplicaciones fácilmente cuando, por ejemplo, va a cambiar el nombre de una columna, entonces podría considerar refactorizar las cosas de una manera más limpia.
fuente
Varía de una implementación a otra.
Claro, nunca podría eliminar una tabla o una columna. Nunca podría cambiar nada que rompiera la compatibilidad de la interfaz. Siempre puedes agregar una capa de abstracción. Pero luego tienes que versionar esa abstracción y la versión el versionado.
La pregunta que debe hacerse es si cada versión cambia el esquema de tal manera que no sea compatible con versiones anteriores.
Si muy pocas versiones cambian el esquema de esa manera, entonces el problema de la base de datos es mudo. Simplemente realice una implementación continua de los servidores de aplicaciones.
Las dos cosas que he visto que ayudan más con la implementación de tiempo de inactividad mínimo son:
Esperemos que el resto de sus implementaciones se puedan guardar para ventanas de mantenimiento.
Otras ideas que pueden ayudar a lidiar con las pocas implementaciones que requieren tiempo de inactividad:
fuente
Potencialmente, podría hacerlo así por un poco de esfuerzo adicional.
Naturalmente, las actualizaciones web necesitarían nuevas entradas de configuración para apuntar al nuevo esquema de Db. La cuestión es que si está haciendo lanzamientos una vez al mes y es un equipo pequeño, ¿cuántos cambios de base de datos está haciendo realmente que no son compatibles con versiones anteriores? Si puede controlar eso mediante la prueba, podría obtener una implementación automatizada sin tiempo de inactividad o, en el peor de los casos, solo 5 minutos de tiempo de inactividad.
fuente