Múltiples cronjobs simultaneos

  • Autor Autor BotPress
  • Fecha de inicio Fecha de inicio
B

BotPress

Delta
Programador
Verificación en dos pasos activada
Hola betas programadores. Llevo como loco unos dias probando varias formas de hacer el código efectivo y no encuentro forma.

La cosa es que tengo una plataforma que por cada usuario registrado hay que ejecutar unos 10-15 scripts cada X minutos. Hay algunos que son bastante rápidos y otros que tardan un poco más.

La cosa es que no se de que forma optimizar esto. He intentado dos formas diferentes y ninguna cumple con lo que necesito, incluso una de ellas, me rompe el servidor.

El entorno está programado con Laravel y lo que he hecho primeramente es configurar en plesk 13 cron jobs con una url y en esa url hacia un loop por cada usuario y llamaba a la función que ejecutaba todas las consultas mysql y acciones. El problema de este caso es que tarda demasiado una url ya que ejecuta las acciones en orden y acaba dando timeout (y no quiero darle 10 minutos de timeout al servidor por motivos de seguridad)

La segunda que he intentado también es configurar en plesk 13 conjobs pero en vez de llamar a una función dentro del loop lo que hago es montar un multi_curl_exec. Este método me gusta ya que ejecuta las acciones de cada usuario por separado y si alguno tiene algun problema es más facil de detectar. El problema de este método es que me pone la CPU a 100% y me tira el servidor en pocos minutos.

La verdad que no se como hacerlo. Tengo recursos para comprar un servidor tan grande como necesite pero ahora mismo tengo uno de 2GB/2CPU y debería ser suficiente por la carga de usuarios que tengo.

¿Alguien tiene alguna plataforma que haya tenido que hacer algo parecido? Todos las acciones son necesarias hacerlas cada corto plazo de tiempo ya que son estadisticas en su mayoría.

Saludos a todos,
 
Hombre, tienes que optimizar tu consulta.
Actualizar las estadísticas cuando el usuario haga login o cuando este las solicite usas un:
if(random(0,10)==1) actualizar($usuario).
o también puedes almacenar en la variable $_SESSION['last_update']) la hora en que actualizo y en base a los minutos de diferencia llamar a actualizar($usuario)

No hay necesidad de actualizar a todos los usuarios, solo a los que requieran las estadísticas.
 
set_time_limit(0); // sin limites de tiempo de ejecución y aumentando la memoria en php.ini

Si es una tarea del servidor no habría lió en dejarlo trabajar por un tiempo mas del normal, ya que si fuera que se ejecuta indefinidamente por las acciones de los usuarios ahí si habría lió,

También podría ser hacer las tareas cuando hay menos trafico, otra seria dividir los procesos largos en varios scripts diferentes (uno por cada cpu o por cada hilo, núcleo o core lo que sea), si ahora mismo tienes dos cpus modificar el script y hacerlo en dos archivos .php ya que cada script agarra un hilo del procesador entonces si lo divides durara menos en hacer la misma tarea, en mi caso tenia un proceso que duraba 6 horas, después de dividir el mismo proceso en tres archivos php ahora toma 1 hora pasadita, antes un solo hilo del cpu se ponía al 100% y ahora tres hilos se ponen casi al cien, también cabe decir que actualice a php 7 (algunas cosas se rompieron como la conexión y la forma de llamar a las consultas, fue cuestión de actualizar hacia mysqli)

El tipo de tabla utilizado, si haces mas lecturas que escrituras MyIsam va como un rayo, pero si usas transacciones entonces definitivamente Innodb, aunque hay de tareas a tareas y habeces unas van mas rápido en cierto motor, en mi caso actualizando muchas filas me va mas rápido en myisam por ejemplo creando las urls usando un solo script, en este caso con innodb se toma una eternidad, en otro proceso si quiero que múltiples scrips actualicen una tabla entonces innodb es mas rápido, dependiendo de la situación, myisam bloquea toda la tabla en cualquier escritura y innodb solo bloquea el registro actual, digo esto por que quizás con un pequeño ajuste como cambiando de motor haga una gran diferencia.
 
Muchas gracias a ambos.
De momento lo que he hecho es optimizar mis consultas MySQL y aumentar el time_limit sólo en el fichero que me interesa.

He pasado de utilizar el 100% de CPU al 25-30% haciendo las mismas acciones. A veces la solución es trabajar un poco más las SQL aunque parezca una tonteria. Es increible la mejora de rendimiento.

Gracias a los dos nuevamente,
Saludos cordiales,

- - - Actualizado - - -
[MENTION=45882]Rodrhigo[/MENTION] [MENTION=82252]Joefay[/MENTION]
 
Hombre, tienes que optimizar tu consulta.
Actualizar las estadísticas cuando el usuario haga login o cuando este las solicite usas un:
if(random(0,10)==1) actualizar($usuario).
o también puedes almacenar en la variable $_SESSION['last_update']) la hora en que actualizo y en base a los minutos de diferencia llamar a actualizar($usuario)

No hay necesidad de actualizar a todos los usuarios, solo a los que requieran las estadísticas.

Esta me parece una muy buena opción, ahorras recursos y mantienes a cada usuario actualizado según su actividad. :encouragement:
 
Una opción es usar el servicio de AWS SQS, que sirve, si mal no recuerdo, para procesar colas.

Yo considero que la clave seguramente está en la forma en que está desarrollado esos cron. Yo tengo compañeros de profesión que consiguen procesar más de 25000 productos (ecommerce), en un minutos. Y todo ha sido cambiando la estrategia en la que han abordado esos procesos.
 
Atrás
Arriba