No ejecutamos trabajos Cron en Nextdoor

Background

En Nextdoor, ejecutamos muchos trabajos programados para varios propósitos importantes, como enviar decenas de millones de correos electrónicos de síntesis a nuestros usuarios diariamente, generar informes internos sobre nuestro crecimiento y algunas tareas operativas. Al igual que muchas otras compañías de Internet (por ejemplo, Airbnb y Quora), comenzamos con Cron y terminamos construyendo nuestro propio reemplazo de cron, al que llamamos Programador Nextdoor.

Hemos estado usando Nextdoor Scheduler durante más de 18 meses y estamos muy contentos con él.

Entonces, ¿cuál es el problema con Cron?

Hay cuatro problemas principales con Cron.

En primer lugar, la forma en que usamos Cron no era escalable. Ejecutamos todos los trabajos Cron en una máquina programadora robusta (c3.8xlarge). A medida que ganamos tracción, los trabajos Cron llevaron la máquina a su límite, en términos de uso de recursos informáticos.

En segundo lugar, editar el tab de texto plano es propenso a errores para administrar trabajos, por ejemplo, agregar, eliminar o pausar trabajos. Por ejemplo, un asterisco adicional impidió que todos los trabajos de producción se ejecutaran el otro día:

1 * * * * * /opt/nextdoor/some_job.sh

En tercer lugar, incurrimos en una gran cantidad de gastos generales operativos con Cron. Tenemos cerca de doscientos trabajos de producción que se ejecutan miles de veces al día, con diferentes frecuencias (por ejemplo, minuciosamente, cada hora, semanalmente). El fracaso laboral es común. La persona de oncall tuvo que reiniciar manualmente los trabajos fallidos varias veces al día, a veces después de la medianoche. A continuación se muestra un ejemplo de una experiencia típica de llamada a distancia: 1) se pagina con la línea de comandos del trabajo fallido; 2) ssh en la máquina del programador; 3) copie & pegue la línea de comandos para volver a ejecutar el trabajo fallido. Esto ciertamente no es bueno para la felicidad de ingeniería, ¡sí, nos importa la felicidad de nuestros empleados!

En cuarto lugar, tuvimos poca visibilidad para los trabajos de producción durante el tiempo de ejecución. No había una manera fácil de saber qué trabajos se estaban ejecutando o si tuvieron éxito.

Decisión

Ya es suficiente. Decidimos construir un reemplazo de cron. Pero, ¿por qué no usamos soluciones de código abierto? No pudimos encontrar uno adecuado. Hablamos de python. Queríamos aprovechar los componentes de infraestructura existentes en la empresa. Queríamos construirlo, entenderlo y poseerlo.

Para solucionar el problema de escalabilidad, hicimos de cada trabajo una tarea asincrónica que se puede ejecutar en un clúster de máquinas de trabajo de tareas. Podemos configurar fácilmente los trabajos que se ejecutan en Taskworker para que se reintenten automáticamente cuando fallan, lo que requiere solo un cambio de código de línea. ¡A nuestros ingenieros de oncall les encanta esta función de reintento automático!

Para reemplazar a Cron, utilizamos el excelente módulo de python ApScheduler para programar trabajos, lo que nos permitió administrar trabajos de forma programática: creamos API REST, herramientas de línea de comandos y una interfaz de usuario web amigable para las personas.

Arquitectura

La siguiente imagen muestra la arquitectura de nuestro sistema de programador.

Nextdoor Programador se implementa con Python / Tornado. Se ejecuta como un proceso de demonio único (Proceso del Planificador) en una sola máquina, que consta de tres componentes.

  1. Programador (o Programador principal). Reemplaza a cron y programa los trabajos para que se ejecuten. Cuando se activa la ejecución de un trabajo, el proceso del Programador simplemente publica un mensaje para el trabajo en Amazon SQS. Un clúster de máquinas de trabajo de tareas toma mensajes de Amazon SQS y ejecuta los trabajos correspondientes. Como se mencionó anteriormente, usamos APScheduler para implementar el planificador principal.
  2. API del programador. Proporciona una interfaz REST para administrar trabajos, por ejemplo, agregar trabajos, pausar/reanudar un trabajo, eliminar trabajos, modificar trabajos e iniciar manualmente un trabajo. Hemos creado herramientas de línea de comandos en la parte superior de la API del Programador para facilitar las operaciones, por ejemplo, pausar un grupo de trabajos a la vez.
  3. INTERFAZ de usuario web. Es una aplicación de una sola página que habla con la API del Programador. Usamos Backbone.js y Bootstrap para implementar la interfaz de usuario Web. Los operadores humanos utilizan principalmente la interfaz de usuario Web para interactuar con el programador Nextdoor.

La información de todos los trabajos y ejecuciones de trabajos se almacena en un almacén de datos. Usamos Postgres principalmente aquí en la puerta de al lado.

Interfaz de usuario web

A los ingenieros les encanta la interfaz de usuario Web de Nextdoor Scheduler, que proporciona una forma intuitiva de administrar trabajos en lugar de tratar con Cron similar a blackbox en los viejos tiempos.

Página de empleos

En esta página, podemos ver qué trabajos tenemos y cuándo se ejecutarán la próxima vez. También podemos hacer clic en» Ejecución personalizada » para iniciar manualmente un trabajo.

Edición de un Trabajo

podemos editar fácilmente un puesto de trabajo, por ejemplo, cambiar la programación y hacer una pausa con un clic de botón! Esto es mucho mejor que modificar el crontab de texto plano en los viejos tiempos.

Ejecuciones Página

por último, tenemos una gran visibilidad, por lo que los trabajos se están ejecutando y si tienen éxito o no.

Rolling out

Escribir código es fácil. La producción es difícil. Para cuando terminamos la implementación de Nextdoor Scheduler, teníamos cerca de 200 trabajos Cron de producción que necesitaban migrar al nuevo sistema.

Aplicamos lo que hemos aprendido del proyecto Taskworker para implementar el sistema de programador Nextdoor. Cuatro pasos:

  1. We dark lanzó el programador de puertas contiguas a la producción — aún no se ejecutaban trabajos de producción con el nuevo sistema.
  2. Agregamos un conmutador de funciones a la clase base de todos los trabajos.
  3. Encendimos lenta y cuidadosamente los interruptores de funciones para cada trabajo durante dos semanas.
  4. Apagamos la vieja máquina planificadora fornida que ejecutaba Cron.

Final feliz

Con el nuevo Programador Nextdoor, podemos ejecutar una instancia EC2 de programador mucho más barata (c3.2xlarge) que antes (c3.8xlarge), mientras mantenemos la carga súper baja a medida que descargamos trabajos para ejecutarse en máquinas de trabajo de tareas distribuidas.

Aquí está la comparación de uso de CPU entre la antigua máquina programadora (gráfico superior) y la nueva máquina programadora (gráfico inferior):

Hemos estado utilizando el Programador de puestos de trabajo por más de 18 meses. Estamos felices hasta ahora. Si está interesado en trabajar en este tipo de problemas y otros desafíos de infraestructura interesantes, ¡estamos contratando!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.