applicazione GridGain che è più lento di un'applicazione multithread su una macchina

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

  •  11-10-2019
  •  | 
  •  

Domanda

Ho implementato il mio prima applicazione GridGain e non sto ottenendo i miglioramenti delle prestazioni che mi aspettavo. Purtroppo è più lento. Vorrei un po 'di aiuto nel migliorare la mia implementazione in modo che possa essere più veloce.

Il succo della mia domanda è che sto facendo un'ottimizzazione forza bruta con milioni di possibili parametri che prendono una frazione di secondo per ogni valutazione della funzione. Ho implementato questo dividendo i milioni di iterazioni in alcuni gruppi, e ogni gruppo viene eseguito come un unico lavoro.

Il pezzo rilevante del codice è al di sotto. la funzione maxAppliedRange chiama la funzione foo per ogni valore nella gamma x, e ritorna il massimo, e il risultato diventa il massimo di tutti i massimi trovata da ogni posto di lavoro.

  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)
  }

Il mio codice può scegliere tra un'esecuzione multi-threaded su una macchina o utilizzare diversi nodi GridGain usando il codice di cui sopra. Quando eseguo la versione gridgain inizia fuori come che sta per essere più veloce, ma poi un paio di cose sempre accadere:

  • Uno dei nodi (su una macchina diversa) non trova un battito cardiaco, causando il nodo sul mio computer principale di rinunciare a quel nodo e per avviare l'esecuzione del lavoro una seconda volta.
  • Il nodo che ha mancato un battito cardiaco continua a fare lo stesso lavoro. Ora ho due nodi che fanno la stessa cosa.
  • Alla fine, tutti i lavori sono in corso di esecuzione sulla mia macchina principale, ma dal momento che alcuni dei lavori è iniziata più tardi, ci vuole più tempo per modo tutto alla fine.
  • A volte un'eccezione si butta da GridGain perché un nodo scaduta e l'intera operazione viene riuscita.
  • I annoiarsi.

Ho provato a configurarlo per avere molti posti di lavoro, quindi se uno fallito allora non sarebbe così grande di un affare, ma quando faccio questo io alla fine con molti posti di lavoro in corso di esecuzione su ogni nodo. Che mette un onere molto più grande su ogni macchina rendendo più probabile per un nodo a perdere un battito cardiaco, causando tutto per andare in discesa veloce. Se ho un lavoro per CPU, allora se uno processo non riesce, un altro nodo deve ricominciare dall'inizio. Ad ogni modo non posso vincere.

Quello che penso che funziona meglio è se ho potuto fare due cose:

  • Aumentare il timeout per i battiti cardiaci
  • farfallato ciascun nodo in modo che lo fa solo un processo alla volta.

Se potessi fare questo, ho potuto dividere il mio compito in molti posti di lavoro. Ogni nodo avrebbe fatto un lavoro alla volta e nessuna macchina sarebbe diventato sovraccaricato per indurlo a perdere un battito cardiaco. Se un lavoro non è riuscita quindi poco lavoro sarebbe perduto e il recupero sarebbe stata veloce.

Qualcuno può dirmi come fare questo? Cosa dovrei fare qui?

È stato utile?

Soluzione 2

Ora devo farlo funzionare correttamente. Nella mia situazione per la mia applicazione sto ottenendo circa uno speed-up del 50% nel corso di un applicazione multithread su una macchina, ma che non è il meglio che posso fare. Più lavoro deve essere fatto.

Per usare gridgain, sembra che il file di configurazione è fondamentale per ottenere tutto lavoro. Questo è dove il comportamento nodo è impostato e deve soddisfare le esigenze della vostra applicazione.

Una cosa che ho bisogno nel mio file di configurazione XML è questa:

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

Imposta i battiti massimi che possono essere perse prima che un nodo viene considerato mancante. Ho impostato ad un valore alto perché ho continuato a avere un problema di nodi di partire e tornare dopo pochi secondi. In alternativa, invece di usare il multicasting avrei potuto fissa gli indirizzi IP delle macchine con l'esecuzione di nodi utilizzando altre proprietà nel nel file di configurazione. Non ho fatto questo, ma se si sta utilizzando le stesse macchine più e più probabilmente sarebbe più affidabile.

L'altra cosa che ho fatto è:

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

Per il primo, il valore activeJobsThreshold dice al nodo di quanti posti di lavoro può funzionare allo stesso tempo. Questo è un modo migliore di fare strozzamento che cambiare il numero di thread nel servizio esecutore. Inoltre, lo fa un po 'il bilanciamento del carico e nodi di inattività può 'rubare' il lavoro da altri nodi di fare tutto più velocemente.

Ci sono modi migliori per fare questo anche. Gridgain può fare size i lavori sulla base della performance misurata di ogni nodo, a quanto pare, che migliorerebbe le prestazioni complessive, soprattutto se si dispone di computer lenti e veloci nella griglia.

Per il futuro ho intenzione di studiare il file di configurazione e si confronti con i javadoc per imparare tutto su tutte le diverse opzioni, per ottenere questo a correre ancora più veloce.

Altri suggerimenti

ho capito.

In primo luogo, v'è un file di configurazione XML che controlla i dettagli di come i nodi della griglia operano. Il file di configurazione di default è in GRIDGAIN_HOME / config / default-spring.xml. o modificare questo o potrei copiarlo e passare il nuovo file al ggstart.sh quando avvio il nodo di rete. Le due cose che avevo bisogno di aggiungere sono:

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

che imposta il timeout per i messaggi di rete a 25 secondi, e

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

I primi due argomenti del costruttore sono per 1 filo per iniziare e una dimensione massima di filo 1. I controlli di servizio esecutore ThreadPool che esegue i lavori gridgain. Il valore di default è 100, che è il motivo per cui la mia domanda era stato travolto ed i battiti cardiaci venivano scaduta.

L'altro cambiamento ho dovuto fare per il mio codice è:

  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)
  }

Perché senza la dichiarazione .Applicare inizia un nodo di rete con tutte le opzioni di default, non il file di configurazione con le modifiche di cui sopra, che è quello che voglio.

Ora funziona esattamente come ho bisogno di. Posso suddividere il compito in piccoli pezzi e anche il mio computer più deboli e più lento di poter dare un contributo a questo sforzo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top