Explicación detallada y demostración de caso práctico de DataFrame y Schema de Spark

1. Introducción del concepto

Spark es un marco de computación distribuida para manejar tareas de procesamiento de datos a gran escala. En Spark, DataFrame es una recopilación de datos distribuida, similar a una tabla en una base de datos relacional. DataFrame proporciona una abstracción de alto nivel que permite a los usuarios procesar datos de manera declarativa sin preocuparse por los detalles de los datos subyacentes y las complejidades de la computación distribuida. El esquema se usa en Spark para describir la estructura de datos en DataFrame, similar a la definición de columna en una tabla.

Presentemos DataFrame y Schema por separado:

Marco de datos:

Un DataFrame es una colección distribuida de datos compuesta por filas y columnas, similar a la estructura de una base de datos u hoja de cálculo tradicional. El DataFrame de Spark tiene las siguientes características:
Computación distribuida: DataFrame se distribuye y se puede procesar en paralelo en varios nodos del clúster para lograr un procesamiento de datos a gran escala de alto rendimiento.
Inmutabilidad: los DataFrames son inmutables, lo que significa que una vez creados, no se pueden modificar. En cambio, las operaciones en DataFrames generan nuevos DataFrames.
Ejecución retrasada: Spark adopta una estrategia de ejecución retrasada, es decir, las operaciones en el DataFrame no se ejecutan inmediatamente, sino que se optimizan y ejecutan cuando se requieren resultados de salida.
Los usuarios pueden usar instrucciones SQL, Spark API o Spark SQL para operar DataFrame, realizar filtrado de datos, conversión, agregación y otras operaciones. La ventaja de DataFrame radica en su facilidad de uso y capacidades de optimización. Spark optimizará todo el proceso de cálculo de acuerdo con el plan de ejecución de la operación para mejorar el rendimiento.

Esquema:

Schema es una descripción estructural de los datos en DataFrame, que define los nombres de las columnas y los tipos de datos de DataFrame. En Spark, un esquema es una colección de metadatos que incluye nombres de columnas y tipos de datos. La información de esquema de un DataFrame es crucial para el cálculo optimizado y la interpretación correcta de los tipos de datos.
Por lo general, el esquema se infiere automáticamente cuando se crea el DataFrame, o se puede especificar explícitamente mediante programación. La ventaja de especificar un esquema es que garantiza que los datos se interpreten correctamente y evita posibles errores de conversión de tipos. Si la fuente de datos no contiene información de esquema o necesita modificar el esquema, puede usar StructType y StructField para personalizar el esquema. Por ejemplo, puede crear un esquema con varios campos y tipos de datos, como cadenas, números enteros, fechas, etc.

Al usar Spark para leer fuentes de datos, como archivos CSV, datos JSON, tablas de bases de datos, etc., Spark intentará inferir automáticamente el esquema de los datos. Si la fuente de datos en sí no proporciona suficiente información, puede usar la opción de esquema para especificar o ajustar el esquema de DataFrame a través de operaciones de transformación de datos posteriores.

Resumen: DataFrame es una poderosa estructura de datos distribuidos en Spark que permite a los usuarios procesar datos de manera declarativa, mientras que Schema se usa para describir la información estructural de los datos en DataFrame para garantizar que los datos se interpreten y procesen correctamente. Estos dos conceptos juntos constituyen las poderosas capacidades de procesamiento de datos de Spark.

Código de combate

package test.scala

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{
    
    IntegerType, StringType, StructType}

object TestSchema {
    
    
  def getSparkSession(appName: String, localType: Int): SparkSession = {
    
    
    val builder: SparkSession.Builder = SparkSession.builder().appName(appName)
    if (localType == 1) {
    
    
      builder.master("local[8]") // 本地模式,启用8个核心
    }

    val spark = builder.getOrCreate() // 获取或创建一个新的SparkSession
    spark.sparkContext.setLogLevel("ERROR") // Spark设置日志级别
    spark
  }

  def main(args: Array[String]): Unit = {
    
    
    println("Start TestSchema")
    val spark: SparkSession = getSparkSession("TestSchema", 1)

    val structureData = Seq(
      Row("36636", "Finance", Row(3000, "USA")),
      Row("40288", "Finance", Row(5000, "IND")),
      Row("42114", "Sales", Row(3900, "USA")),
      Row("39192", "Marketing", Row(2500, "CAN")),
      Row("34534", "Sales", Row(6500, "USA"))
    )

    val structureSchema = new StructType()
      .add("id", StringType)
      .add("dept", StringType)
      .add("properties", new StructType()
        .add("salary", IntegerType)
        .add("location", StringType)
      )

    val df = spark.createDataFrame(
      spark.sparkContext.parallelize(structureData), structureSchema)
    df.printSchema()
    df.show(false)

    val row = df.first()
    val schema = row.schema
    val structTypeList = schema.toList
    println(structTypeList.size)
    for (i <- 0 to structTypeList.size - 1) {
    
    
      val structType = structTypeList(i)
      println(structType.name, row.getAs(structType.name), structType.dataType, structType.dataType)
    }
  }
}

producción

Inicie TestSchema
usando el perfil log4j predeterminado de Spark: org/apache/spark/log4j-defaults.properties
23/07/29 09:47:59 INFO SparkContext: ejecutando Spark versión 2.4.0
23/07/29 09:47:59 WARN NativeCodeLoader : No se puede cargar la biblioteca nativa de Hadoop para su plataforma... usando clases integradas de Java donde corresponda
23/07/29 09:47:59 INFO SparkContext: Aplicación enviada: TestSchema
23/07/29 09:47:59 INFO SecurityManager: Cambiando ver acls a: Nebula
23/07/29 09:47:59 INFO SecurityManager: Cambiar modificar acls a: Nebula
23/07/29 09:47:59 INFO SecurityManager: Cambiar ver acls grupos a:
23/07/29 09: 47:59 INFO SecurityManager: Cambiar modificar grupos de acls a:
23/07/29 09:47:59 INFO SecurityManager: SecurityManager: autenticación deshabilitada; ui acls deshabilitado; usuarios con permisos de visualización: Set(Nebula); grupos con permisos de visualización: Set(); usuarios con permisos de modificación: Set(Nebula); grupos con permisos de modificación: Set ()
23/07/29 09:48:01 INFO Utils: se inició correctamente el servicio 'sparkDriver' en el puerto 60785.
23/07/29 09:48:01 INFO SparkEnv: registro de MapOutputTracker
23/07/ 29 09:48:01 INFO SparkEnv: registro de BlockManagerMaster
23/07/29 09:48:01 INFO BlockManagerMasterEndpoint: uso de org.apache.spark.storage.DefaultTopologyMapper para obtener información de topología
23/07/29 09:48:01 INFO BlockManagerMasterEndpoint : BlockManagerMasterEndpoint arriba
23/07/29 09:48:01 INFO DiskBlockManager: directorio local creado en C:\Users\Nebula\AppData\Local\Temp\blockmgr-6f861361-4d98-4372-b78a-2949682bd557
23/07/29 09:48: 01 INFO MemoryStore: MemoryStore comenzó con una capacidad de 8,3 GB
23/07/29 09:48:01 INFO SparkEnv: registro de OutputCommitCoordinator
23/07/29 09:48:01 INFO Utils: se inició correctamente el servicio 'SparkUI' en el puerto 4040.
23/ 29/07 09:48:01 INFO SparkUI: Vinculó SparkUI a 0.0.0.0 y comenzó en http://LAPTOP-PEA8R2PO:4040
23/07/29 09:48:01 INFO Ejecutor: Iniciando el controlador ID del ejecutor en el host localhost
23/07/29 09:48:01 INFO Utils: se inició correctamente el servicio 'org.apache.spark.network.netty.NettyBlockTransferService' en el puerto 60826.
23/07/29 09:48:01 INFO NettyBlockTransferService: Servidor creado en LAPTOP-PEA8R2PO:60826
23/07/29 09:48:01 INFO BlockManager: Uso de org.apache.spark.storage.RandomBlockReplicationPolicy para la política de replicación de bloques
23/ 29/07 09:48:01 INFO BlockManagerMaster: Registro de BlockManager BlockManagerId(controlador, LAPTOP-PEA8R2PO, 60826, Ninguno)
23/07/29 09:48:01 INFO BlockManagerMasterEndpoint: Registro del administrador de bloques LAPTOP-PEA8R2PO:60826 con 8,3 GB de RAM , BlockManagerId (controlador, LAPTOP-PEA8R2PO, 60826, Ninguno)
23/07/29 09:48:01 INFO BlockManagerMaster: BlockManager registrado BlockManagerId (controlador, LAPTOP-PEA8R2PO, 60826, Ninguno)
23/07/29 09:48:01 INFO BlockManager: BlockManager inicializado: BlockManagerId (controlador, LAPTOP-PEA8R2PO, 60826, Ninguno)

Supongo que te gusta

Origin blog.csdn.net/programmer589/article/details/131991436
Recomendado
Clasificación