Migra desde MapReduce para App Engine hacia Apache Beam y Dataflow

Este instructivo está dirigido a los usuarios de MapReduce para App Engine. En él se muestra cómo migrar desde MapReduce para App Engine hacia Apache Beam y Dataflow.

¿Por qué migrar?

MapReduce para App Engine es un modelo de programación que permite procesar grandes cantidades de datos de forma paralela y distribuida. Es útil para tareas grandes y de larga duración que no se pueden manejar dentro del alcance de una sola solicitud, como las siguientes:

  • Analizar registros de aplicaciones
  • Agregar datos relacionados de fuentes externas
  • Transformar datos de un formato a otro
  • Exportar datos para análisis externo

Sin embargo, App Engine MapReduce es una biblioteca de código abierto que mantiene la comunidad basada en los servicios de App Engine y ya no es compatible con Google.

Por otro lado, Dataflow es compatible por completo con Google y proporciona más funciones en comparación con MapReduce para App Engine.

Casos de migración

A continuación, se incluyen algunos ejemplos de casos en los que podrías beneficiarte de la migración desde MapReduce para App Engine hacia Apache Beam y Dataflow:

  • Almacena los datos de tu aplicación de base de datos de Datastore en un almacén de datos de BigQuery para el procesamiento analítico mediante SQL.
  • Usa Dataflow como alternativa a MapReduce para App Engine a fin de llevar a cabo el mantenimiento o las actualizaciones de tu conjunto de datos de Datastore.
  • Crea una copia de seguridad de partes de tu base de datos de Datastore en Cloud Storage.

¿Qué son Dataflow y Apache Beam?

Dataflow es un servicio administrado que ejecuta una amplia variedad de patrones de procesamiento de datos. Apache Beam es un modelo de programación unificado que proporciona SDK para definir flujos de trabajo de procesamiento de datos. Usa Apache Beam a fin de crear canalizaciones complejas por lotes y de transmisión, y ejecútalas en Dataflow.

Comienza a usar Dataflow y Apache Beam

Para comenzar, elige una de las siguientes guías de inicio rápido:

Crea y ejecuta una canalización

Cuando uses MapReduce para App Engine, crea clases de procesamiento de datos y agrega la biblioteca de MapReduce. Luego, una vez que se hayan definido las especificaciones y la configuración del trabajo, crea y, también, inicia el trabajo en un solo paso mediante el método estático start() en la clase de trabajo adecuada.

En el caso de los trabajos de Map, crea las clases Input y Output, y la clase Map, que realiza la asignación. En los trabajos de MapReduce para App Engine, crea las clases Input y Output, además de define las clases Mapper y Reducer a fin de llevar a cabo las transformaciones de datos.

Con Apache Beam, el proceso es un poco distinto, ya que debes crear una canalización. Debes usar conectores de entrada y salida para leer y escribir en tus receptores y fuentes de datos. Usa transformaciones de datos predefinidas (o escríbelas tú mismo) para implementar las transformaciones de datos. Luego, una vez que tu código esté listo, implementa la canalización en el servicio de Dataflow.

Convierte trabajos de MapReduce para App Engine en canalizaciones de Apache Beam

En la tabla siguiente, se muestran los equivalentes en Apache Beam de los pasos de asignación, distribución y reducción del modelo de MapReduce para App Engine.

Java

MapReduce para App Engine Equivalente en Apache Beam
Map MapElements<InputT,OutputT>
Shuffle GroupByKey<K,V>
Reduce Combine.GroupedValues<K,InputT,OutputT>

Una práctica común es usar Combine.PerKey<K,InputT,OutputT> en lugar de GroupByKey y CombineValues.

Python

MapReduce para App Engine Equivalente en Apache Beam
Map beam.Map
Shuffle beam.GroupByKey
Reduce beam.CombineValues

Una práctica común es usar beam.CombinePerKey en lugar de beam.GroupByKey y beam.CombineValues.

Go

MapReduce para App Engine Equivalente en Apache Beam
Map beam.ParDo
Shuffle beam.GroupByKey
Reduce beam.Combine


En el siguiente código de muestra, se muestra cómo implementar el modelo de MapReduce para App Engine en Apache Beam:

Java

Tomado de MinimalWordCount.java:
p.apply(TextIO.read().from("gs://apache-beam-samples/shakespeare/*"))

 // Apply a ParDo that returns a PCollection, where each element is an
 // individual word in Shakespeare's texts.
 .apply("ExtractWords", ParDo.of(new DoFn() {
                   @ProcessElement
                   public void processElement(ProcessContext c) {
                     for (String word : c.element().split(ExampleUtils.TOKENIZER_PATTERN)) {
                       if (!word.isEmpty()) {
                         c.output(word);
                       }
                     }
                   }
                 }))

 // Apply the Count transform that returns a new PCollection of key/value pairs,
 // where each key represents a unique word in the text.
 .apply(Count.perElement())

 // Apply a MapElements transform that formats our PCollection of word counts
 // into a printable string, suitable for writing to an output file.
 .apply("FormatResults", MapElements.via(new SimpleFunction, String>() {
                   @Override
                   public String apply(KV input) {
                     return input.getKey() + ": " + input.getValue();
                   }
                 }))

 // Apply a write transform that writes the contents of the PCollection to a
 // series of text files.
 .apply(TextIO.write().to("wordcounts"));

Python

Tomado de wordcount_minimal.py:
# Read the text file[pattern] into a PCollection.
lines = p | ReadFromText(known_args.input)

# Count the occurrences of each word.
counts = (
    lines
    | 'Split' >> (beam.FlatMap(lambda x: re.findall(r'[A-Za-z\']+', x))
                  .with_output_types(unicode))
    | 'PairWithOne' >> beam.Map(lambda x: (x, 1))
    | 'GroupAndSum' >> beam.CombinePerKey(sum))

# Format the counts into a PCollection of strings.
output = counts | 'Format' >> beam.Map(lambda (w, c): '%s: %s' % (w, c))

# Write the output using a "Write" transform that has side effects.
# pylint: disable=expression-not-assigned
output | WriteToText(known_args.output)

Go

Tomado de minimal_wordcount.go:
// beam.Init() is an initialization hook that must be called on startup.
beam.Init()

// Create the Pipeline object and root scope.
p := beam.NewPipeline()
s := p.Root()
lines := textio.Read(s, "gs://apache-beam-samples/shakespeare/kinglear.txt")

// Invoke a ParDo transform on our PCollection of text lines.
// This ParDo invokes a DoFn (defined in-line) on each element that
// tokenizes the text line into individual words. The ParDo returns a
// PCollection of type string, where each element is an individual word in
// Shakespeare's collected texts.
words := beam.ParDo(s, func(line string, emit func(string)) {
    for _, word := range wordRE.FindAllString(line, -1) {
        emit(word)
    }
}, lines)

// Invoke the stats.Count transform on our PCollection of
// individual words. The Count transform returns a new PCollection of
// key/value pairs, where each key represents a unique word in the text.
// The associated value is the occurrence count for that word.
counted := stats.Count(s, words)

// Use a ParDo to format our PCollection of word counts into a printable
// string, suitable for writing to an output file. When each element
// produces exactly one element, the DoFn can simply return it.
formatted := beam.ParDo(s, func(w string, c int) string {
    return fmt.Sprintf("%s: %v", w, c)
}, counted)

// Invoke textio.Write at the end of the pipeline to write
// the contents of a PCollection (in this case, our PCollection of
// formatted strings) to a text file.
textio.Write(s, "wordcounts.txt", formatted)

Beneficios adicionales de Apache Beam y Dataflow

Si decides migrar tus trabajos de MapReduce para App Engine a las canalizaciones de Apache Beam, te beneficiarás con varias funciones que ofrecen Apache Beam y Dataflow.

Programa trabajos de Cloud Dataflow

Si estás familiarizado con las listas de tareas en cola de App Engine, puedes programar tus trabajos recurrentes mediante Cron. En este ejemplo, se muestra cómo usar Cron de App Engine para programar las canalizaciones de Apache Beam.

Hay varias formas adicionales de programar la ejecución de tu canalización. Puede hacer lo siguiente:

Supervisa los trabajos de Cloud Dataflow

A fin de supervisar tus trabajos de MapReduce para App Engine, dependes de una URL alojada en appspot.com.

Cuando ejecutas las canalizaciones mediante el servicio administrado de Dataflow, puedes supervisarlas mediante la interfaz de usuario de la supervisión basada en la web de Dataflow. También puedes usar Cloud Monitoring para obtener información adicional acerca de las canalizaciones.

Lee y escribe

En Apache Beam, los lectores y escritores de MapReduce para App Engine se denominan fuentes y receptores de datos, o conectores de E/S.

Apache Beam tiene muchos conectores de E/S para varios servicios de Google Cloud, como Bigtable, BigQuery, Datastore, Cloud SQL y otros. También hay conectores de E/S que crean los colaboradores de Apache Beam para servicios que no son de Google, como Apache Cassandra y MongoDB.

Pasos siguientes