GridGain aplicación que es más lenta que una aplicación multiproceso en una máquina

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

  •  11-10-2019
  •  | 
  •  

Pregunta

Me han puesto en práctica mi primera aplicación GridGain y no estoy recibiendo las mejoras de rendimiento que esperaba. Lamentablemente es más lento. Me gustaría un poco de ayuda en la mejora de mi aplicación para que pueda ser más rápido.

La esencia de mi solicitud es que estoy haciendo una optimización de la fuerza bruta con millones de posibles parámetros que tienen una fracción de segundo para cada evaluación de la función. He implementado este mediante la fragmentación de los millones de iteraciones en varios grupos, y cada grupo se ejecuta como un solo trabajo.

La pieza relevante de código es a continuación. la función maxAppliedRange llama a la función foo para cada valor en el intervalo x, y vuelve al máximo, y el resultado se convierte en el máximo de todos los valores máximos encontrados por cada puesto de trabajo.

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

Mi código puede elegir entre una ejecución multi-roscado en una máquina o utilizar varios nodos GridGain utilizando el código de seguridad. Cuando ejecuto la versión gridgain que comienza como que va a ser más rápido, pero luego algunas cosas siempre sucede:

  • Uno de los nodos (en una máquina diferente) no ve un latido del corazón, haciendo que el nodo en mi equipo principal para renunciar a ese nodo y que comience a ejecutar el trabajo por segunda vez.
  • El nodo que se perdió un latido del corazón sigue haciendo el mismo trabajo. Ahora tengo dos nodos que hacen lo mismo.
  • Con el tiempo, todos los trabajos se ejecutan en mi máquina principal, pero ya que algunos de los puestos de trabajo se inició más tarde, se tarda mucho más largo para todo, hasta el final.
  • A veces, una excepción es lanzada por GridGain porque un nodo de tiempo de espera y toda la tarea se falló.
  • Me molesta.

He intentado configurarlo para que tenga muchos puestos de trabajo por lo que si una falló entonces no sería tan grande de un acuerdo, pero cuando hago esto termino con muchos puestos de trabajo que se ejecutan en cada nodo. Que representa una carga mucho más grande en cada máquina por lo que es más probable que se pierda un nodo a un latido del corazón, haciendo que todo ir cuesta abajo rápido. Si tengo un empleo por cada CPU a continuación, si falla un trabajo, un nodo distinto tiene que empezar de nuevo desde el principio. De cualquier manera no puedo ganar.

Lo que creo que funcionaría mejor si yo podía hacer dos cosas:

  • Aumentar el tiempo de espera para los latidos del corazón
  • acelerador cada nodo para que sólo hace un trabajo a la vez.

Si pudiera hacer esto, yo podría dividir mi tarea en muchos puestos de trabajo. Cada nodo haría un trabajo a la vez y ninguna máquina que se convertiría en sobrecargado para hacer que se pierda un latido del corazón. Si un trabajo no poco trabajo a continuación, se perdería y la recuperación sería rápida.

Puede alguien decirme cómo hacer esto? ¿Qué debería estar haciendo aquí?

¿Fue útil?

Solución 2

Ahora tengo que funcione correctamente. En mi situación para mi aplicación que estoy recibiendo alrededor de un aceleramiento del 50% a través de una aplicación multiproceso en una máquina, pero eso no es lo mejor que puedo hacer. Más trabajo que hay que hacer.

Para usar gridgain, parece que el archivo de configuración es fundamental para conseguir que todo funcione. Aquí es donde el comportamiento de nodo se establece y debe coincidir con las necesidades de su aplicación.

Una cosa que se necesita en mi archivo de configuración XML es la siguiente:

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

Esto establece los latidos máximos que se pueden perder antes de considerar un nodo faltante. Me puse a un valor alto porque yo seguía teniendo un problema de nodos de salir y volver a los pocos segundos. Alternativamente, en lugar de utilizar la multidifusión que podría haber fijado las direcciones IP de las máquinas con el funcionamiento de los nodos utilizando otras propiedades en el en el archivo de configuración. No he hecho esto, pero si usted está usando las mismas máquinas y otra vez, probablemente sería más fiable.

La otra cosa que hice es:

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

En la primera, el valor activeJobsThreshold le dice al nodo de cuántos puestos de trabajo se puede ejecutar al mismo tiempo. Esta es una mejor forma de hacer estrangulación de cambiar el número de hilos en el servicio ejecutor. Además, se hace un poco de balanceo de carga y los nodos de inactividad puede 'robar' el trabajo de otros nodos para hacerlo todo más rápido.

Hay mejores maneras de hacer esto también. Gridgain puede hacer de tamaño de los puestos de trabajo basado en el rendimiento medido de cada nodo, al parecer, lo que mejoraría el rendimiento general, sobre todo si tiene equipos rápidos y lentos en la red.

En el futuro voy a estudiar el archivo de configuración y que para comparar los javadocs para aprender todo sobre todas las diferentes opciones, para conseguir esto para ejecutar aún más rápido.

Otros consejos

lo he descubierto.

En primer lugar, hay un archivo de configuración XML que controla los detalles de cómo operan los nodos de la red. El archivo de configuración por defecto está en GRIDGAIN_HOME / config / default-spring.xml. Podría ya sea Editar o copiarlo y aprobar el nuevo archivo a ggstart.sh cuando inicio el nudo de la red. Las dos cosas que tenía que añadir son:

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

que establece el tiempo de espera para los mensajes de red a 25 segundos, y

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

Los dos primeros argumentos del constructor son para 1 hilo para empezar y un diámetro de rosca máximo de 1. Los controles de servicio ejecutor ThreadPool que ejecuta los trabajos gridgain. El valor por defecto es 100, por lo que mi solicitud estaba siendo abrumado y los latidos del corazón estaban siendo tiempo de espera.

El otro cambio que tenía que hacer para que mi código es:

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

Porque sin la declaración .apply se inicia un nodo de la red con todas las opciones por defecto, no el archivo de configuración con las ediciones anteriores, que es lo que quiero.

Ahora funciona exactamente como lo necesito a. Puedo dividir la tarea en trozos pequeños e incluso mi equipo más débil y más lento puede hacer una contribución a este esfuerzo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top