2011-03-10 11 views
48

¿Alguien me puede señalar en un marco/API de reducción/API de código abierto para Java? No parece existir mucha evidencia de que exista tal cosa, pero alguien más puede saber diferente.Mapa de Java simple/marco de reducción

Lo mejor que puedo encontrar es, por supuesto, Hadoop MapReduce, pero eso no cumple los criterios "simples". No necesito la capacidad de ejecutar trabajos distribuidos, solo algo que me permita ejecutar trabajos de mapeo/reducción de estilo en una máquina de varios núcleos, en una sola JVM, utilizando concurrencia estándar de estilo Java5.

No es difícil escribir uno mismo, pero preferiría no tener que hacerlo.

+3

me encontré con este video que ANUNCIA sobre nueva característica en Java 8. parece que habrá API mapreduce en la nueva versión. http://www.youtube.com/watch?v=47_Em-zc7_Q – gigadot

+0

Tengo curiosidad por saber cuál es su solución actual para este problema. Solo estoy buscando formas rápidas y fáciles de hacer Lists.transform (función) en paralelo en una sola máquina. – Snekse

+6

LeoTask funciona. Es una ejecución paralela de tareas y un marco de agregación de resultados en una máquina multinúcleo. https://github.com/mleoking/leotask –

Respuesta

10

Creo que vale la pena mencionar que estos problemas son historia como de Java 8. Un ejemplo:

int heaviestBlueBlock = 
    blocks.filter(b -> b.getColor() == BLUE) 
      .map(Block::getWeight) 
      .reduce(0, Integer::max); 

en otras palabras: de un solo nodo MapReduce está disponible en Java 8.

Para más detalles, ver Brian Goetz's presentation about project lambda

+0

Suponiendo que lo haga, sí. La historia nos dice que lo interesante generalmente es expulsado. – skaffman

+4

@skaffman: ¡¡Lloraré si lambda finalmente no lo logra !! –

+1

Estoy (muy tarde) aceptando esta respuesta, ya que cualquier otra opción se volverá rápidamente anacrónica a medida que Java8 gane en adopción. – skaffman

9

utilizo la siguiente estructura

int procs = Runtime.getRuntime().availableProcessors(); 
ExecutorService es = Executors.newFixedThreadPool(procs); 

List<Future<TaskResult>> results = new ArrayList(); 
for(int i=0;i<tasks;i++) 
    results.add(es.submit(new Task(i))); 
for(Future<TaskResult> future:results) 
    reduce(future); 
+6

Umm ... eso no es map-reduce, es solo un ejecutor desnudo. – skaffman

+0

Usted quería simple. El bucle asigna el trabajo a tareas de 'tareas' y se puede usar para combinar o reducir los resultados individuales. Opcionalmente, los resultados se pueden almacenar en un futuro. –

+0

Me doy cuenta de que * puedo * escribir mi propio mapa/reducir el marco, pero no * quiero * hacerlo. Es lo suficientemente complejo como para querer usar una solución genérica estándar. – skaffman

6

creé una sola vez para mí hace un par de años cuando llegué a una máquina de 8 núcleos, pero no estaba terriblemente feliz con él. Nunca conseguí que fuera tan simple de usar como esperaba, y las tareas que requerían mucha memoria no se escalaron bien.

Si usted no recibe ningún reales respuestas que puedo compartir más, pero el núcleo de la misma es:

public class LocalMapReduce<TMapInput, TMapOutput, TOutput> { 
    private int m_threads; 
    private Mapper<TMapInput, TMapOutput> m_mapper; 
    private Reducer<TMapOutput, TOutput> m_reducer; 
    ... 
    public TOutput mapReduce(Iterator<TMapInput> inputIterator) { 
     ExecutorService pool = Executors.newFixedThreadPool(m_threads); 
     Set<Future<TMapOutput>> futureSet = new HashSet<Future<TMapOutput>>(); 
     while (inputIterator.hasNext()) { 
      TMapInput m = inputIterator.next(); 
      Future<TMapOutput> f = pool.submit(m_mapper.makeWorker(m)); 
      futureSet.add(f); 
      Thread.sleep(10); 
     } 
     while (!futureSet.isEmpty()) { 
      Thread.sleep(5); 
      for (Iterator<Future<TMapOutput>> fit = futureSet.iterator(); fit.hasNext();) { 
       Future<TMapOutput> f = fit.next(); 
       if (f.isDone()) { 
        fit.remove(); 
        TMapOutput x = f.get(); 
        m_reducer.reduce(x); 
       } 
      } 
     } 
     return m_reducer.getResult(); 
    } 
} 

EDIT: Basado en un comentario, a continuación es una versión sin sleep. El truco es usar CompletionService que esencialmente proporciona una cola de bloqueo de Future s completa.

public class LocalMapReduce<TMapInput, TMapOutput, TOutput> { 
    private int m_threads; 
    private Mapper<TMapInput, TMapOutput> m_mapper; 
    private Reducer<TMapOutput, TOutput> m_reducer; 
    ... 
    public TOutput mapReduce(Collection<TMapInput> input) { 
     ExecutorService pool = Executors.newFixedThreadPool(m_threads); 
     CompletionService<TMapOutput> futurePool = 
        new ExecutorCompletionService<TMapOutput>(pool); 
     Set<Future<TMapOutput>> futureSet = new HashSet<Future<TMapOutput>>(); 
     for (TMapInput m : input) { 
      futureSet.add(futurePool.submit(m_mapper.makeWorker(m))); 
     } 
     pool.shutdown(); 
     int n = futureSet.size(); 
     for (int i = 0; i < n; i++) { 
      m_reducer.reduce(futurePool.take().get()); 
     } 
     return m_reducer.getResult(); 
    } 

También habrá dado cuenta de que esto es un mapa a reducir el algoritmo muy destilada, incluyendo un solo reducir trabajador que realiza tanto la operación de reducir y fusionar.

+0

Hay una falta de valores de reducción de clasificación por clave, por lo que la parte de reducción no se paraleliza como se hace en Hadoop. – yura

+0

@yura: De hecho. Este es el tipo de sutileza refinada de la que no quiero preocuparme. – skaffman

+0

Thread.sleep is bad :) –

8

que se dan cuenta de que esto podría ser un poco después de los hechos, pero es posible que desee echar un vistazo a las clases de JSR166y ForkJoin JDK7.

Hay una biblioteca back ported que funciona bajo JDK6 sin ningún problema, por lo que no tiene que esperar hasta el próximo milenio para probarlo. Se ubica en algún lugar entre un ejecutor sin formato y hadoop que proporciona un marco para trabajar en el trabajo de reducción de mapa dentro de la JVM actual.

3

¿Has echado un vistazo a GridGain?

+0

GridGain es muy bueno, tal vez el mejor, pero muy caro y no admiten más la edición de la comunidad. Incluso los archivos de la edición de comunidad 3.6 no están disponibles para su descarga. No recomiendo la ganancia de red para propósitos simples. Solo si tienes un proyecto grande y una muy grande. Por esta razón, recomendaría Akka. – felipe

+0

Re-opensourced en marzo de 2014. – CheatEx

18

¿Has echado un vistazo Akka? Si bien Akka es realmente un marco de simultaneidad basado en el modelo Actor distribuido, puedes implementar muchas cosas simplemente con poco código. Es tan fácil dividir el trabajo en pedazos con él, y automáticamente aprovecha al máximo una máquina de múltiples núcleos, además de poder utilizar múltiples máquinas para procesar el trabajo. A diferencia del uso de hilos, se siente más natural para mí.

Tengo un Java map reduce example usando akka. No es el ejemplo de reducción de mapa más fácil, ya que hace uso de futuros; pero debería darte una idea aproximada de lo que está involucrado. Hay varias cosas importantes que mi mapa reduce el ejemplo demuestra:

  • Cómo dividir el trabajo.
  • Cómo asignar el trabajo: akka tiene un sistema de mensajería realmente simple, así como un partidista de trabajo, cuya agenda puede configurar. Una vez que aprendí a usarlo, no pude parar. Es tan simple y flexible. Estaba usando los cuatro núcleos de mi CPU en poco tiempo. Esto es realmente genial para implementar servicios.
  • Cómo saber cuándo se realiza el trabajo y el resultado está listo para procesar: Esta es la parte que puede ser la más difícil y confusa de entender a menos que ya esté familiarizado con Futures. No necesita usar futuros, ya que hay otras opciones. Los usé porque quería algo más corto para que la gente asimilara.

Si tiene alguna pregunta, StackOverflow en realidad tiene una excelente sección de control de calidad de AKAKA.

5

Me gusta usar Skandium para el paralelismo en Java. El marco implementa ciertos patrones de paralelismo (concretamente Master-Slave, Map/Reduce, Pipe, Fork y Divide & Conquer) para máquinas multi-core con memoria compartida. Esta técnica se llama "esqueletos algorítmicos". Los patrones se pueden anidar.

En detalle hay esqueletos y músculos. Los músculos hacen el trabajo real (dividir, fusionar, ejecutar y condicionar). Los esqueletos representan los patrones de paralelismo, excepto "While", "For" y "If", que pueden ser útiles al anidar patrones.

Se pueden encontrar ejemplos dentro del marco. Necesité un poco para entender cómo usar los músculos y los esqueletos, pero después de superar este obstáculo me gusta mucho este marco. :)

+0

Esto no parece ser desarrollado activamente. –

+0

Triste, pero cierto.Quería visitar su sitio web hace unos días y parece que lo han sacado a principios de este año. Entonces, si nadie se siente obligado a mantener el paquete por sí mismo (es de código abierto), no habrá actualizaciones. Tal vez busque alternativas la próxima vez, pero estoy muy contento con eso. –

3

Es posible que desee echar un vistazo a la página web del proyecto de funcionales 4 Java: http://f4j.rethab.ch/ Se introduce el filtro, el mapa y se reducen a las versiones de Java antes 8.

0

API A MapReduce se introdujo en v3.2 de Hazelcast (ver la MapReduce API section in the docs). Si bien Hazelcast está destinado a ser utilizado en un sistema distribuido, funciona perfectamente en una configuración de nodo único, y es bastante liviano.

0

Usted puede intentar LeoTask: una ejecución de tareas en paralelo y los resultados marco de la agregación

Es gratuito y de código abierto: https://github.com/mleoking/leotask

que aquí hay una breve introducción mostrando su API: https://github.com/mleoking/leotask/blob/master/leotask/introduction.pdf?raw=true

Es un marco ligero que trabaja en una sola computadora usando todos sus núcleos de CPU disponibles.

Tiene las siguientes características:

  • & parámetro paralelo exploración espacial
  • Flexible &
  • modelo
  • Programación centrarse únicamente en la lógica clave
  • fiable & interrupción automática automático basado en configuración agregación resultado recuperación

y Utilidades:

  • dinámicos & redes estructuras Cloneable.
  • Integración con Gnuplot
  • generación de red de acuerdo con los modelos de red comunes
  • DelimitedReader: un lector sofisticado que explora CSV (valores separados por comas) archivos como una base de datos
  • generador de números aleatorios Fast basado en el algoritmo Mersenne Twister
  • un sistema integrado CurveFitter del proyecto ImageJ
+0

Esto es un anuncio. –