8
votes

Motifs pour PHP Multi Processes?

Quel modèle de conception existent pour réaliser l'exécution de certains processus PHP et la collecte des résultats dans un processus PHP?

arrière-plan:
J'ai beaucoup de grands arbres (> 10000 entrées) en PHP et je dois exécuter des contrôles récursifs dessus. Je veux réduire le temps d'exécution écoulé.


1 commentaires

... Écris une extension C?


7 Réponses :


11
votes

à partir de votre script PHP, vous pouvez lancer un autre script (à l'aide de exécutant code>) pour effectuer le traitement. Enregistrer les mises à jour d'état dans un fichier texte, qui pourrait ensuite être lu périodiquement par le thread parent.

Remarque: Pour éviter PHP en attente du script EXED CODE> 'de terminer, tuyez la sortie dans un fichier : p> xxx pré>

alternativement strong>, vous pouvez fourrer un script à l'aide du PCNTL Fonctions. Cela utilise un script PHP, qui, lorsque vous avez changé peut détecter s'il s'agit du parent ou de l'enfant et de fonctionner en conséquence. Il existe des fonctions pour envoyer / recevoir des signaux dans le but de communiquer entre parents / enfant, ou que vous disposez du journal des enfants à un fichier et que le parent lu à partir de ce fichier. P>

à partir du PCNTL_FORK Page manuelle: P>

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}


4 commentaires

Désolé, pas vraiment d'expérience pratique. À travers donc, je suis surpris de voir combien de personnes disent catégoriquement qu'il n'y a aucun moyen de préparer PHP


J'ai écrit un wrapper perl avant d'utiliser Fork (à Perl) pour exécuter un script PHP avec d'excellents résultats.


@powtac puis-je vous demander ce que vous recherchez ce n'est pas dans les réponses données?


Il n'y a pas beaucoup de contrôle sur les processus et j'ai besoin d'une solution plus générique. pour différents arbres et objets et parties du code. La solution de file d'attente de message correspond à plus.



4
votes

Ceci pourrait être un bon moment à envisager d'utiliser un file d'attente de message , même si vous exécutez Tout sur une machine.


5 commentaires

Le problème avec une file d'attente de message est que nous avons besoin du même espace de noms global / périmètre des différents processus.


Je ne sais pas ce que vous avez besoin de la portée partagée et de l'espace de noms, mais une file d'attente de messages, couplée à la mémoire partagée (par exemple, MemCache) pourrait être une possibilité.


Le message QUE Solution correspond au meilleur pour cette application à grande échelle. Avec MemCache, nous pouvons contrôler très bien quoi faire quand. Parce que tout est très oo il n'y a pas un gros problème avec l'espace de noms. Je dois juste remplir les objets de et dans Memcache.


Avec MemCache, je peux partager la charge également sur différentes machines. Cela signifie que je peux très bien évoluer à l'avenir.


Aussi Memcache stocke la plaine des objets PHP, il n'est pas nécessaire de les sérialiser et de les désériorialiser.



2
votes

Utiliser Web ou CLI?

Si vous utilisez Web, vous pouvez intergramser cette partie de Quercus puis vous pourrait utiliser les avantages de Java Multhreading.

Je ne sais pas réellement à quel point le quercus fiable est cependant. Je suggérerais également d'utiliser une sorte de file d'attente de message et de refactoriser le code. Il n'a donc pas besoin de la portée.

Peut-être que vous pourriez reconstruire le code sur une carte / réduire le modèle. Vous pouvez ensuite exécuter le code PHP dans Hadoop, vous pouvez regrouper le traitement par quelques machines.

Je ne sais pas si c'est utile, mais je suis tombé sur un autre projet, appelé Gearman . Il est également utilisé pour faire en grappes les processus PHP. Je suppose que vous pouvez également combiner cela avec un script de réduction, si Hadoop n'est pas comme si vous voulez aller.


2 commentaires

Je ne veux pas utiliser une implémentation Java de PHP, il semble un peu "gonflé".


J'ai testé Quercus, ce n'est pas si mauvais mais il n'est pas compatible à 100% avec le code existant. L'utilisation probablement en utilisant un cluster Hadoop est la solution la plus rapide.



10
votes

Si votre objectif est un temps minimal - la solution est simple à décrire, mais pas si simple à mettre en œuvre.

Vous devez trouver un modèle pour diviser le travail (vous ne fournissez pas beaucoup d'informations dans la question à cet égard).

Ensuite, utilisez un processus maître que Fourks enfants à faire le travail. En règle générale, le nombre total de processus que vous utilisez doit être compris entre N et 2n , où n est le nombre de noyaux de la machine.

En supposant que ces données seront stockées dans des fichiers que vous pourriez envisager d'utiliser l'IO non bloquante pour maximiser le débit. Ne faisant pas que la plupart de votre processus passeront du temps à attendre le disque. Php a stream_select () cela pourrait vous aider. Notez que l'utilisation de ce n'est pas triviale.

Si vous décidez de ne pas utiliser SELECT - L'augmentation du nombre de processus pourrait aider.


en ce qui concerne les fonctions PCNTL : J'ai écrit une DAAMON avec eux (une bonne avec le fourchette, la modification de la session ID, l'utilisateur en cours d'exécution, etc.) et c'est l'un des plus Morceau fiable de logiciel que j'ai écrit. Parce qu'il abeille des travailleurs pour chaque tâche, même s'il y a un bogue dans l'une des tâches, cela n'affecte pas les autres.


1 commentaires

Pour voir Stream_Select In Action Checkout, le code dans drupal.org/project/httprl . Je prévois de pousser cette bibliothèque à Github une fois que je l'obtiens plus polis; quelque chose qui peut être couru en dehors de Drupal. Vous pouvez l'utiliser comme exemple de la manière complexe Stream_Select.



3
votes

La question semble être un peu confuse.

Je veux réduire le temps d'exécution absolu.

Voulez-vous dire temps écoulé? L'utilisation certainement de la bonne structure de données améliorera le débit, mais pour une structure de données donnée, l'ordre minimum de l'algorithme est absolu et rien à voir avec la manière dont vous implémentez l'algorithme.

Quel modèle de conception existent pour réaliser ....?

Les motifs de conception sont quelque chose que le code est , pas un modèle de rédaction de programmes et d'outils utiles pour la conception du curriculum. Pour commencer avec un motif et rendre votre code, il est en soi un anti-motif.

Personne ne peut répondre à cette question avec vous en sachant beaucoup plus sur vos données et sa structure, mais le pilote de clé de l'efficacité sera la structure de données que vous utilisez pour implémenter votre arbre. Si le temps écoulé est important, il s'agit certainement d'une exécution parallèle, il peut également s'agir également d'envisager d'exécuter l'opération dans un outil différent - des bases de données sont très optimisées pour traiter avec de grands ensembles de données, mais notez que la méthode évidente de décrivant un arbre Une base de données relationnelle est très inefficace lorsqu'il s'agit d'isoler des sous-arbres et de marcher dans l'arbre.

En réponse à la suggestion d'Adam, vous avez répondu:

J'ai "entendu" que PCNTL n'est pas une bonne solution. Toutes expériences?

Où avez-vous entendu ça? Cercité d'un script invoqué CGI ou mod_PHP est une mauvaise idée, mais rien de mal à le faire de la ligne de commande. Avoir un Google pour les processus PHP à long terme (soyez averti qu'il y a beaucoup d'informations incorrectes). Quel code que vous écrivez variera en fonction du système d'exploitation sous-jacent - que vous n'avez pas indiqué.

Je soupçonne que vous pouvez résoudre une grande partie de vos problèmes de performance en identifiant quelles parties de l'arbre doivent être vérifiées et ne vérifiant que ces pièces et déclencher les chèques lorsque l'arborescence est mise à jour, ou au moins marquer les nœuds comme " sale '.

Vous pourriez trouver ces informations utiles:

http://mikehillyer.com/articles/maning-hierarchical- Data-in-MySQL / http://fr.wikipedia.org/wiki/Thikipedia.binary_tree

c.


0 commentaires

3
votes

Vous pouvez utiliser une structure de données plus efficace, telle qu'une BREEE. J'ai utilisé une fois en Java mais pas en PHP. Vous pouvez essayer ce script: http://www.phpclasses.org/browse/file/ 708.html , c'est une implémentation de BREEE.

Si ce n'est pas suffisant, vous pouvez utiliser Hadoop pour mettre en œuvre une carte de carte / réduire, comme l'a dit Michael. Je ne ferais pas le processus de PHP de Fork, il ne semble pas aider à la performance.

Personnellement, j'utiliserais PHP comme client et tout mettre dans Hadoop. Ce tutoriel peut aider: http: // www .lunchpauze.com / 2007/10 / Écriture-Hadoop-Mapreduce-Program-in-php.html .

Une autre solution peut être d'utiliser une implémentation Java de BTREE: http://jdbm.sourceforge.net/. JDBM est une base de données d'objet à l'aide d'une astruture de données BTREE +. Ensuite, vous pouvez rechercher avec PHP en exposant des données avec un service Web ou en y accédant directement avec Quercus


0 commentaires

0
votes

Pthreads

Il y a une extension PHP assez nouvelle (depuis 2012) disponible: Pthreads strong> . Il peut être installé via pecl . P>

implémentation simple en code PHP: Étendre de thread code> classe. Ajoutez un exécuté () code> méthode et exécutez la méthode Démarrer () code>. P> xxx pré>

sorties p>

>php pthreads.php
0.041301012039185
end
T 1: Sleeping 3sec
T 2: Sleeping 3sec
T 3: Sleeping 3sec
T 4: Sleeping 3sec
T 5: Sleeping 3sec
T 1: Hello World
T 2: Hello World
T 3: Hello World
T 4: Hello World
T 5: Hello World


0 commentaires