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.

30
demandé sur enricog 2011-05-24 11:56:29

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...

14
répondu Quamis 2011-05-24 08:19:46

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:

  1. 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"
  2. 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)
  3. 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

5
répondu Mahmoud Zalt 2016-04-06 02:53:32

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.

3
répondu inquam 2011-05-24 10:20:07

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.

2
répondu Magic 2011-05-24 10:09:22

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:

  1. boucles - devrait pouvoir être manipulé par des var globales.
  2. 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.

2
répondu Rakesh Sankar 2011-05-24 10:30:48

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.

1
répondu symcbean 2011-05-24 10:39:47

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:

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.

1
répondu Simon East 2018-05-08 01:05:37