¿Cómo convertir trabajos cron de Linux a "la forma de Amazon"?

112

Para bien o para mal, hemos migrado toda nuestra aplicación web LAMP de máquinas dedicadas a la nube (máquinas Amazon EC2). Va muy bien hasta ahora, pero la forma en que hacemos crons es sub-óptimo. Tengo una pregunta específica de Amazon sobre cómo administrar mejor los trabajos cron en la nube usando "la forma de Amazon".

El problema : tenemos varios servidores web y necesitamos ejecutar crons para trabajos por lotes, como crear feeds RSS, activar correos electrónicos, muchas cosas diferentes en realidad. PERO los trabajos cron solo deben ejecutarse en una máquina porque a menudo escriben en la base de datos, por lo que duplicarían los resultados si se ejecutaran en varias máquinas.

Hasta ahora, hemos designado a uno de los servidores web como el "servidor web maestro" y tiene algunas tareas "especiales" que los otros servidores web no tienen. La compensación por la computación en la nube es la confiabilidad: no queremos un "servidor web maestro" porque es un único punto de falla. Queremos que todos sean idénticos y que puedan aumentar y reducir la escala sin recordar no sacar el servidor web principal del clúster.

¿Cómo podemos rediseñar nuestra aplicación para convertir trabajos cron de Linux en elementos de trabajo transitorios que no tienen un solo punto de falla?

Mis ideas hasta ahora:

  • Tenga una máquina dedicada solo a ejecutar crons. Esto sería un poco más manejable, pero aún sería un punto de falla único y desperdiciaría algo de dinero teniendo una instancia adicional.
  • Es posible que algunos trabajos se trasladen de los crons de Linux a MySQL Events; sin embargo, no soy un gran fanático de esta idea, ya que no quiero poner la lógica de la aplicación en la capa de la base de datos.
  • Quizás podamos ejecutar todos los crons en todas las máquinas, pero cambiar nuestros scripts cron para que todos comiencen con un poco de lógica que implemente un mecanismo de bloqueo para que solo un servidor realmente actúe y los demás simplemente salten. No soy un fanático de esta idea, ya que suena potencialmente defectuoso y preferiría usar una de las mejores prácticas de Amazon en lugar de lanzar la nuestra.
  • Me estoy imaginando una situación en la que los trabajos se programan en algún lugar, se agregan a una cola y luego los servidores web podrían ser cada uno un trabajador, que puede decir "oye, me quedo con este". Amazon Simple Workflow Service suena exactamente a este tipo de cosas, pero actualmente no sé mucho al respecto, por lo que cualquier detalle sería útil. ¿Parece algo pesado para algo tan simple como un cron? ¿Es el servicio adecuado o hay un servicio de Amazon más adecuado?

Actualización: desde que hice la pregunta, vi el seminario web de Amazon Simple Workflow Service en YouTube y me di cuenta de que a las 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ) vislumbré un diapositiva que menciona trabajos cron como una aplicación de muestra. En su página de documentación, " Muestras de AWS Flow Framework para Amazon SWF ", Amazon dice que tiene un código de muestra para crons:

... > Trabajos cron En este ejemplo, un flujo de trabajo de larga duración ejecuta periódicamente una actividad. Se demuestra la capacidad de continuar las ejecuciones como nuevas ejecuciones, de modo que una ejecución puede ejecutarse durante períodos de tiempo muy prolongados. ...

Descargué el AWS SDK para Java ( http://aws.amazon.com/sdkforjava/ ) y, efectivamente, enterrado dentro de unas ridículas capas de carpetas, hay algo de código Java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

El problema es que, si soy honesto, esto realmente no ayuda, ya que no es algo que pueda digerir fácilmente con mis habilidades. Falta la misma muestra en el SDK de PHP y no parece haber un tutorial que recorra el proceso. Básicamente, sigo buscando consejos o sugerencias.

Tom
fuente
2
Posiblemente relacionado: stackoverflow.com/questions/8812025/scheduling-a-job-on-aws-ec2
Ilmari Karonen

Respuestas:

38

Me inscribí en el soporte de Amazon Gold para hacerles esta pregunta, esta fue su respuesta:

Tom

Hice una encuesta rápida a algunos de mis colegas y no encontré nada en el cron, pero después de dormir en él, me di cuenta de que el paso importante puede limitarse al bloqueo. Así que busqué "bloqueo de trabajos cron distribuido" y encontré una referencia a Zookeeper, un proyecto de Apache.

http://zookeeper.apache.org/doc/r3.2.2/recipes.html

http://highscalability.com/blog/2010/3/22/7-secrets-to-successfully-scaling-with-scalr-on-amazon-by-se.html

También he visto una referencia al uso de memcached o un mecanismo de almacenamiento en caché similar como una forma de crear bloqueos con un TTL. De esta manera, establece una bandera, con un TTL de 300 segundos y ningún otro trabajador cron ejecutará el trabajo. El bloqueo se liberará automáticamente una vez que haya expirado el TTL. Esto es conceptualmente muy similar a la opción SQS que discutimos ayer.

Ver también; El gordito de Google http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

Hágame saber si esto ayuda, y no dude en hacer preguntas, somos muy conscientes de que nuestros servicios pueden ser complejos y desalentadores tanto para principiantes como para desarrolladores experimentados. Siempre nos complace ofrecer asesoramiento sobre arquitectura y mejores prácticas.

Atentamente,

Servicios web Ronan G. Amazon

Tom
fuente
13

Creo que este video responde a su pregunta exacta: cronjobs al estilo aws (escalable y tolerante a fallas):

Uso de Cron en la nube con Amazon Simple Workflow

El video describe el servicio SWF utilizando el caso de uso específico de implementar cronjobs.

La relativa complejidad de la solución puede ser difícil de asimilar si viene directamente de un crontab. Hay un estudio de caso al final que me ayudó a comprender lo que le compra esa complejidad adicional. Sugeriría ver el estudio de caso y considerar sus requisitos de escalabilidad y tolerancia a fallas para decidir si debe migrar desde su solución crontab existente.

Nathan Buesgens
fuente
2
esta es una gran respuesta, ya que utiliza una herramienta bien soportada de AWS y SWF es un producto poderoso. El único inconveniente, en mi opinión, es que SWF tiene una curva de aprendizaje significativa y puede ser difícil hacer cosas complicadas. Al menos esa fue mi experiencia con los tutoriales de Java
Don Cheadle
11

Tenga cuidado con el uso de SQS para cronjobs, ya que no garantizan que solo "una sola máquina vea un trabajo". Garantizan que "al menos uno" recibirá el mensaje.

De: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

P: ¿Cuántas veces recibiré cada mensaje?

Amazon SQS está diseñado para proporcionar una entrega "al menos una vez" de todos los mensajes en sus colas. Aunque la mayoría de las veces cada mensaje se enviará a su aplicación exactamente una vez, debe diseñar su sistema de modo que procesar un mensaje más de una vez no cree errores o inconsistencias.

Hasta ahora, puedo pensar en la solución en la que tiene una instancia con la instancia de Gearman Job Server instalada: http://gearman.org/ . En la misma máquina, configura trabajos cron que están produciendo comandos para ejecutar su tarea cronjob en segundo plano. Entonces uno de sus servidores web (trabajadores) comenzará a ejecutar esta tarea, garantiza que solo uno la tomará. No importa cuántos trabajadores tenga (especialmente cuando usa el escalado automático).

Los problemas con esta solución son:

  • El servidor Gearman es un punto único de falla, a menos que lo configure con almacenamiento distribuido, por ejemplo, usando memcached o alguna base de datos
  • Luego, utilizando varios servidores de Gearman, debe seleccionar uno que cree la tarea a través de cronjob, por lo que nuevamente volvemos al mismo problema. Pero si puede vivir con este tipo de punto único de falla, usar Gearman parece una solución bastante buena. Especialmente que no necesita una instancia grande para eso (la micro instancia en nuestro caso es suficiente).
Maciej Majewski
fuente
Bueno, los mensajes permanecen en el servidor una vez recibidos. Depende del desarrollador eliminarlos después. Mientras se procesan, otro servidor no puede acceder a ellos.
Frederik Wordenskjold
2
@FrederikWordenskjold Eso es incorrecto, incluso después de que se haya entregado un mensaje a un cliente, aún se puede entregar a otro, ya que la replicación del estado de SQS es asincrónica. Incluso se le puede dar una copia de un mensaje "después" de que fue eliminado.
Chris Pitman
Esta respuesta está desactualizada. Ahora hay 2 tipos de colas. Utilice FIFO para obtener el procesamiento de una sola vez: un mensaje se entrega una vez y permanece disponible hasta que un consumidor lo procesa y elimina. Los duplicados no se introducen en la cola. aws.amazon.com/sqs/features
Lukas Liesis
10

Amazon acaba de lanzar nuevas funciones para Elastic Beanstalk. De los documentos :

AWS Elastic Beanstalk admite tareas periódicas para
niveles de entorno de trabajo en entornos que ejecutan una configuración predefinida con una pila de soluciones que contiene "v1.2.0" en el nombre del contenedor. "

Ahora puede crear un entorno que contiene un cron.yamlarchivo que configura las tareas de programación:

version: 1
cron:
- name: "backup-job"          # required - unique across all entries in this file
  url: "/backup"              # required - does not need to be unique
  schedule: "0 */12 * * *"    # required - does not need to be unique
- name: "audit"
  url: "/audit"
   schedule: "0 23 * * *"

Me imagino que el seguro de ejecutarlo solo una vez en un entorno de escala automática se utiliza a través de la cola de mensajes (SQS). Cuando el demonio cron desencadena un evento, coloca esa llamada en la cola SQS y el mensaje en la cola solo se evalúa una vez. Los documentos dicen que la ejecución podría retrasarse si SQS tiene muchos mensajes para procesar.

usuario541905
fuente
¿Podrías incluir también algún contenido de los enlaces?
Robert
6

Me encontré con esta pregunta por tercera vez y pensé en contribuir. Hemos tenido este dilema por un tiempo. Sigo sintiendo realmente que a AWS le falta una función aquí.

En nuestro caso, después de analizar las posibles soluciones, decidimos que teníamos dos opciones:

  • Configure un servidor cronjob que ejecute los trabajos que solo deben ejecutarse una vez a la vez, escale automáticamente y asegúrese de que se reemplace cuando ciertas estadísticas de CloudWatch no sean las que deberían ser. Usamos cloud-initscripts para ejecutar cronjobs. Por supuesto, esto viene con un tiempo de inactividad, lo que lleva a cronjobs perdidos (cuando se ejecutan ciertas tareas cada minuto, como lo hacemos nosotros).
  • Usa la lógica que rcronusa. Por supuesto, la magia no está realmente en rcronsí misma, está en la lógica que usa para detectar un nodo que falla (usamos keepalivedaquí) y "actualizar" otro nodo para dominarlo.

Decidimos optar por la segunda opción, simplemente porque es increíblemente rápido y ya teníamos experiencia con servidores web que ejecutan estos cronjobs (en nuestra era anterior a AWS).

Por supuesto, esta solución está diseñada específicamente para reemplazar el enfoque tradicional de cronjob de un nodo, donde el tiempo es el factor decisivo (por ejemplo, "Quiero que el trabajo A se ejecute una vez al día a las 5 a. M." , O como en nuestro caso "Quiero el trabajo B que se ejecute una vez por minuto " ). Si usa cronjobs para activar la lógica de procesamiento por lotes, realmente debería echarle un vistazo SQS. No existe un dilema activo-pasivo, lo que significa que puede usar un solo servidor o una fuerza laboral completa para procesar su cola. También sugeriría buscar SWFescalar su fuerza laboral (aunque auto scalingpodría ser capaz de hacer el truco también en la mayoría de los casos).

Depender de otro tercero era algo que queríamos evitar.

Jaap Haagmans
fuente
6

El 12 de febrero de 2016, Amazon publicó un blog sobre la programación de trabajos SSH con AWS Lambda . Creo que esto responde a la pregunta.

Tom
fuente
1
¿Es posible agregar cronjobs u horarios dinámicos con AWS lambda?
Sanjay Kumar NS
Sí, puede hacer que los eventos de Cloudwatch invoquen Lambda. Mírelo como mejor le parezca.
Michael Quale
4

La forma "Amazon" es distribuirse, lo que significa que los crones voluminosos deben dividirse en muchos trabajos más pequeños y entregarse a las máquinas adecuadas.

Usando la cola SQS con el tipo establecido en FIFO, péguelas para asegurarse de que cada trabajo sea ejecutado por una sola máquina. También tolera fallas, ya que las colas se almacenarán en búfer hasta que una máquina vuelva a girar.

Procesamiento FIFO exactamente una vez : un mensaje se entrega una vez y permanece disponible hasta que un consumidor lo procesa y elimina. Los duplicados no se introducen en la cola.

Considere también si realmente necesita "agrupar" estas operaciones. ¿Qué sucede si las actualizaciones de una noche son considerablemente más grandes de lo esperado? Incluso con recursos dinámicos, su procesamiento podría retrasarse esperando a que se pongan en marcha suficientes máquinas. En su lugar, almacene sus datos en SDB, notifique a las máquinas sobre actualizaciones a través de SQS y cree su fuente RSS sobre la marcha (con almacenamiento en caché).

Los trabajos por lotes son de una época en que los recursos de procesamiento eran limitados y los servicios "en vivo" tenían prioridad. En la nube, este no es el caso.

vsekhar
fuente
Gracias, me gusta la dirección que está describiendo.
Tom
5
Tenga en cuenta que SQS solo garantiza que un mensaje será visto por una máquina eventualmente, no que los mensajes solo los verá un único servidor. Todo lo que ponga en una cola de SQS debe ser idempotente.
Richard Hurt
Mi trabajo cron debería ejecutarse a diario y con SQS solo puede retrasar hasta 15 minutos. Una opción podría ser agregar una etiqueta personalizada al mensaje con el tiempo objetivo para ejecutarlo y volver a colocarlo en la cola si aún no se alcanza ese tiempo, pero esto realmente parece una tontería. Además, todavía necesito un trabajo cron para completar inicialmente la cola. Parece un problema de huevo de gallina :) Pero sigo pensando que SQS es lo correcto para usar, porque garantiza escalabilidad y tolerancia a fallas
Raffaele Rossi
"Los trabajos por lotes son de una época en la que los recursos de procesamiento eran limitados y los servicios 'en vivo' tenían prioridad. En la nube, este no es el caso". Esto es cierto para algunas actividades, pero no para todas. Por ejemplo, procesar registros de tráfico es algo mejor como proceso por lotes que en vivo.
Jordan Reiter
1

¿Por qué construirías el tuyo propio? ¿Por qué no usar algo como Quartz (con programación agrupada)? Ver documentación.

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering

Rama Nallamilli
fuente
Usé Quartz.NET en una solución SaaS que dependía en gran medida de las tareas programadas. Algunas eran tareas de mantenimiento del sistema, pero la mayoría eran actividades programadas por los usuarios finales. Todas nuestras tareas se escribieron en colas de mensajes (amq) para las que teníamos varios servicios idempotentes. La API es muy buena y permite horarios potentes. No agrupamos varias instancias de Quartz, pero lo admite.
Jerico Sandhorn
1

Lo que hacemos es que tenemos un servidor en particular que es parte de nuestro clúster de aplicaciones web detrás de un ELB y también se le asigna un nombre DNS específico para que podamos ejecutar los trabajos en ese servidor específico. Esto también tiene la ventaja de que si ese trabajo hace que el servidor se ralentice, ELB lo eliminará del clúster y luego lo devolverá una vez que finalice el trabajo y vuelva a estar en buen estado.

Funciona como un campeón.

Patrick Steil
fuente
1

Un método para verificar que su expresión cron funciona a la manera de Amazon es ejecutarla a través del comando events. Por ejemplo:

aws events put-rule --name "DailyLambdaFunction" --schedule-expression "<your_schedule_expression>

Si su expresión de programación no es válida, esto fallará.

Más recursos: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html

Kevin Eid
fuente
0

Dado que nadie ha mencionado el evento CloudWatch , diría que es la forma en que AWS hace trabajos cron. Puede ejecutar muchas acciones, como la función Lambda, la tarea ECS.

wanghq
fuente