parallel - Procesamiento paralelo en PHP-¿Cómo lo haces?
php asynchronous task (7)
Aquí hay un resumen de algunas opciones para el procesamiento paralelo en PHP.
AMPERIO
Checkout Amp: simplificación asíncrona simplificada : esta parece ser la biblioteca de PHP más madura que he visto para el procesamiento paralelo.
Clase de proceso de peec
Esta clase se publicó en los comentarios de la función exec () de PHP y proporciona un punto de partida realmente simple para bifurcar nuevos procesos y hacer un seguimiento de ellos.
Ejemplo:
// You may use status(), start(), and stop(). notice that start() method gets called automatically one time.
$process = new Process(''ls -al'');
// or if you got the pid, however here only the status() metod will work.
$process = new Process();
$process.setPid(my_pid);
// Then you can start/stop/check status of the job.
$process.stop();
$process.start();
if ($process.status()) {
echo "The process is currently running";
} else {
echo "The process is not running.";
}
Otras opciones comparadas
También hay un gran artículo de procesamiento asíncrono o multitarea en PHP que explica los pros y los contras de varios enfoques:
- Extensión pthreads (vea también este artículo de SitePoint )
- Amp / Thread Library
- asíncrono de hack (requiere ejecutar HHVM de Facebook)
- pcntl_fork
- popen
- fopen / curl / fsockopen
Portero
Luego, también está este sencillo tutorial que estaba envuelto en una pequeña biblioteca llamada Doorman .
Espero que estos enlaces brinden un punto de partida útil para más investigación.
Actualmente estoy tratando de implementar una cola de trabajo en PHP. La cola se procesará como un trabajo por lotes y debería poder procesar algunos trabajos en paralelo.
Ya investigué un poco y encontré varias formas de implementarlo, pero no estoy al tanto de sus ventajas y desventajas.
Por ejemplo, hacer el procesamiento paralelo llamando a un script varias veces a través de fsockopen
como se explica aquí:
Fácil procesamiento paralelo en PHP
Otra forma que encontré fue usando las funciones curl_multi
.
curl_multi_exec documentos PHP
Pero creo que esas dos formas agregarán una gran sobrecarga para la creación del procesamiento por lotes en una cola que debería ejecutarse principalmente en segundo plano.
También leí sobre pcntl_fork
que también parece ser una forma de resolver el problema. Pero parece que puede ser realmente complicado si realmente no sabes lo que estás haciendo (como yo en este momento;)).
También eché un vistazo a Gearman
, pero también necesitaría generar los hilos de trabajo de forma dinámica según sea necesario y no solo ejecutar algunos y dejar que el servidor de trabajo de gearman lo enviara a los trabajadores libres. Especialmente porque los subprocesos deben salir de forma limpia después de que se haya ejecutado un trabajo, para que no se produzcan eventuales pérdidas de memoria (el código puede no ser perfecto en ese problema).
Gearman Comenzando
Entonces mi pregunta es, ¿cómo manejas el procesamiento paralelo en PHP? ¿Y por qué elige su método, qué ventajas / desventajas pueden tener los diferentes métodos?
Gracias por cualquier entrada.
Bueno, supongo que tenemos 3 opciones allí:
A. Multi-Thread:
PHP no es compatible con multihilo de forma nativa. Pero hay una extensión de PHP (experimental) llamada pthreads ( https://github.com/krakjoe/pthreads ) que le permite hacer precisamente eso.
B. multiproceso:
Esto se puede hacer de 3 maneras:
- Bifurcación
- Ejecutando Comandos
- Tubería
C. Procesamiento paralelo distribuido:
Cómo funciona:
- La aplicación del
Client
envía datos (mensaje AKA) "se puede formatear con JSON" al motor (Motor MQ) "puede ser un servicio web local o externo" - El
MQ Engine
almacena los datos "principalmente en la memoria y opcionalmente en la base de datos" dentro de las colas (puede definir el nombre de la cola) - La aplicación de
Client
le pide al motor de MQ que los datos (mensajes) se procesen en orden (FIFO o según la prioridad) "también puede solicitar datos de la cola específica".
Algunos motores MQ:
- ZeroMQ (buena opción, difícil de usar) una biblioteca IPC orientada a mensajes, es un servidor de colas de mensajes en Erlang, almacena trabajos en la memoria. Es una biblioteca de socket que actúa como un marco de concurrencia. Más rápido que TCP para productos en clúster y supercomputación.
- RabbitMQ (buena opción, fácil de usar) auto hospedado, colas de mensajes empresariales, no es realmente una cola de trabajo, sino una cola de mensajes que se puede usar como una cola de trabajo pero requiere una semántica adicional.
- Beanstalkd (la mejor opción, fácil de usar) (Laravel built in support, construido por Facebook, para la cola de trabajos) - tiene una herramienta "Beanstalkd console" que es muy agradable
- Gearman (problema: sistema de intermediario centralizado para el procesamiento distribuido)
- Apache ActiveMQ es el intermediario de mensajes de código abierto más popular en Java, (problema: muchos errores y problemas)
- Amazon SQS (Laravel integrado en soporte, Hosted - por lo que no se requiere administración. No es realmente una cola de trabajo, por lo tanto, requerirá trabajo adicional para manejar la semántica, como enterrar un trabajo)
- IronMQ (soporte incorporado de Laravel, Written in Go, disponible tanto en versión en la nube como en las instalaciones)
- Redis (Laravel construido en soporte, no tan rápido ya que no está diseñado para eso)
- Gorrión (escrito en Ruby que basado en memcache)
- Starling (escrito en Ruby que basado en memcache, construido en twitter)
- Kestrel (solo otro QM)
- Kafka (Escrito en LinkedIn en Scala)
- EagleMQ open source, alto rendimiento y gestor de colas liviano (Escrito en C)
Más de ellos pueden ser fundados aquí: http://queues.io
El método descrito en ''Procesamiento paralelo sencillo en PHP'' es francamente aterrador: el principio es correcto, pero ¿la implementación? Como ya ha señalado, las curl_multi_fns proporcionan una forma mucho mejor de implementar este enfoque.
Pero creo que esas 2 formas agregarán bastante sobrecarga
Sí, es probable que no necesite una pila HTTP de cliente y servidor para entregar el trabajo, pero a menos que esté trabajando para Google, su tiempo de desarrollo es mucho más costoso que los costos de hardware, y hay muchas herramientas para administrar HTTP / analizando el rendimiento, y hay un estándar definido que cubre cosas tales como notificaciones de estado y autenticación.
Gran parte de la forma en que implementa la solución depende del nivel de integridad transaccional que necesita y de si necesita procesamiento en el pedido.
Fuera de los enfoques que menciona, recomiendo centrarse en el método de solicitud HTTP utilizando curl_multi_. Pero si necesita un buen control transaccional / para la entrega de pedidos, definitivamente debe ejecutar un demonio de intermediario entre la fuente de los mensajes y los agentes de procesamiento (aquí hay un servidor de un solo subproceso bien escrito adecuado para usar como marco para el intermediario). Tenga en cuenta que los agentes de procesamiento deben procesar un solo mensaje a la vez.
Si necesita una solución altamente escalable, eche un vistazo a un sistema de colas de mensajes adecuado, como RabbitMQ .
HTH
DO.
Prefiero exec () y gearman. exec () es fácil y no requiere conexión y consume menos memoria. gearman debería necesitar una conexión de zócalo y el trabajador debería llevarse algo de memoria. Pero gearman es más flexible y más rápido que exec (). Y lo más importante es que puede implementar el trabajador en otro servidor. Si el trabajo requiere mucho tiempo y recursos. Estoy usando Gearman en mi proyecto actual.
Si su aplicación se va a ejecutar en un entorno unix / linux, le sugiero que utilice la opción de bifurcación. Es básicamente un juego de niños para que funcione. Lo he usado para un administrador de Cron y tenía un código para revertirlo a un código de ruta amistoso de Windows si bifurcar no era una opción.
Las opciones de ejecutar el script completo varias veces agregan un poco de sobrecarga. Si su script es pequeño, podría no ser un problema. Pero probablemente te acostumbrarás a hacer un procesamiento paralelo en PHP por la forma en que elijas. Y la próxima vez, cuando tenga un trabajo que usa 200mb de datos, podría ser un problema. Así que serías mejor aprendiendo una manera en la que puedas mantenerte.
También probé Gearman y me gusta mucho. Hay algunas cosas en las que pensar, pero en su conjunto ofrece una muy buena forma de distribuir trabajos a diferentes servidores ejecutando diferentes aplicaciones escritas en diferentes idiomas. Además de configurarlo, en realidad usarlo desde PHP, o cualquier otro idioma, es ... una vez más ... el juego de niños.
Podría muy bien ser una exageración para lo que necesita hacer. Pero te abrirá los ojos a nuevas posibilidades cuando se trata de manejar datos y trabajos, así que te recomendaría que pruebes a Gearman solo por ese hecho.
Yo uso PHP pnctl - es bueno siempre que sepa lo que hace. Entiendo su situación, pero no creo que sea algo difícil de entender nuestro código, solo tenemos que ser un poco más conscientes que nunca al implementar la cola JOB o el proceso paralelo.
Siento que siempre que lo codifique perfectamente y se asegure de que el flujo sea perfecto fuera de curso, debe tener en cuenta el PROCESO PARALELO cuando lo implemente.
Donde podrías cometer errores:
- Bucles - deben ser capaces de manejar por vars GLOBAL.
- Procesar algunos conjuntos de transacciones: una vez más, siempre que defina los conjuntos adecuados, debería poder hacerlo.
Eche un vistazo a este ejemplo: https://github.com/rakesh-sankar/Tools/blob/master/PHP/fork-parallel-process.php .
Espero eso ayude.
yo uso exec()
Es fácil y limpio. Básicamente, necesitas construir un administrador de hilos y secuencias de comandos, que harán lo que necesites.
No me gusta fsockopen()
porque abrirá una conexión de servidor, que se acumulará y puede alcanzar el límite de conexión de Apache.
No me gustan las funciones de curl
por la misma razón
No me gusta pnctl
porque necesita la extensión pnctl disponible, y tienes que mantener un registro de las relaciones padre / hijo.
nunca jugué con Gearman ...