Traitement parallèle en PHP-Comment faire?
j'essaie actuellement d'implémenter une file d'attente de travail en php. La file d'attente sera alors traitée comme une tâche par lots et devrait pouvoir traiter certaines tâches en parallèle.
j'ai déjà fait quelques recherches et j'ai trouvé plusieurs façons de le mettre en oeuvre, mais je ne suis pas vraiment conscient de leurs avantages et inconvénients.
E. G. faire le traitement parallèle en appelant plusieurs fois un script par fsockopen
comme expliqué ici:
traitement parallèle facile en PHP
J'ai trouvé une autre façon d'utiliser le curl_multi
fonctions.
curl_multi_exec PHP docs
mais je pense que ces 2 façons vont ajouter à peu près beaucoup de frais généraux pour créer le traitement par lots sur une file d'attente taht devrait principalement fonctionner sur l'arrière-plan?
j'ai aussi lu sur <!-Qui semble aussi être un moyen de gérer le problème. Mais qui ressemble peut être vraiment salissant si vous ne savez pas vraiment ce que vous faites (comme moi à l' moment.));
j'ai aussi eu un coup d'oeil à Gearman
, mais là j'aurais aussi besoin de lancer les threads des worker dynamiquement au besoin et pas seulement d'en lancer quelques-uns et de laisser le gearman job server l'envoyer ensuite aux Free workers. Surtout parce que les threads doivent être sortis proprement après qu'une tâche a été exécutée, pour ne pas courir dans des fuites de mémoire éventuelles (le code peut ne pas être parfait dans cette question).
Gearman Prise En Main
alors ma question Est, Comment faites-vous gérer le traitement parallèle en PHP? Et Pourquoi choisissez-vous votre méthode, Quels Avantages/Désavantages peuvent avoir les différentes méthodes?
Merci pour toute entrée.
7 réponses
j'utilise exec()
. Il est facile et propre. Vous avez essentiellement besoin de construire un gestionnaire de thread, et des scripts de thread, qui feront ce que vous avez besoin.
je n'aime pas fsockopen()
parce qu'il ouvrira une connexion serveur, qui s'accumulera et pourra atteindre la limite de connexion d'apache
je n'aime pas curl
fonctions pour la même raison
je n'aime pas pnctl
parce qu'il a besoin de l'extension pnctl disponible, et vous devez garder une trace de parent / enfant relation.
n'a jamais joué avec gearman...
Eh bien je suppose que nous avons 3 options là:
A. Multi-Thread:
PHP ne supporte pas multithread nativement. Mais il y a une extension PHP (expérimental) a appelé les pthreads (https://github.com/krakjoe/pthreads) qui permet de faire exactement cela.
B. Multi-Process:
Cela peut se faire de 3 façons:
- bifurcation
- exécution Les commandes
- Tuyauterie
C. Traitement Parallèle Distribué:
Comment cela fonctionne:
Client
Application envoie des données (AKA message) "peut être au format JSON" pour le Moteur (MQ Moteur) "peut être local ou à l'extérieur d'un service web"MQ Engine
stocke les données "la plupart du temps en mémoire et optionnellement dans la base de données" à l'intérieur d'une file d'attente (vous pouvez définir le nom de la file d'attente)Client
App demande au moteur MQ un message de données à traiter dans l'ordre (FIFO ou basé sur la priorité) "vous pouvez également demander des données à partir d'une file d'attente spécifique".
Certains MQ Moteur:
- ZeroMQ (bonne option, difficile à utiliser) une bibliothèque IPC orientée message, est un serveur de file D'attente de messages dans Erlang, stocke les travaux en mémoire. C'est une bibliothèque socket qui agit comme un cadre de concurrence. Plus rapide que TCP pour les produits groupés et calcul intensif.
- RabbitMQ (bonne option, facile à utiliser) auto-hébergé, les Files D'attente de messages D'entreprise, pas vraiment une file d'attente de travail - mais plutôt une file d'attente de message qui peut être utilisé comme une file d'attente de travail, mais nécessite une sémantique supplémentaire.
- Beanstalkd (meilleure option, facile à utiliser) (Laravel construit en support, construit par facebook, pour la file d'attente de travail) - a un outil" beanstalkd console " qui est très agréable
- Gearman (problème: courtier centralisé système de traitement distribué)
- Apache ActiveMQ le courtier de messages open source le plus populaire en Java, (problème: beaucoup de bogues et de problèmes)
- Amazon SQS (Laravel construit en support, hébergé - donc aucune administration est nécessaire. Pas vraiment une file d'attente de travail nécessitent ainsi un travail supplémentaire pour gérer la sémantique comme l'enterrement d'un emploi)
- IronMQ (Laravel construit en support, écrit en Go, disponible à la fois en version cloud et sur site)
- Redis (Laravel construit dans le soutien, pas aussi rapide que son pas conçu pour cela)
- Moineau (écrit en Ruby que, sur la base de memcache)
- Starling (écrit en Ruby que basé sur memcache, construit dans twitter)
- Kestrel (juste un autre QM)
- Kafka (Signé à LinkedIn en Scala)
- EagleMQ open source, haute performance et léger gestionnaire de file d'attente (écrit en C)
Plusieurs d'entre eux peuvent être foun ici: http://queues.io
si votre application doit fonctionner sous un environnement unix / linux, je vous suggère d'utiliser l'option bifurcation. En gros, c'est un jeu d'enfant pour le faire fonctionner. Je l'ai utilisé pour un cron manager et avait le code pour qu'il revienne à un codepath Windows si bifurcation n'était pas une option.
les options d'exécution de l'ensemble du script plusieurs fois, comme vous le dites, ajoutent un peu de overhead. Si votre script est petit, ce ne sera peut-être pas un problème. Mais vous vous habituerez probablement à faire le traitement parallèle en PHP par la façon dont vous choisissez d'aller. Et la prochaine fois que vous avez un travail qui utilise 200 Mo de données il pourrait très bien être un problème. Donc tu ferais mieux d'apprendre un moyen de t'y tenir.
j'ai aussi testé Gearman et je l'aime beaucoup. Il y a une petite chose à laquelle réfléchir, mais dans l'ensemble, il offre une très bonne façon de distribuer des œuvres à différents serveurs exécutant différentes applications écrites dans différentes langues. Outre la mise en place, en fait l'utiliser à partir de PHP, ou tout autre langage pour cette matière, est... une fois de plus... un jeu d'enfant.
Il pourrait très bien être exagéré pour ce que vous devez faire. Mais cela vous ouvrira les yeux sur de nouvelles possibilités en ce qui concerne le traitement des données et des travaux, donc je vous recommande d'essayer Gearman pour ce seul fait.
je préfère exec () et gearman. exec () est facile et sans connexion et consomme moins de mémoire. gearman besoin d'une connexion de socket et le travailleur devrait prendre un peu de mémoire. Mais gearman est plus flexible et plus rapide que exec(). Et le plus important est qu'il peut déployer le travailleur dans d'autres serveur. Si le travail est du temps et des ressources. J'utilise gearman dans mon projet actuel.
j'utilise la pnctl de PHP - c'est bon tant que vous savez ce que vous faites. Je comprends votre situation, mais je ne pense pas que ce soit quelque chose de difficile à comprendre notre code, nous devons juste être un peu plus conscients que jamais lors de la mise en œuvre de la file d'attente de travail ou du processus parallèle.
je pense que tant que vous le codez parfaitement et assurez-vous que le flux est parfait hors cours, vous devriez garder le processus parallèle à l'esprit lorsque vous mettez en œuvre.
où vous pouvez faire erreurs:
- boucles - devrait pouvoir être manipulé par des var globales.
- Traitement de certaines transactions de nouveau tant que vous définissent les ensembles correcte, vous devriez être en mesure de le faire.
regardez cet exemple - https://github.com/rakesh-sankar/Tools/blob/master/PHP/fork-parallel-process.php.
j'Espère que ça aide.
la méthode décrite dans 'Easy parallel processing in PHP' est carrément effrayante - le principe est correct - mais l'implémentation??? Comme vous l'avez déjà souligné, le curl_multi_ fns offre une bien meilleure façon de mettre en œuvre cette approche.
Mais je pense que ces 2 façons ajoutera assez bien frais généraux
Oui, vous n'avez probablement pas besoin D'une pile HTTP client et serveur pour passer le travail - mais à moins que vous ne travailliez pour Google, votre temps de développement est beaucoup plus cher que vos coûts de matériel - et il ya beaucoup d'outils pour gérer HTTP/analyser les performances - et il ya une norme définie couvrant des choses telles que les notifications d'état et l'authentification.
la façon dont vous mettez en œuvre la solution dépend en grande partie du niveau d'intégrité transactionnelle dont vous avez besoin et si vous avez besoin de traitement en ordre.
parmi les approches que vous mentionnez, je vous recommande de vous concentrer sur la méthode de requête HTTP en utilisant curl_multi_ . Mais si vous avez besoin d'un bon contrôle transactionnel / livraison de la commande, alors vous devez absolument exécuter un démon broker entre la source des messages et les agents de traitement (il y a un serveur fileté simple bien écrit qui peut être utilisé comme cadre pour le broker ici). Notez que les agents de traitement doivent traiter un seul message à la fois.
Si vous avez besoin d'une solution hautement évolutive, alors jetez un oeil à un bon message queuing système tels que RabbitMQ.
HTH
C.
voici un résumé de quelques options pour le traitement parallèle en PHP.
AMP
Caisse amp-concurrence asynchrone rendue simple - cela semble être la bibliothèque PHP la plus mature que j'ai vu pour le traitement parallèle.
classe de procédé de la Peec
Cette classe a été publiée dans les commentaires de la fonction exec() de PHP et fournit un point de départ très simple pour chercher de nouveaux processus et garder une trace d'eux.
Exemple:
// 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.";
}
Autres Options Comparées
Il y a aussi un grand article traitement Async ou multitâche en PHP qui explique les avantages et les inconvénients de différentes approches:
- pthreads extension (voir aussi c'SitePoint article)
- Ampli\Bibliothèque De Threads
- hack asynchrone (nécessite l'exécution de Facebook est HHVM)
- pcntl_fork
- popen
- fopen/curl / fsockopen
Portier
alors, il y a aussi ce tutoriel qui était enveloppé dans une petite bibliothèque appelée Portier.
j'Espère que ces liens fournissent un point de départ utile pour la recherche.