¿Deberíamos diseñar programas para suicidarse al azar? [cerrado]

76

En pocas palabras, ¿debemos diseñar la muerte en nuestros programas, procesos y subprocesos en un nivel bajo, para el bien del sistema en general?

Las fallas suceden. Los procesos mueren. Planeamos para el desastre y de vez en cuando nos recuperamos de él. Pero raramente diseñamos e implementamos programas impredecibles de muerte. Esperamos que los tiempos de funcionamiento de nuestros servicios sean siempre que nos cueste mantenerlos en funcionamiento.

Un ejemplo macro de este concepto es el Chaos Monkey de Netflix , que termina al azar las instancias de AWS en algunos escenarios. Afirman que esto les ha ayudado a descubrir problemas y a construir sistemas más redundantes.

A lo que me refiero es a un nivel inferior. La idea es que los procesos tradicionalmente de larga duración salgan aleatoriamente. Esto debería forzar la redundancia en el diseño y, en última instancia, producir sistemas más resistentes.

¿Este concepto ya tiene un nombre? ¿Ya se está utilizando en la industria?

EDITAR

Según los comentarios y las respuestas, me temo que no estaba claro en mi pregunta. Para mayor claridad:

  • sí, quiero decir al azar,
  • sí, quiero decir en producción, y
  • no, no solo para pruebas.

Para explicar, me gustaría hacer una analogía con los organismos multicelulares.

En la naturaleza, los organismos consisten en muchas células. Las células se bifurcan para crear redundancia, y eventualmente mueren. Pero siempre debe haber suficientes células del tipo correcto para que el organismo funcione. Este sistema altamente redundante también facilita la curación cuando se lesiona. Las células mueren para que el organismo viva.

La incorporación de la muerte aleatoria en un programa forzaría al sistema mayor a adoptar estrategias de redundancia para que permanezcan viables. ¿Ayudarían estas mismas estrategias a que el sistema permanezca estable frente a otros tipos de fallas impredecibles?

Y, si alguien ha intentado esto, ¿cómo se llama? Me gustaría leer más sobre esto si ya existe.

    
pregunta jimbojw 25.06.2013 - 01:18

16 respuestas

60

No.

Deberíamos diseñar el manejo correcto de la ruta incorrecta y diseñar casos de prueba (y otras mejoras de procesos) para validar que los programas manejen estas condiciones excepcionales también. Cosas como Chaos Monkey pueden ser parte de eso, pero tan pronto como haces "debes bloquear aleatoriamente" un requisito los bloqueos aleatorios reales se convierten en cosas que los probadores no pueden presentar como errores.

    
respondido por el Telastyn 22.06.2013 - 17:37
19

El proceso de introducir defectos en el software o en el hardware para probar los mecanismos de tolerancia a fallas se llama inyección por error .

De Wikipedia:

  

La técnica de inyección de fallas se remonta a la década de 1970 cuando   se utilizó por primera vez para inducir fallas a nivel de hardware. Este tipo de   la inyección de fallas se llama inyección de fallas implementada en hardware (HWIFI)   e intenta simular fallos de hardware dentro de un sistema. El primero   experimentos en inyección de fallas de hardware involucraron nada más que   Acortar las conexiones en los tableros de circuitos y observar el efecto en el   sistema (fallas puente). Fue utilizado principalmente como una prueba de la   Fiabilidad del sistema hardware. Más tarde se especializó el hardware.   Desarrollado para extender esta técnica, como dispositivos para bombardear.   Áreas específicas de una placa de circuito con fuerte radiación. Fue pronto   encontró que las fallas pueden ser inducidas por técnicas de software y que   Los aspectos de esta técnica podrían ser útiles para evaluar el software.   sistemas En conjunto estas técnicas son conocidas como software.   Inyección de fallas implementada (SWIFI).

    
respondido por el mouviciel 22.06.2013 - 19:56
9

Sí. No. Tal vez.

La terminación periódica es una espada de dos filos. Te van a golpear con un borde u otro, y el menor de los dos males depende de tu situación.

Una ventaja es la confiabilidad: si obliga a que el programa finalice de manera aleatoria (o predecible) y de manera ordenada, puede prepararse para ese evento y lidiar con él. Puede garantizar que el proceso saldrá cuando no esté ocupado haciendo algo útil. Esto también garantiza que los errores que se manifestarían más allá del tiempo de ejecución sancionado no levantarán sus cabezas feas en la producción, lo que es bueno. Apache HTTPD tiene una configuración que le permitirá ajustar cuántas solicitudes servirá un proceso secundario (o subproceso en versiones más recientes) antes de terminar.

La otra ventaja también es la confiabilidad: si no permite que el programa se ejecute por mucho tiempo, nunca encontrará errores que se manifiesten con el tiempo. Cuando finalmente te encuentras con uno de esos errores, es mucho más probable que el programa devuelva una respuesta incorrecta o que no lo haga. Peor aún, si ejecuta muchos subprocesos del mismo trabajo, un error inducido por el tiempo o el conteo podría afectar a un gran número de tareas al mismo tiempo y dar como resultado un viaje de 3 a.m. a la oficina.

En una configuración en la que se ejecutan muchos de los mismos subprocesos (por ejemplo, en un servidor web), la solución práctica es adoptar un enfoque mixto que resulte en una tasa de error aceptable. Si ejecuta 100 subprocesos, ejecutar una relación corta a larga de 99: 1 significa que solo uno exhibirá errores a largo plazo, mientras que los otros continúan haciendo lo que sea que hacen sin fallar. Contrasta eso con la ejecución del 100%, donde corres un riesgo mucho mayor de fallar al mismo tiempo todos los subprocesos.

Donde tengas un solo hilo, probablemente sea mejor dejarlo correr y fallar, porque el tiempo muerto durante un reinicio puede resultar en una latencia no deseada cuando hay trabajo real que hacer que se complete con éxito.

En cualquier caso, es importante que haya algo que supervise los procesos para que puedan reiniciarse inmediatamente. Además, no hay ninguna ley que diga que sus decisiones iniciales sobre cuánto tiempo debe durar un proceso tienen que estar escritas en piedra. La recopilación de datos operativos le ayudará a ajustar su sistema para mantener las fallas a un nivel aceptable.

Recomendaría no hacer una terminación aleatoria, porque eso hace que sea más difícil detectar errores relacionados con el tiempo. Chaos Monkey lo hace para asegurarse de que el software de supervisión funciona, lo cual es un problema ligeramente diferente.

    
respondido por el Blrfl 22.06.2013 - 19:09
9

¿Realmente quieres decir aleatorio? Hacer que tu software se mate a sí mismo suena como una idea terrible. ¿Qué punto serviría?

Supongo que lo que realmente quieres decir es que deberíamos ser realistas con los procesos / procesos de larga ejecución y aceptar que cuanto más se ejecuten, es más probable que se hayan encontrado con algún tipo de error oculto y se hayan metido en un Estado no funcional. Por lo tanto, como una medida puramente pragmática, la vida útil de los procesos y subprocesos debería ser limitada.

Creo que a finales de los años 90, el servidor web Apache usaba algo como esto. Tenían un grupo de procesos de trabajo (no hilos) y cada proceso de trabajo se eliminaría después de una vida fija. Esto evitó que el servidor fuera monopolizado por procesos de trabajo que se habían atascado en algún estado patológico.

No he trabajado en el área por algún tiempo, así que no sé si este es el caso.

    
respondido por el Charles E. Grant 22.06.2013 - 19:18
7

El problema que veo es que si un programa así muere, solo diremos "Oh, es solo otra terminación aleatoria, no hay nada de qué preocuparse". Pero, ¿qué pasa si hay un problema real que necesita solución? Será ignorado.

Los programas ya "al azar" fallan debido a que los desarrolladores hacen mystaykes, errores que se convierten en sistemas de producción, fallas de hardware, etc. Cuando esto ocurra, queremos saberlo para poder solucionarlo. Diseñar la muerte en los programas solo aumenta la probabilidad de fracaso y solo nos obligaría a aumentar la redundancia, lo que cuesta dinero.

No veo nada malo en matar procesos al azar en un entorno de prueba al probar un sistema redundante (esto debería estar sucediendo más de lo que está sucediendo) pero no en un entorno de producción. ¿Retiraríamos un par de unidades de disco duro de un sistema de producción en vivo cada pocos días, o desactivaríamos una de las computadoras en un avión cuando está volando llena de pasajeros? En un escenario de prueba - bien. En un escenario de producción en vivo, prefiero no hacerlo.

    
respondido por el prunge 23.06.2013 - 11:09
4

No debería ser necesario agregar un código de salida aleatorio a la aplicación. Los evaluadores pueden escribir scripts que matan aleatoriamente los procesos de la aplicación.

En las redes, es necesario simular una red no confiable para probar la implementación de un protocolo. Esto no se incorpora en el protocolo; se puede simular a nivel de controlador de dispositivo, o con algún hardware externo.

No agregue el código de prueba al programa para situaciones que pueden lograrse externamente.

Si esto es para producción, ¡no puedo creer que sea serio!

En primer lugar, a menos que los procesos salgan abruptamente para que las transacciones en curso y los datos volátiles se pierdan, no es una implementación honesta del concepto. Las salidas planeadas y con gracia, incluso si se cronometran al azar, no ayudan adecuadamente a preparar la arquitectura para enfrentar los choques reales, que no son elegantes.

Si las fallas reales o realistas están integradas en la aplicación, podrían resultar en daños económicos, al igual que las fallas reales, y el daño económico intencional es básicamente un acto criminal casi por definición.

Es posible que pueda salirse con cláusulas en el acuerdo de licencia que exime a la responsabilidad civil de cualquier daño que surja de la operación del software, pero si esos daños son por diseño, es posible que no pueda renunciar a la responsabilidad penal.

Ni siquiera pienses en acrobacias como esta: haz que funcione de la manera más confiable posible, y coloca situaciones de fallas falsas solo en configuraciones o configuraciones especiales.

    
respondido por el Kaz 25.06.2013 - 00:10
3

Es posible que desee buscar " recuperación proactiva " y " rejuvenecimiento " en el contexto de sistemas distribuidos tolerantes a fallas, para tratar fallas arbitrarias (es decir, no solo procesos fallidos, pero también datos corruptos y comportamiento potencialmente malicioso). Se han realizado muchas investigaciones sobre la frecuencia y las condiciones en que debe reiniciarse un proceso (en un sentido abstracto, en realidad puede ser una máquina virtual o un host). Intuitivamente, puedes entender las ventajas del enfoque como preferir tratar con un proceso muerto que con un proceso traidor ...

    
respondido por el jop 23.06.2013 - 15:21
2

Esto realmente no es diferente de las pruebas. Si está diseñando una solución de conmutación por error siempre disponible (como Netflix), entonces sí, debería probarlo. Sin embargo, no sé si las salidas aleatorias esparcidas por todo el código base son una forma adecuada de probar eso. A menos que realmente intente probar que su diseño es resistente a dispararse en el pie, parecería más apropiado probarlo manipulando el entorno alrededor del código y verificando que se comporte adecuadamente. / p>

Si no estás diseñando sistemas redundantes, entonces no, no deberías agregar esa característica porque agregaste algunas salidas aleatorias. Solo debes eliminar las salidas aleatorias, y entonces no tendrás ese problema. Es posible que su entorno aún le falle, en cuyo momento lo tachará como no soportado / no reparará o endurecerá su código contra esa falla y agregará una prueba para ello. Haga eso con la frecuencia suficiente y se dará cuenta de que en realidad está diseñando un sistema redundante; vea el escenario n.º 1.

En algún momento, puede determinar que ya no está seguro de qué fallas se manejan o no. Ahora puedes comenzar a sacar la alfombra al azar para detectar los puntos de falla.

Lo único interesante del ejemplo de Netflix es que ejecutan estas pruebas en producción. Eso tiene cierto sentido: algunos errores son en realidad solo cosas de producción que son muy difíciles o imposibles de simular en un entorno aislado. Sospecho que Netflix pasó mucho tiempo en entornos de prueba antes de que estuvieran lo suficientemente cómodos para hacer esto en producción, sin embargo. Y realmente todo lo que están haciendo es tratar de que ocurran choques durante las horas de trabajo, lo que tiene cierto sentido para su mercado pero no para muchos otros.

    
respondido por el Mark Brackett 22.06.2013 - 19:38
2

El término que estás buscando ha sido recientemente acuñado por Nassim Nicholas Taleb: Antifragility. Su libro Antifragile es definitivamente recomendado. Apenas lo menciona, pero los paralelos evidentes y evidentes son muy inspiradores. Su idea es ampliar la escala de frágil < - > robusto a frágil < - > robusto < - > antifragile Roturas frágiles con eventos aleatorios, gestiones robustas con eventos aleatorios y ganancias antifriles con eventos aleatorios.

    
respondido por el leancz 10.07.2013 - 14:18
1

Depende. Me he dado cuenta de que los programadores tienden a sobregeneralizar las técnicas que se aplican a su dominio específico ignorando todos los demás. Por ejemplo, el lanzamiento del programa al costo de solucionar todos los errores puede ser bueno ... a menos que programe el controlador de la aeronave, el reactor nuclear, etc. "No optimizar: el costo del programador es mayor que el costo del programa en ejecución" no es necesario válido para HPC ya que un programa relativamente simple puede ocupar un clúster durante meses, etc. (o incluso un programa popular que es usado por una gran cantidad de usuarios). Así que incluso si la compañía X está haciendo S por una buena razón, no es necesario que sigas sus pasos ya que tu situación podría ser diferente.

Por lo general, las rutinas de manejo de errores son la parte peor probada del código. Aunque parece simple, es difícil simular que no hay suficiente memoria o que no hay algún archivo importante. Por esa razón leí los textos que propusieron que el kernel de Unix fallara aleatoriamente algunas llamadas al sistema. Sin embargo, sería más difícil escribir un programa simple (si necesito conectar 3 bibliotecas C ++ juntas para ejecutar un programa en 2 archivos una vez que no quiera molestarme con el manejo de errores). Incluso con excepciones, GC debe asegurarse de dejar atrás un estado coherente (imagine una excepción en medio de agregar un nodo a la lista vinculada).

Cuantos más servicios distribuidos tenga, más fallas tendrá la pregunta de "con qué frecuencia", luego "si" o "cuándo". En los centros de datos, el reemplazo de discos en los RAID es parte de las operaciones de rutina de lo que sé, no de fallas inesperadas. Si opera a gran escala, debe tenerlo en cuenta, incluso si la probabilidad de fallo de un componente es pequeña, es probable que algo falle.

No sé qué es exactamente lo que está haciendo, pero para saber si vale la pena, debe pensar si el fracaso es algo que debe tener en cuenta (ya que ignorarlo cuesta) o es algo demasiado costoso de analizar ( como teniendo en cuenta los errores el tiempo de desarrollo de los costos).

    
respondido por el Maciej Piechotka 22.06.2013 - 21:24
1

El servidor IIS tiene una función configurable que recicla automáticamente los procesos de trabajo, ya sea después de que hayan usado una cierta cantidad de memoria o después de atender un cierto número de solicitudes o después de que hayan estado activas durante un período de tiempo específico. ( enlace ) y ( enlace )

Cuando un CONTAINER como IIS lo hace, tiene sentido proteger el servidor de procesos no autorizados. Sin embargo, preferiría mantener esto desactivado, porque no tiene sentido si ha probado suficientemente su código.

Ya trabajamos en capas no confiables (hardware, red), por lo que nunca escribiría ningún código que elimine aleatoriamente sus subprocesos o procesos de manera intencional. La matanza aleatoria también es una mala idea desde una perspectiva económica: nadie usaría mi API si pensara que la he programado para bloquearse al azar. Por último, si consumiera una API o utilizara un sistema con subprocesos aleatorios, tendría que gastar una gran cantidad de dinero para crear un mecanismo de supervisión lo suficientemente robusto como para poder dormir tranquilo por la noche.

En cambio, si estuviera desarrollando un sistema o una API, escribiría scripts o utilizaría un arnés que haría esto simplemente para poner a prueba la resistencia del sistema. Y haría una prueba de este tipo en todas las compilaciones para identificar las compilaciones malas. Sin embargo, si bien esta sería una prueba necesaria, nunca podría ser una prueba "suficiente".

    
respondido por el user90766 10.07.2013 - 12:54
1

Hay una literatura relacionada con esta idea, se llama software Crash-Only (también Computación orientada a la recuperación) y puede comenzar con este documento de usenix por Candea & Fox desde 2003. En lugar de muertes aleatorias, los autores argumentan que puede mejorar la confiabilidad del sistema deteniendo sus programas solo matándolos, por lo que tiene un solo interruptor para apagar como botón de apagado y una única ruta de inicio bien ejecutada para la recuperación.

Aunque no estoy seguro de qué tan bien captó la idea, algunas de las técnicas específicas siguen siendo útiles. Por ejemplo, no confiando en que su software pueda cerrarse por sí solo cuando se lo solicite y, por lo tanto, utilizar programas de supervisión especializados (por ejemplo, supervisor, etc.) y también pensar detenidamente qué estado del programa es esencial y asegurarse de que se registre en los momentos adecuados en un almacén de datos diseñado para habilitar la recuperación (por ejemplo, una base de datos SQL).

    
respondido por el kzuberi 27.07.2013 - 21:46
1

Realmente al azar, no. Pero probablemente sea una buena idea que los procesos / subprocesos de larga duración salgan / reinicien en un intervalo dado, o después de haber estado inactivos durante un tiempo determinado (pero dependiendo de ciertos criterios), o después de ejecutar un tipo particular de tarea. Los procesos de larga ejecución acumulan inevitablemente estados obsoletos, presumiblemente pueden aferrarse a la memoria impidiendo que se libere el espacio de intercambio, todo lo cual se limpia (o debería recibir) al salir, lo que mejora la estabilidad general del sistema.

    
respondido por el RJVB 28.07.2013 - 10:33
1

Depende del tipo de aplicación que estés diseñando.

Los bloqueos aleatorios son una excelente manera de probar y mejorar la robustez de los sistemas distribuidos (en red).

En el ejemplo de Netflix, cuando su programa depende de servicios remotos que pueden fallar por una variedad de razones que están fuera de su control (el disco duro se deteriora, la pérdida de energía, la lluvia de meteoritos en el centro de datos, etc.). Su servicio necesita seguir funcionando de alguna manera.

¿Cómo haces eso? Agregar redundancia y escalar es una solución común.

Por ejemplo, si un mouse mastica a través del cable de alimentación de su servidor, entonces su servicio debería tener alguna solución para seguir funcionando. Por ejemplo, puede mantener servidores de respaldo redundantes que comenzará a usar en su lugar.

Sin embargo, si su programa es una aplicación de un solo proceso que no funciona en una red, hacer que se elimine a sí mismo no va a probar nada, ya que no hay forma de recuperarse.

Aquí hay un comentario adicional sobre el concepto Chaos Monkeys enlace

    
respondido por el Zain R 30.07.2013 - 02:28
1

Es posible que ocurra un cambio aleatorio de bits debido a la radiación cósmica . Se reconoció este problema y se desarrollaron varias técnicas para evitar que se produzcan cambios de bits.

Sin embargo, no es posible arreglarlo al 100%, y corrupción de memoria todavía puede causar problemas, y estos problemas siguen ocurriendo ( con muy baja probabilidad ).

Ahora para responder a tu pregunta. Ya sea que necesite o no diseñar un sistema muy robusto, depende de lo que esté haciendo. Si necesita crear una nave espacial, es mejor que la haga super robusta, y luego tendrá que tener en cuenta todos los problemas posibles.

Si necesita diseñar una aplicación de escritorio normal, debería considerar los fallos aleatorios como errores en su código.

    
respondido por el BЈовић 02.08.2013 - 09:16
0

Esto no parece una idea tan absurda.

El sistema operativo Android mata y reinicia aleatoriamente las aplicaciones / servicios del usuario todo el tiempo. En mi experiencia, definitivamente me ha ayudado a pensar más profundamente sobre las condiciones de error, así como a diseñar arquitecturas más robustas.

    
respondido por el Xavi 22.06.2013 - 21:40

Lea otras preguntas en las etiquetas