Pregunta

Tengo una tarea programada que ejecuta un script de forma regular (cada hora).Este script interactúa intensamente con la base de datos y el sistema de archivos y normalmente tarda varios minutos en ejecutarse.El problema es que el uso de la CPU del servidor aumenta mientras se ejecuta el script y ralentiza las operaciones normales.¿Hay alguna manera de acelerar este proceso para que demore más pero no consuma tantos recursos?

He mirado diferentes opciones de configuración para PHP pero no parece haber ninguna que se ajuste a mis necesidades.

Establecer Memory_limit en php.ini en un valor inferior hace que mis objetos de datos se desborden con bastante facilidad.

He visto publicaciones similares en las que la gente sugería usar sleep() en ciertos puntos del script, pero eso no evita que el script acelere el servidor.

La solución óptima sería alguna forma de decirle a la pila Lamp (en este caso Wamp) que solo use el 10% de utilización máxima de la CPU.No me preocupa en absoluto el tiempo de ejecución y preferiría que demore más si eso significa ahorrar ciclos de CPU por segundo.Mi solución alternativa sería configurar un servidor diferente con replicación de base de datos para que el cron pueda funcionar sin ralentizar todo lo demás.

Ambiente:Servidor Windows 2k3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1

Agradezco cualquier idea sobre esta situación.

EDITAR: Agradezco todas las respuestas, incluso las que son específicas de *nix.Todavía es temprano en mi situación para cambiar el entorno de alojamiento.Con suerte, esta pregunta ayudará a otros, independientemente del sistema operativo.

¿Fue útil?

Solución

Este es un problema complicado.Si está ejecutando el script PHP a través de la línea de comando, puede establecer la prioridad de programación del proceso en baja (start /low php.exe myscript.php Yo creo).Si su propio script PHP en realidad realiza la mayor parte del procesamiento que consume su CPU, esto podría funcionar.Sin embargo, usted dijo que está realizando una intensa interacción con la base de datos y el sistema de archivos, lo que esta solución no ayudará.Parece que hay una sugerencia de MySQL "LOW_PRIORITY" para consultas INSERTAR y ACTUALIZAR que pueden ayudarlo, pero no las he probado.

Otros consejos

Puede configurar procesos en Windows para que sea una prioridad más baja. no estoy seguro de cómo el proceso se inició, pero si se establece que el proceso sea una prioridad baja, lo que quiere recursos de la CPU obtendrán si se establece la prioridad para ser realmente bajo.

UNIX (LAMP) Me las arreglé para resolver el problema mediante la comprobación de la carga del servidor antes de continuar el bucle

function get_server_load($windows = 0) {
    $os = strtolower(PHP_OS);
    if(strpos($os, "win") === false) {
        if(file_exists("/proc/loadavg")) {
         $load = file_get_contents("/proc/loadavg");
         $load = explode(' ', $load);
         return $load;
        }
        elseif(function_exists("shell_exec")) {
         $load = explode(' ', `uptime`);
         return $load;
        }
        else {
         return "";
        }
    }
}

for(... ... ...){
    $data = get_server_load(); 
    if($data[0] < 0.2){
     // continue
    }else{
        sleep(1);
    }
}

Esta función debería funcionar también en las ventanas, pero no puedo garantizarlo. En Linux se le da una copia de una matriz con la carga del pasado 1 minuto, 5 minutos y 15 minutos

Además, considere a iniciar las secuencias de comandos (CLI por si) con una prioridad más baja (en Linux, utilice "agradable")

También puede utilizar otros valores antes de continuar el bucle, al igual que el número de procesos activos Apache (se puede analizar el 127.0.0.1/server_status?auto página si ha activado la mod_status en httpd.conf), o también la situación de MySQL (conexiones activas?)

Se puede alterar su entrada cron para iniciar la secuencia de comandos utilizando agradable ?

No es una buena idea para utilizar un servidor para servir a los clientes y analizar los datos.

Así que si usted está buscando una solución final, hacer algunos rediseño de su solicitud y sacar datos del análisis de datos de las interfaces y de la base de datos activa a otro sistema dedicado a esta tarea.

Incluso si se puede estrangular con éxito el analizador, que sería utilizar los recursos preciosos de otro modo estaría disponible para servir a los usuarios.

Esto podría ser un cambio difícil pero es posible que la pena Refactorizando las estructuras de datos en iteradores. Además, si usted tiene referencias circulares en su código, proporcionar un método como clearReferences () que desarma estos objetos. Este es un problema que se resuelve en PHP 5,3 por cierto.

Así que si usted tiene:

class Row
{
    protected $_table;

    public function __construct($table)
    {
        $this->_table = $table;
    }
}

class Table
{
    protected $_row;

    public function __construct()
    {
        $this->_row = new Row($this);
    }
}

Añadir clearReferences () para la clase Fila:

class Row
{
    public function clearReferences()
    {
        $this->_table = null;
    }
}

Eso es todo lo que puedo llegar a por el momento.

Tengo un montón de secuencias de comandos que corro desde cron de manera similar utilizando agradable:

0 * * * * agradable -n19 php myscript.php

Esto no ayudará a la utilización de RAM (sólo cambiando la forma en que el guión está escrito puede hacer eso), pero sólo se utiliza la CPU que de otro modo sería ocioso.

EDIT: no ver que la cuestión involucrado un entorno Windows, lo siento ... dejando esto en para cualquier usuario en Unix que tienen el mismo problema ..

Tal vez lo que su guión es simplemente tratar de hacer demasiado a la vez. ¿Sería menos si se llevó a cabo tres veces por hora?

Otra solución podría ser la configuración de un servidor adicional sólo para la ejecución de este tipo de procesamiento 'back-end'. Esto sería particularmente eficaz si no está poniendo la carga indebida en la base de datos, sólo el servidor web.

Sin embargo, otro enfoque para tener en cuenta es si se trata de trabajo se puede dividir en una dirección diferente. Este tipo de secuencias de comandos a menudo tienen unos grandes sentencias SQL que generan resultados se utilizan para generar una gran cantidad de sentencias SQL pequeños. En este último caso se puede dejar a un lado en alguna parte, que se pueden ejecutar en contra de la base de datos como un paso posterior. Dicho enfoque también podría permitir que utiliza una consulta sin búfer a buscar los datos pre-procesamiento que podría reducir significativamente el consumo de memoria en el código PHP.

Si lo tienes (Apache) que se ejecuta como un servicio, puede cambiar la prioridad ajustes en el control de victorias centro / servicios. Su uso de la CPU se alza todos modos, pero se prefieren otros programas por el planificador. También tratar de poner la base de datos / servidor en un hd diferente de su Aplicaciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top