l'application GridGain qui est plus lente qu'une application multithread sur une machine

StackOverflow https://stackoverflow.com/questions/4481645

  •  11-10-2019
  •  | 
  •  

Question

J'ai mis en œuvre ma première application GridGain et je ne reçois pas les améliorations de performance que j'attendais. Malheureusement, il est plus lent. Je voudrais un peu d'aide à l'amélioration de ma mise en œuvre de sorte qu'il peut être plus rapide.

L'essentiel de ma demande est que je fais une optimisation de la force brute avec des millions de paramètres possibles qui prennent une fraction de seconde pour chaque évaluation de la fonction. Je l'ai mis en œuvre ce en divisant les millions d'itérations dans quelques groupes, et chaque groupe est exécuté comme un emploi.

La pièce correspondante du code est ci-dessous. la fonction maxAppliedRange appelle la fonction foo pour chaque valeur comprise entre x et retourne au maximum, et le résultat devient le maximum de toutes les valeurs maximales par chaque emploi trouvé.

  scalar {
    result = grid !*~
      (for (x <- (1 to threads).map(i => ((i - 1) * iterations / threads, i * iterations / threads)))
        yield () => maxAppliedRange(x, foo), (s: Seq[(Double, Long)]) => s.max)
  }

Mon code peut choisir entre une exécution multi-filetée sur une machine ou d'utiliser plusieurs noeuds de GridGain en utilisant le code ci-dessus. Quand je lance la version GridGain il commence comme ça va être plus rapide, mais quelques choses arrivent toujours:

  • L'un des nœuds (sur une autre machine) manque un battement de coeur, ce qui provoque le nœud sur mon ordinateur principal de renoncer à ce nœud et de commencer à exécuter le travail une deuxième fois.
  • Le nœud qui a manqué un battement de coeur continue de faire le même travail. Maintenant, j'ai deux noeuds qui font la même chose.
  • Finalement, tous les travaux sont en cours d'exécution sur ma machine principale, mais depuis quelques-uns des emplois ont commencé plus tard, il prend beaucoup plus de temps pour tout à la fin.
  • Parfois, une exception est jeté par GridGain parce qu'un noeud a expiré et toute tâche s'échoué.
  • Je vous fâchez.

J'ai essayé de le mettre en place pour avoir beaucoup d'emplois donc si on a échoué alors il ne serait pas aussi grand d'un accord, mais quand je fais cela, je finir avec beaucoup d'emplois en cours d'exécution sur chaque nœud. Cela met un fardeau beaucoup plus sur chaque machine qui rend plus probable un nœud à manquer un battement de coeur, ce qui provoque tout pour aller plus vite en descente. Si j'ai un emploi par processeur alors si un travail échoue, un autre nœud doit recommencer depuis le début. De toute façon, je ne peux pas gagner.

Ce que je pense qui fonctionnerait le mieux est de savoir si je pouvais faire deux choses:

  • Augmentez le délai d'attente pour les battements de coeur
  • Throttle chaque noeud de sorte qu'il ne fait qu'une seule tâche à la fois.

Si je pouvais le faire, je pouvais diviser ma tâche en beaucoup d'emplois. Chaque nœud ferait un emploi à la fois et aucune machine ne sont surchargées pour l'amener à manquer un battement de coeur. Si un travail a échoué alors peu de travail serait perdu et la récupération serait rapide.

Quelqu'un peut-il me dire comment faire? Que dois-je faire ici?

Était-ce utile?

La solution 2

Je l'ai fonctionne correctement. Dans ma situation pour ma demande que je reçois sur une application multithread vitesse jusqu'à 50% sur une sur une machine, mais ce n'est pas le meilleur que je peux faire. Plus le travail est à faire.

Pour utiliser GridGain, il semble que le fichier de configuration est essentielle pour obtenir le travail du tout. Ce comportement est là du nœud est défini et doit correspondre aux besoins de votre application.

Une I chose nécessaire dans mon fichier de configuration XML est le suivant:

    <property name="discoverySpi">
        <bean class="org.gridgain.grid.spi.discovery.multicast.GridMulticastDiscoverySpi">
            <property name="maxMissedHeartbeats" value="20"/>
            <property name="leaveAttempts" value="10"/>
        </bean>
    </property>

Ceci définit les battements de coeur maximum qui peut être un nœud avant manqué est considéré comme manquant. Je donne la valeur à une valeur élevée parce que je continuais d'avoir un problème de nœuds et laissant revenir quelques secondes plus tard. Sinon, au lieu d'utiliser I multicasting aurait pu régler les adresses IP des machines avec des noeuds en cours d'exécution en utilisant d'autres propriétés dans le dans le fichier de configuration. Je ne le fais pas, mais si vous utilisez les mêmes machines encore et il serait probablement plus fiable.

L'autre chose que je l'ai fait est:

    <property name="collisionSpi">
        <bean class="org.gridgain.grid.spi.collision.jobstealing.GridJobStealingCollisionSpi">
            <property name="activeJobsThreshold" value="2"/>
            <property name="waitJobsThreshold" value="4"/>
            <property name="maximumStealingAttempts" value="10"/>
            <property name="stealingEnabled" value="true"/>
            <property name="messageExpireTime" value="1000"/>
        </bean>
    </property>

    <property name="failoverSpi">
        <bean class="org.gridgain.grid.spi.failover.jobstealing.GridJobStealingFailoverSpi">
            <property name="maximumFailoverAttempts" value="10"/>
        </bean>
    </property>

Pour la première, la valeur activeJobsThreshold indique au nœud combien d'emplois il peut fonctionner en même temps. Ceci est une meilleure façon de faire que de changer le étranglement nombre de threads au service de l'exécuteur. En outre, il fait un peu d'équilibrage de charge et les nœuds inactifs peut travailler « voler » d'autres nœuds pour tout faire plus rapidement.

Il y a de meilleures façons de le faire aussi. GridGain peut faire la taille des emplois en fonction de la performance mesurée de chaque noeud, apparemment, ce qui améliorerait les performances globales, surtout si vous avez des ordinateurs rapides et lents dans la grille.

Pour l'avenir, je vais étudier le fichier de configuration et les comparer aux javadocs pour tout savoir sur toutes les différentes options, pour obtenir ce à courir encore plus vite.

Autres conseils

Je compris.

Tout d'abord, il y a un fichier de configuration XML qui contrôle les détails de la façon dont les nœuds du réseau fonctionnent. Le fichier de configuration par défaut est GRIDGAIN_HOME / config / default-spring.xml. Je pouvais soit modifier ceci ou copier et transmettre le nouveau fichier à ggstart.sh quand je commence le nœud de grille. Les deux choses que je devais ajouter sont:

    <property name="networkTimeout" value="25000"/>

qui définit le délai d'attente pour les messages du réseau à 25 secondes, et

   <property name="executorService">
        <bean class="org.gridgain.grid.thread.GridThreadPoolExecutor">
            <constructor-arg type="int" value="1"/>
            <constructor-arg type="int" value="1"/>
            <constructor-arg type="long">
                <util:constant static-field="java.lang.Long.MAX_VALUE"/>
            </constructor-arg>
            <constructor-arg type="java.util.concurrent.BlockingQueue">
                <bean class="java.util.concurrent.LinkedBlockingQueue"/>
            </constructor-arg>
        </bean>
    </property>

Les deux premiers arguments du constructeur sont pour 1 fil pour démarrer et un pas de vis max 1. Les commandes de service exécuteurs de la ThreadPool qui exécute les travaux d'GridGain. La valeur par défaut est de 100, ce qui est la raison pour laquelle ma demande était submergé et les battements de coeur étaient en cours a expiré.

L'autre changement que je devais faire à mon code est:

  scalar.apply("/path/to/gridgain home/config/custom-spring.xml") {
    result = grid !*~
      (for (x <- (1 to threads).map(i => ((i - 1) * iterations / threads, i * iterations / threads)))
        yield () => maxAppliedRange(x, kalmanBruteForceObj.performKalmanIteration), (s: Seq[(Double, Long)]) => s.max)
  }

Parce que sans la déclaration .Appliquer il commence un nœud de grille avec toutes les options par défaut, pas le fichier de configuration avec les modifications ci-dessus, ce qui est ce que je veux.

Maintenant, il fonctionne exactement comme je l'ai besoin pour. Je peux diviser la tâche en petits morceaux et même mon plus faible et le plus lent ordinateur peut apporter une contribution à cet effort.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top