spark 1. Guía de programación

Resumen

Primero, cada aplicación de chispa tiene un controlador para ejecutar la función principal y operaciones paralelas en cada nodo.
Spark proporciona un conjunto de datos RDD (Conjunto de datos distribuidos resilientes), que se puede operar en paralelo a través de diferentes nodos y se puede construir a través de archivos hdfs. RDD puede almacenarse en la memoria caché y será más eficiente cuando sea necesario reutilizarlo.

En segundo lugar, se proporcionan variables compartidas (varibales compartidas) para su uso en operaciones paralelas en diferentes nodos. Una son las variables de difusión y la otra son los acumuladores. Puede usar estas dos herramientas cuando una variable necesita compartirse nuevamente en diferentes tareas de nodo o cuando la tarea de nodo y el controlador ven los requisitos para compartir variables.

Conectar chispa

from pyspark import SparkContext, SparkConf
  • SparkContext: una interfaz utilizada para conectar nodos de clúster
  • SparkConf:
  1. Configuración de la aplicación de chispa, establezca varios parámetros de chispa como pares clave-valor. Cuando se inicia el programa, leerá automáticamente varios parámetros de configuración del sistema.Si SparkConf está configurado, SparkConf tendrá prioridad.
  2. La configuración SparkConf(false)se puede evitar en la configuración del sistema externo, que está completamente sujeta a SparkConf.
  3. Todos los ajustes de configuración admiten el encadenamiento, como:

SparkConf().setMaster(“local”).setAppName(“My app”)

Inicializar chispa

from pyspark import SparkContext, SparkConf

conf = SparkConf().setAppName('programm_guide')
sc = SparkContext(conf=conf)
print ('the sc is: {}'.format(sc))

Usar concha

Agregue el directorio de la papelera a las variables de entorno y ejecútelo directamente

pyspark

RDD

Colecciones Paralelas

data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)

Use la interfaz sc.parallelize para crear un RDD desde un iterador o colección. Los datos en el iterador o la colección se copiarán y crearán como un conjunto de datos distribuido flexible que se puede calcular en paralelo, o RDD.

Por lo general, los datos RDD se dividirán, puede especificar parámetros para especificar en cuántas particiones se dividen los datos. Por ejemplo:

sc.parallelize(data, 10))

Conjunto de datos externo

distFile = sc.textFile("data.txt")

Spark admite la lectura de datos para crear RDD de las siguientes maneras:

  1. HDFS
  2. Cassandra
  3. HBase
  4. Amazon S3
  5. local

Spark admite la lectura directa de archivos de texto, SequenceFiles y otros formatos de entrada hadoop.

Tenga en cuenta los siguientes puntos cuando utilice spark para leer archivos:

  1. Si la ruta de lectura es una ruta local, debe asegurarse de que la misma ruta en el nodo debe existir y ser accesible.
  2. Todas las operaciones de archivos de lectura de chispa, como sc.textFile, todas las carpetas de soporte, archivos comprimidos y nombres de archivos comodín. Por ejemplo:
rdd = sc.textFile("/my/directory")
rdd = sc.textFile("/my/directory/*.txt")
rdd = sc.textFile("/my/directory/*.gz")

Otros:

  1. SparkContext.wholeTextFiles
    Admite la lectura de muchos archivos pequeños de una carpeta y devuelve RDD según pares (nombre de archivo, contenido). En contraste, el método de sc.textFile lee la carpeta y devuelve un RDD, y cada línea de cada archivo es un registro RDD. .
  2. RDD.saveAsPickleFileY SparkContext.pickleFile
    para la secuencia de RDD en un objeto de formato de pitón.
  3. Guardar y cargar SequenceFiles
rdd = sc.parallelize(range(1, 4)).map(lambda x: (x, "a" * x))
rdd.saveAsSequenceFile("path/to/file")
sorted(sc.sequenceFile("path/to/file").collect())
  1. Guarde y cargue datos de otros formatos de entrada y salida de hadoop: ...

Operación RDD

RDD admite dos tipos de operaciones:

1. transformaciones

Todas las transformaciones se realizan perezosamente, como el mapa. En pocas palabras, todas las transformaciones no se ejecutan de inmediato. El programa sabe qué transformaciones ha realizado en los datos y el orden de ejecución correspondiente. Solo cuando encuentre una acción calculará y devolverá el resultado a Conductores El diseño implementado por lazy puede hacer que el programa spark funcione más eficientemente.

El RDD después de cada transformación puede ser almacenado en caché y reutilizado por rdd.persist () o rdd.cache ().

2. Las acciones son lo
opuesto a la transformación y se ejecutan de inmediato.

Fundacion

lines = sc.textFile("data.txt")
lineLengths = lines.map(lambda s: len(s))
lineLengths.persist()

totalLength = lineLengths.reduce(lambda a, b: a + b)

Leer datos, maop y persistir, reducir la operación.

Pase la función a chispa

Tres formas:

  • expresión lambda
rdd.map(lambda s: len(s))
  • función definida def
def myFunc(s):
    words = s.split(" ")
    return len(words)

sc = SparkContext(...)
sc.textFile("file.txt").map(myFunc)

Dado que el nodo que accede a las propiedades de un objeto externo conducirá a hacer referencia a todo el objeto, es mejor operar copiando una variable local dentro de la función.

class MyClass(object):
    def __init__(self):
        self.field = "Hello"
    def doStuff(self, rdd):
        field = self.field
        return rdd.map(lambda s: field + s)
  • Algunas funciones avanzadas del módulo encapsuladas por la propia chispa

Comprender los cierres

Una de las dificultades para comprender la chispa es comprender con precisión el alcance y el ciclo de vida de las variables y los métodos cuando se ejecuta código entre nodos. Las operaciones RDD que modifican variables fuera de rango pueden causar confusión. Echemos foreach()un vistazo al caso que se pasa a continuación .

Caso

counter = 0
rdd = sc.parallelize(data)

# Wrong: Don't do this!!
def increment_counter(x):
    global counter
    counter += x
rdd.foreach(increment_counter)

print("Counter value: ", counter)

Este código se usa para contar la cantidad de registros en rdd. Tenga en cuenta que esta escritura está mal!

Modo local vs modo nodo

Lo anterior no es correcto. El ejecutor de chispa descompondrá la operación rdd en tareas, y el ejecutor ejecuta cada tarea. Antes de ejecutar la tarea, spark calculará el cierre de la tarea, es decir, aquellas variables y métodos que deben ser visibles cuando el programa de ejecución realiza el cálculo, y lo enviará a cada ejecutor.

En el código anterior, la variable de contador se ha copiado y enviado al programa de ejecución de cada nodo, que es equivalente a la variable local del programa de ejecución de diferentes nodos. Cada nodo cambia la variable local. El contador del piloto final sigue siendo 0.

Al ejecutar el programa en modo local, a veces la función foreach se ejecutará en la misma JVM que el controlador, y hará referencia al contador global, entonces el programa será válido. Pero esta forma de escribir todavía no es la forma recomendada de escribir.

Para resolver los problemas en los escenarios anteriores, la chispa proporciona un acumulador (acumulador), el uso detallado se introducirá más adelante.

Imprimir elementos RDD

Use para rdd.collect()obtener el valor en rdd, y luego imprima. Pero esta no es una buena manera. Debido a que la operación de recopilación resumirá todos los datos en el rdd a una máquina, cuando el rdd tiene muchos datos, se quedará sin memoria.

rdd.foreach(println)No de la misma manera, la salida estándar se enviará a diferentes nodos.

El enfoque correcto debería ser :rdd.take(100).foreach(println)

Manejar pares de datos clave-valor

La mayoría de las operaciones RDD admiten cualquier tipo de datos, pero algunas operaciones solo admiten datos de valor clave. Las más comunes son las operaciones de distribución aleatoria, como grupo y agregado.

lines = sc.textFile("data.txt")
pairs = lines.map(lambda s: (s, 1))
counts = pairs.reduceByKey(lambda a, b: a + b)

transformaciones

Para más detalles, consulte: Documento de interfaz RDD

comportamiento

Para más detalles, consulte: Documento de interfaz RDD

API Spark RDD soporta operaciones asíncronas, como por foreachel foreachAsync.

operación aleatoria

shuffle es un mecanismo para redistribuir datos para que los datos se puedan agrupar de manera diferente en las particiones. Implicar la copia de datos a través de programas ejecutivos y máquinas es una operación complicada y costosa.

Antecedentes

Tome la operación reduceByKey como ejemplo.

Todos los valores de una sola clave pueden no estar en la misma partición o incluso en la misma máquina, pero el valor de la misma clave debe calcularse juntos.

Durante el cálculo de Spark, una sola tarea opera en una sola partición. Para organizar todos los valores de la misma clave, spark debe leer todos los datos de todas las particiones y agregar los valores de la misma clave para obtener el resultado final. Esto es barajar.

Las operaciones que causan shuffle incluyen operaciones de reparto tales como partición y fusión; operaciones ByKey como groupByKey y reduceByKey, y operaciones de unión como cogroup y join.

Impacto en el rendimiento

La reproducción aleatoria implica E / S de disco, serialización de datos, E / S de red y operaciones relativamente costosas.

Las operaciones reduceByKey y aggregateByKey consumen memoria de pila adicional, y las operaciones de volcado de datos involucradas en estas operaciones están todas organizadas en estructuras de datos de memoria. Cuando los datos no son adecuados para las operaciones de memoria, se producirá una sobrecarga de E / S de disco adicional y la recolección de basura.

Shuffle generará una gran cantidad de archivos intermedios, y spark mantendrá temporalmente estos archivos hasta que ya no use el RDD correspondiente antes de la recolección de basura. Si el programa retiene referencias al RDD correspondiente o la recolección de basura no se inicia con frecuencia, la tarea de chispa de mayor duración ocupará mucho espacio en disco.

RDD resistencia

RDD necesita usar la tecnología de persistencia de RDD cuando se reutiliza en el programa para acelerar el programa.

rdd.persist()
rdd.cache()

Existen diferentes niveles de almacenamiento para la persistencia.
imagen

MEMORY_ONLY es la opción predeterminada de rdd.cache ().

Selección de nivel de almacenamiento

La elección del nivel de almacenamiento es una compensación entre el uso de memoria y la eficiencia de la CPU. Se recomienda elegir de acuerdo con los siguientes principios:

  1. El MEMORY_ONLY predeterminado es una opción de alta eficiencia para la CPU. Si el programa se ejecuta bien, intente no cambiarlo.
  2. Si el programa funciona mal, intente MEMORY_ONLY_SER (solo para JAVA / SCALA)
  3. Si desea reparar la falla rápidamente, use el nivel de almacenamiento basado en la replicación. Habrá una mejor tolerancia a fallas durante la ejecución del programa, y ​​los datos perdidos se recuperarán automáticamente de la copia de seguridad para continuar con el cálculo.

eliminar datos

Spark monitorea el uso de memoria de cada nodo y realiza la recolección de basura de acuerdo con el principio LRU (menos utilizado recientemente). También puede eliminar manualmente un RDD a través de RDD.unpersist ().

Variable compartida

Variable de difusión

broadcastVar = sc.broadcast([1, 2, 3])
broadcastVar.value

La variable compartida creada por sc.broadcast se puede pasar a cada nodo para llamar. Una vez que se entrega, el conductor no debe cambiarlo. El programa de ejecución de cada nodo obtiene el mismo valor.

Acumuladores

Dos maneras

  1. sc.accumulator
accum = sc.accumulator(0)
sc.parallelize([1, 2, 3, 4]).foreach(lambda x: accum.add(x))
accum.value

sc.accumulator (0) le da a acum un valor inicializado. acum puede ser operado por todos los nodos utilizando el método add, pero el valor no puede leerse. Solo el controlador puede leer su valor a través de accm.value.

  1. Herede la clase AccumulatorParam , el uso específico de esta cosa aún no se ha estudiado.
class VectorAccumulatorParam(AccumulatorParam):
    def zero(self, initialValue):
        return Vector.zeros(initialValue.size)

    def addInPlace(self, v1, v2):
        v1 += v2
        return v1

# Then, create an Accumulator of this type:
vecAccum = sc.accumulator(Vector(...), VectorAccumulatorParam())

Implementar

Para más detalles, ver: Documentos oficiales

Supongo que te gusta

Origin www.cnblogs.com/Fosen/p/12689035.html
Recomendado
Clasificación