python apache-spark pyspark rdd reduce

python - Spark groupByKey alternativa



apache-spark pyspark (1)

groupByKey está bien para el caso en el que queremos una colección "pequeña" de valores por clave, como en la pregunta.

TL; DR

La advertencia de "no usar" en groupByKey aplica a dos casos generales:

1) Desea agregar sobre los valores:

  • NO HACER : rdd.groupByKey().mapValues(_.sum)
  • DO : rdd.reduceByKey(_ + _)

En este caso, groupByKey desperdiciará recursos para materializar una colección, mientras que lo que queremos es un solo elemento como respuesta.

2) Desea agrupar colecciones muy grandes sobre claves de baja cardinalidad:

  • NO HAGA : allFacebookUsersRDD.map(user => (user.likesCats, user)).groupByKey()
  • SOLO NO

En este caso, groupByKey potencialmente generará un error OOM.

groupByKey materializa una colección con todos los valores para la misma clave en un ejecutor. Como se mencionó, tiene limitaciones de memoria y, por lo tanto, otras opciones son mejores según el caso.

Todas las funciones de agrupación, como groupByKey , aggregateByKey y reduceByKey basan en la base: combineByKey y, por lo tanto, ninguna otra alternativa será mejor para el caso de uso en la pregunta, todas se basan en el mismo proceso común.

De acuerdo con las mejores prácticas de groupByKey debe evitar Spark groupByKey procesamiento de Spark groupByKey funciona de manera que la información se groupByKey primero entre los trabajadores y luego se producirá el procesamiento. Explanation

Entonces, mi pregunta es, ¿cuáles son las alternativas para groupByKey de manera que devuelva lo siguiente de manera distribuida y rápida?

// want this {"key1": "1", "key1": "2", "key1": "3", "key2": "55", "key2": "66"} // to become this {"key1": ["1","2","3"], "key2": ["55","66"]}

Me parece que quizás glom o glom podrían hacerlo primero en la partición ( map ) y luego unir todas las listas ( reduce ).