Crea un lakehouse con Spark y el catálogo de tiempo de ejecución de Lakehouse

Una arquitectura de lakehouse combina la flexibilidad de un data lake con las funciones de administración de datos de un almacén de datos. En este documento, se muestra cómo configurar un lakehouse en Google Cloud. Usas Apache Iceberg como formato de tabla, Managed Service para Apache Spark para el procesamiento y el catálogo de tiempo de ejecución de Lakehouse Iceberg REST Catalog para la administración unificada de metadatos.

Esta arquitectura usa formatos de tabla abiertos, como Iceberg, para agregar capacidades de almacenamiento de datos, como transacciones y evolución de esquemas, a los datos en Cloud Storage. Este enfoque crea una fuente única de información para tus datos a la que pueden acceder varios motores.

En este documento, se describen los catálogos que creas en el catálogo de tiempo de ejecución de Lakehouse. Para consultar tablas de Iceberg administradas por Data Catalog de AWS Glue, el catálogo de Databricks Unity o el catálogo de Snowflake Horizon a través de los catálogos federados del catálogo de tiempo de ejecución de Lakehouse, consulta Consulta catálogos federados con Spark.

Diagrama que muestra los componentes de una arquitectura de lakehouse, incluidos Managed Service para Apache Spark, Cloud Storage y el catálogo de REST de Lakehouse.
Diagrama de arquitectura de Lakehouse.

Acerca del catálogo de tiempo de ejecución de Lakehouse

El catálogo de tiempo de ejecución de Lakehouse es un metastore sin servidores y completamente administrado que se basa en el catálogo de tiempo de ejecución de Lakehouse. Almacena metadatos de tablas para formatos de tablas abiertos, como Iceberg, y expone los siguientes extremos:

  • Extremo del catálogo de REST de Iceberg: Permite que Spark y otros motores lean y escriban tablas de Iceberg a través del protocolo estándar de REST de Iceberg.
  • Extremo del catálogo de Hive: Permite que los gestores de cargas de trabajo de Spark y Hive administren tablas estándar de Hive y Spark, como las tablas de Parquet, ORC, Avro y Delta Lake, sin un almacén de metadatos de Hive alojado de forma independiente.

A partir de las versiones 4.0 de la imagen y el entorno de ejecución de Managed Service para Apache Spark, el catálogo de tiempo de ejecución de Lakehouse es el catálogo predeterminado de Spark, por lo que puedes crear y consultar tablas de Iceberg sin ninguna configuración de catálogo.

Beneficios en comparación con el almacén de metadatos de Hive

De forma predeterminada, Apache Spark de código abierto almacena los metadatos de la tabla en un almacén de metadatos de Hive que se ejecuta con el clúster, como una base de datos de Apache Derby incorporada o un servicio de almacén de metadatos de Hive en la instancia principal del clúster. El catálogo de tiempo de ejecución de Lakehouse ofrece las siguientes ventajas:

Función Hive Metastore de Spark Catálogo de entorno de ejecución de Lakehouse
Infraestructura Se ejecuta en el clúster. Tú lo dimensionas, lo parchas, creas copias de seguridad y lo escalas. Sin servidores y completamente administrado No hay infraestructura de almacén de metadatos para operar.
Vida útil de los metadatos Vinculado al clúster. Los metadatos se pierden cuando borras un clúster efímero, y las cargas de trabajo sin servidores no tienen un almacén de metadatos persistente. Persiste de forma independiente de los clústeres, las cargas de trabajo por lotes y las sesiones.
Uso compartido entre cargas de trabajo Cada clúster tiene su propio almacén de metadatos, a menos que configures y conectes uno externo. Los clústeres, las cargas de trabajo por lotes, las sesiones y otros proyectos comparten el mismo catálogo.
Acceso a varios motores Spark y Hive. Spark, Hive, BigQuery y cualquier motor que admita el protocolo REST de Iceberg.
Formatos de tabla Tablas de Hive. Iceberg requiere una configuración de catálogo adicional. Tablas de Iceberg a través del extremo del catálogo de REST de Iceberg y tablas de Hive a través del extremo del catálogo de Hive.
Control de acceso Acceso a nivel de almacén de metadatos, que suele administrarse de forma independiente del acceso a los datos. Permisos de catálogo y tabla basados en IAM.
Configuración Propiedades de catálogo manuales en cada clúster o carga de trabajo. Está activado de forma predeterminada para la versión de imagen y entorno de ejecución 4.0 y posteriores.

Para obtener una lista detallada de las operaciones de Hive Metastore que admite el extremo del catálogo de Hive, consulta Comparación de funciones con Hive Metastore.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that you have the permissions required to complete this guide.

  4. Verify that billing is enabled for your Google Cloud project.

  5. Enable the Dataproc, BigLake, BigQuery, and Cloud Storage APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  7. Verify that you have the permissions required to complete this guide.

  8. Verify that billing is enabled for your Google Cloud project.

  9. Enable the Dataproc, BigLake, BigQuery, and Cloud Storage APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  10. Crea un bucket de Cloud Storage para almacenar datos de Iceberg.
  11. Crea un catálogo en el catálogo de tiempo de ejecución de Lakehouse que apunte a tu bucket. Se recomienda un catálogo de varios bucket. Este paso es opcional para las versiones de imagen y entorno de ejecución 4.0 y posteriores si usas el catálogo de inicio predeterminado, que se crea automáticamente.

Roles obligatorios

Se requieren ciertos roles de Identity and Access Management (IAM) para ejecutar los ejemplos de esta página. Según las políticas de la organización, es posible que ya se hayan otorgado estos roles. Para verificar las asignaciones de roles, consulta ¿Necesitas otorgar roles?.

Para obtener más información para otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

Los roles que necesitas dependen de cómo se ejecuta tu carga de trabajo. Los clústeres de Managed Service para Apache Spark y los entornos de ejecución sin servidores de Managed Service para Apache Spark 2.3 y anteriores ejecutan cargas de trabajo como una cuenta de servicio. Los entornos de ejecución sin servidores de Managed Service para Apache Spark 3.0 y posteriores ejecutan cargas de trabajo con tus credenciales de usuario final (EUC) de forma predeterminada, por lo que otorgas roles de acceso a los datos a tu cuenta de usuario en lugar de a una cuenta de servicio. Si especificas una cuenta de servicio personalizada para un entorno de ejecución de 3.0 o posterior, la carga de trabajo se ejecuta con las credenciales de la cuenta de servicio. Para obtener más información, consulta Roles de implementaciones sin servidores.

Funciones de usuario

Para obtener los permisos que necesitas para crear un clúster de Managed Service para Apache Spark, enviar una carga de trabajo por lotes o crear una sesión interactiva, pídele a tu administrador que te otorgue los siguientes roles de IAM:

  • Usa un clúster o un entorno de ejecución sin servidores 2.3 o anterior:
  • Usa un entorno de ejecución sin servidores 3.0 o posterior: Editor de Dataproc Serverless (roles/dataproc.serverlessEditor) en el proyecto
  • Usa las credenciales de cuenta de servicio en un entorno de ejecución sin servidores 3.0 o posterior: Usuario de la cuenta de servicio (roles/iam.serviceAccountUser) en la cuenta de servicio personalizada

Si usas un entorno de ejecución sin servidores de Managed Service para Apache Spark 3.0 o posterior con credenciales de usuario final (la opción predeterminada), también necesitas los siguientes roles de acceso a los datos:

Para obtener los permisos que necesitas para leer y escribir tablas en tu catálogo con credenciales de usuario final, pídele a tu administrador que te otorgue los siguientes roles de IAM:

  • Lee y escribe datos de tablas en el modo de venta de credenciales: Editor de BigLake (roles/biglake.editor) en el proyecto que contiene el catálogo
  • Administra los recursos del catálogo y escribe datos de tablas en el modo de venta sin credenciales:

Roles de la cuenta de servicio

Otorga los siguientes roles a la cuenta de servicio que ejecuta tu carga de trabajo. Los entornos de ejecución sin servidores de Managed Service para Apache Spark 3.0 y versiones posteriores necesitan estos roles solo si la carga de trabajo se ejecuta con credenciales de cuenta de servicio.

Para garantizar que la cuenta de servicio predeterminada de Compute Engine o una cuenta de servicio personalizada tengan los permisos necesarios para ejecutar trabajos de Managed Service para Apache Spark y leer y escribir tablas en tu catálogo, pídele a tu administrador que otorgue los siguientes roles de IAM a la cuenta de servicio predeterminada de Compute Engine o a una cuenta de servicio personalizada:

  • Ejecuta trabajos de Managed Service para Apache Spark en un clúster o un entorno de ejecución sin servidores 2.3 o anterior: Trabajador de Dataproc (roles/dataproc.worker) en el proyecto
  • Ejecuta trabajos de Managed Service para Apache Spark en un entorno de ejecución sin servidores 3.0 o posterior:
  • Lee y escribe datos de tablas en el modo de venta de credenciales: Editor de BigLake (roles/biglake.editor) en el proyecto que contiene el catálogo
  • Administra los recursos del catálogo y escribe datos de tablas en el modo de venta sin credenciales:

Usa el catálogo de tiempo de ejecución de Lakehouse

A partir de la versión 4.0 de la imagen y del entorno de ejecución, Managed Service para Apache Spark establece el catálogo de tiempo de ejecución de Lakehouse como el catálogo de Spark predeterminado para clústeres, cargas de trabajo por lotes, sesiones interactivas y perfiles de entorno de ejecución. No es necesario crear un catálogo ni establecer ninguna propiedad de catálogo.

En la versión de imagen y entorno de ejecución 3.0 y anteriores, puedes habilitar el catálogo de tiempo de ejecución predeterminado de Lakehouse configurando la siguiente propiedad:

  • Cargas de trabajo por lotes, sesiones interactivas y perfiles de entorno de ejecución: dataproc.lakehouse.defaultCatalog=standard-lh-catalog-REGION
  • Clústeres: dataproc:dataproc.lakehouse.defaultCatalog=standard-lh-catalog-REGION

Reemplaza REGION por la región de la carga de trabajo, por ejemplo, us-central1.

Managed Service para Apache Spark resuelve el catálogo predeterminado de la siguiente manera:

  1. Si configuras dataproc.lakehouse.defaultCatalog (para clústeres, dataproc:dataproc.lakehouse.defaultCatalog), Managed Service para Apache Spark usa tu valor y no lo cambia.

  2. De lo contrario, para la versión de imagen y entorno de ejecución 4.0 y posteriores, Managed Service para Apache Spark establece dataproc.lakehouse.defaultCatalog en el catálogo de inicio regional, standard-lh-catalog-REGION, donde REGION es la región de la carga de trabajo. Si el catálogo de inicio no existe, Managed Service para Apache Spark lo crea automáticamente en el proyecto que ejecuta la carga de trabajo. No necesitas ningún rol de IAM adicional para crear el catálogo de inicio.

  3. Para la versión de imagen y entorno de ejecución 3.0 y anteriores, Managed Service para Apache Spark no establece un catálogo predeterminado. Para habilitar la función, configura dataproc.lakehouse.defaultCatalog=standard-lh-catalog-REGION de forma explícita, como se describió antes en esta sección.

Cuando se establece el catálogo predeterminado, Spark lo registra con el nombre del catálogo default_catalog y las siguientes propiedades resueltas:

Propiedad de Spark Valor
spark.sql.defaultCatalog default_catalog
spark.sql.catalog.default_catalog org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.default_catalog.type rest
spark.sql.catalog.default_catalog.warehouse bl://projects/PROJECT_ID/catalogs/CATALOG_ID

Como resultado, los nombres de tablas no calificados, como my_namespace.my_table, se resuelven en default_catalog.my_namespace.my_table en el catálogo de tiempo de ejecución de Lakehouse.

Establece el catálogo predeterminado

Para usar el catálogo de tiempo de ejecución de Lakehouse como el catálogo predeterminado en una versión anterior de imagen o entorno de ejecución, o para usar un catálogo que no sea el de inicio, establece la propiedad dataproc.lakehouse.defaultCatalog=CATALOG (para clústeres, dataproc:dataproc.lakehouse.defaultCatalog=CATALOG), en la que CATALOG es una de las siguientes opciones:

  • standard-lh-catalog-REGION: Es el catálogo de inicio regional en el proyecto de carga de trabajo.
  • projects/PROJECT_ID/catalogs/CATALOG_ID: es un catálogo existente, que puede estar en otro proyecto.

Por ejemplo, el siguiente comando envía una carga de trabajo por lotes que usa un catálogo existente como el catálogo predeterminado:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
    --region=REGION \
    --version=RUNTIME_VERSION \
    --properties=dataproc.lakehouse.defaultCatalog=projects/PROJECT_ID/catalogs/CATALOG_ID

Para configurar el catálogo predeterminado en la consola de Google Cloud , consulta las instrucciones de configuración del perfil del entorno de ejecución y del clúster.

Inhabilitar el catálogo de inicio

En la versión 4.0 y posteriores de la imagen y del entorno de ejecución, puedes inhabilitar el catálogo de inicio regional configurando dataproc.lakehouse.defaultCatalog=CATALOG (para clústeres, dataproc:dataproc.lakehouse.defaultCatalog=CATALOG) con el nombre completo del recurso de otro catálogo, como projects/PROJECT_ID/catalogs/CATALOG_ID. Managed Service para Apache Spark usa tu catálogo en lugar del catálogo de inicio y no anula la propiedad cuando la configuras de forma explícita.

Verifica el catálogo predeterminado

  1. Verifica las propiedades resueltas:

    • Para las sesiones interactivas, ejecuta el siguiente comando:

      gcloud beta dataproc sessions describe SESSION_ID \
          --location=REGION \
          --format="yaml(runtimeConfig.properties)"
    • Para los clústeres, verifica /etc/spark/conf/spark-defaults.conf en el nodo principal.

  2. En tu aplicación de Spark, confirma que el catálogo predeterminado esté activo:

    print(spark.conf.get("spark.sql.defaultCatalog"))  # default_catalog
    

Configura Managed Service para Apache Spark y crea una sesión de Spark

Configura un clúster, una carga de trabajo por lotes o una sesión interactiva para usar el catálogo de REST de Iceberg del catálogo de tiempo de ejecución de Lakehouse. Los tres admiten la propiedad de configuración simplificada dataproc.lakehouse.catalog.CATALOG_NAME (recomendada), que permite que Managed Service para Apache Spark lea la definición del catálogo y genere las propiedades de Spark del catálogo de REST de Iceberg. Solo el formato de clúster toma el prefijo dataproc:.

En la versión de imagen y entorno de ejecución 4.0 y posteriores, puedes omitir esta configuración y usar el catálogo de tiempo de ejecución de Lakehouse predeterminado. Usa las siguientes instrucciones para registrar tus propios catálogos o configurar el catálogo de tiempo de ejecución de Lakehouse en versiones anteriores.

Versiones de imagen y entorno de ejecución compatibles:

Tanto la configuración simplificada como la manual usan la autorización de Google para Iceberg (GoogleAuthManager), que requiere una de las siguientes versiones:

  • Clústeres de Managed Service para Apache Spark: versiones de imagen 2.2 2.2.65 y posteriores, versiones de imagen 2.3 2.3.11 y posteriores, o versiones de imagen 4.0 y posteriores.
  • Cargas de trabajo por lotes sin servidores y sesiones interactivas de Managed Service para Apache Spark: entornos de ejecución 2.2 2.2.60 y versiones posteriores, entornos de ejecución 2.3 2.3.10 y versiones posteriores, o entornos de ejecución 3.0 y versiones posteriores.

En la versión de imagen y catálogo de tiempo de ejecución 4.0 y posteriores, el catálogo de tiempo de ejecución de Lakehouse es el catálogo predeterminado.

Para las cargas de trabajo por lotes sin servidores y las sesiones interactivas, los roles requeridos dependen de la versión del entorno de ejecución. Los entornos de ejecución 3.0 y posteriores usan credenciales de usuario final de forma predeterminada. Para obtener más información, consulta Roles obligatorios.

Clúster

Crea un clúster de Managed Service para Apache Spark con los componentes opcionales de Iceberg y Jupyter con propiedades de configuración simplificadas (recomendado) o especificando manualmente las propiedades del catálogo en tu notebook.

Configuración simplificada con propiedades (recomendado)

Crea el clúster con la propiedad de catálogo:

gcloud dataproc clusters create CLUSTER_NAME \
  --project=PROJECT_ID \
  --region=REGION \
  --image-version=IMAGE_VERSION \
  --optional-components=ICEBERG,JUPYTER \
  --enable-component-gateway \
  --properties='dataproc:dataproc.lineage.enabled=true,dataproc:dataproc.lakehouse.catalog.CATALOG_NAME=projects/PROJECT_ID/catalogs/CATALOG_ID,spark:spark.sql.defaultCatalog=CATALOG_NAME'

Reemplaza lo siguiente:

  • CLUSTER_NAME: Es un nombre para tu clúster.
  • PROJECT_ID: Es el ID del proyecto deGoogle Cloud .
  • REGION: Es la región de Google Cloud para el clúster, por ejemplo, us-central1.
  • IMAGE_VERSION: Es la versión de la imagen de Managed Service para Apache Spark, por ejemplo, 2.3-debian12. Consulta Versiones de imágenes y entornos de ejecución compatibles.
  • CATALOG_NAME: Es un nombre para el catálogo local de Spark, por ejemplo, iceberg_catalog. Puede ser igual a la de CATALOG_ID.
  • CATALOG_ID: Es el ID del catálogo que creaste en Antes de comenzar.

La propiedad dataproc:dataproc.lineage.enabled=true no es obligatoria para que el catálogo de REST de Iceberg del catálogo de tiempo de ejecución de Lakehouse funcione correctamente. Se agrega para el seguimiento del linaje en el ejemplo de linaje de datos.

Conéctate al clúster con un notebook de Jupyter (ya sea un notebook de Vertex AI Workbench o un notebook iniciado en el clúster) y crea el SparkSession sin especificar las configuraciones del catálogo:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("APP_NAME").getOrCreate()

Reemplaza APP_NAME por el nombre de tu aplicación de Spark.

Configuración manual

Si no usas la propiedad de configuración simplificada, crea el clúster como se describió antes sin dataproc:dataproc.lakehouse.catalog. en la marca --properties, conéctate a un notebook de Jupyter y configura tu SparkSession de forma manual, como se indica a continuación:

import pyspark
from pyspark.context import SparkContext
from pyspark.sql import SparkSession

catalog_name = "CATALOG_NAME"

spark = SparkSession.builder.appName("APP_NAME") \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

Reemplaza lo siguiente:

  • CATALOG_NAME: Es un nombre para el catálogo local de Spark, por ejemplo, iceberg_catalog.
  • APP_NAME: Es el nombre de tu aplicación de Spark.
  • WAREHOUSE_PATH: Es la ruta de acceso a tu almacén. Para los catálogos de varios bucket (recomendado), usa bl://projects/PROJECT_ID/catalogs/CATALOG_ID. Para los catálogos de un solo bucket, usa gs://CLOUD_STORAGE_BUCKET_NAME.
  • PROJECT_ID: Es el ID del proyecto de Google Cloud .
Configura con la venta de credenciales

Para usar la venta de credenciales, debes usar un catálogo en el modo de venta de credenciales y agregar el encabezado X-Iceberg-Access-Delegation a las solicitudes del catálogo de REST de Iceberg con un valor de vended-credentials agregando la siguiente línea al compilador SparkSession:

.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials')

En el siguiente ejemplo, se configura el SparkSession con la venta de credenciales:

from pyspark.sql import SparkSession

catalog_name = "CATALOG_NAME"

spark = SparkSession.builder.appName("APP_NAME") \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

La configuración simplificada agrega este encabezado cuando el catálogo usa el modo de venta de credenciales. Para obtener más información, consulta la sección Encabezados en RESTCatalog de la documentación de Iceberg.

Configuración mediante Console

Para configurar el catálogo de tiempo de ejecución de Lakehouse cuando creas un clúster en la consola deGoogle Cloud , completa los siguientes pasos:

  1. En la consola de Google Cloud , ve a la página Clústeres de Managed Service para Apache Spark.

    Ir a los clústeres

  2. Haz clic en Crear clúster y, luego, en Crear en la fila Clúster en Compute Engine.

  3. En el paso de configuración del metastore, en Selecciona el metastore y el proyecto, selecciona Catálogo de tiempo de ejecución de Lakehouse.

  4. Configura el ID del proyecto, el catálogo de extremo de REST de Iceberg y el catálogo opcional de extremo de Hive, como se describe en la pestaña Perfil del entorno de ejecución.

  5. Completa el resto de la configuración del clúster y, luego, haz clic en Crear.

Sin servidores

Envía una carga de trabajo por lotes de PySpark a Managed Service para Apache Spark sin servidores con propiedades de configuración simplificadas (recomendado) o especificando manualmente las propiedades del catálogo.

Configuración simplificada con propiedades (recomendado)

Pasa la propiedad dataproc.lakehouse.catalog.CATALOG_NAME (sin el prefijo dataproc:) cuando envíes la carga de trabajo por lotes:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="dataproc.lakehouse.catalog.CATALOG_NAME=projects/PROJECT_ID/catalogs/CATALOG_ID,spark.sql.defaultCatalog=CATALOG_NAME"

Reemplaza lo siguiente:

  • PYSPARK_FILE: Es la ruta de acceso de Cloud Storage de gs:// al archivo de tu aplicación de PySpark.
  • PROJECT_ID: Es el ID del proyecto deGoogle Cloud .
  • REGION: Es la región de tu carga de trabajo por lotes.
  • RUNTIME_VERSION: Es la versión del entorno de ejecución sin servidores de Managed Service para Apache Spark, por ejemplo, 3.0. Los roles requeridos dependen de la versión del entorno de ejecución (consulta Versiones de imágenes y entornos de ejecución compatibles).
  • CATALOG_NAME: Es un nombre para el catálogo local de Spark, por ejemplo, iceberg_catalog. Puede ser igual a la de CATALOG_ID.
  • CATALOG_ID: Es el ID del catálogo que creaste en Antes de comenzar.

En el archivo de la aplicación de PySpark, crea el SparkSession sin especificar las configuraciones del catálogo:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("APP_NAME").getOrCreate()

Configuración manual

Si no usas la propiedad de configuración simplificada, especifica las propiedades del catálogo en la marca --properties cuando envíes tu carga de trabajo por lotes:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="\
spark.sql.defaultCatalog=CATALOG_NAME,\
spark.sql.catalog.CATALOG_NAME=org.apache.iceberg.spark.SparkCatalog,\
spark.sql.catalog.CATALOG_NAME.type=rest,\
spark.sql.catalog.CATALOG_NAME.uri=https://biglake.googleapis.com/iceberg/v1/restcatalog,\
spark.sql.catalog.CATALOG_NAME.warehouse=WAREHOUSE_PATH,\
spark.sql.catalog.CATALOG_NAME.header.x-goog-user-project=PROJECT_ID,\
spark.sql.catalog.CATALOG_NAME.rest.auth.type=org.apache.iceberg.gcp.auth.GoogleAuthManager,\
spark.sql.catalog.CATALOG_NAME.io-impl=org.apache.iceberg.gcp.gcs.GCSFileIO,\
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"

Reemplaza WAREHOUSE_PATH por la ruta de acceso a tu almacén. Para los catálogos de varios bucket (recomendado), usa bl://projects/PROJECT_ID/catalogs/CATALOG_ID. Para los catálogos de un solo bucket, usa gs://CLOUD_STORAGE_BUCKET_NAME.

Configura con la venta de credenciales

Para usar la distribución de credenciales, debes usar un catálogo en el modo de distribución de credenciales y agregar el encabezado X-Iceberg-Access-Delegation a las solicitudes del catálogo de Iceberg REST con un valor de vended-credentials. Para ello, agrega la siguiente propiedad a la marca --properties:

spark.sql.catalog.CATALOG_NAME.header.X-Iceberg-Access-Delegation=vended-credentials

En el siguiente ejemplo, se envía una carga de trabajo por lotes con la venta de credenciales:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="\
spark.sql.defaultCatalog=CATALOG_NAME,\
spark.sql.catalog.CATALOG_NAME=org.apache.iceberg.spark.SparkCatalog,\
spark.sql.catalog.CATALOG_NAME.type=rest,\
spark.sql.catalog.CATALOG_NAME.uri=https://biglake.googleapis.com/iceberg/v1/restcatalog,\
spark.sql.catalog.CATALOG_NAME.warehouse=WAREHOUSE_PATH,\
spark.sql.catalog.CATALOG_NAME.header.x-goog-user-project=PROJECT_ID,\
spark.sql.catalog.CATALOG_NAME.rest.auth.type=org.apache.iceberg.gcp.auth.GoogleAuthManager,\
spark.sql.catalog.CATALOG_NAME.io-impl=org.apache.iceberg.gcp.gcs.GCSFileIO,\
spark.sql.catalog.CATALOG_NAME.header.X-Iceberg-Access-Delegation=vended-credentials,\
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"

La configuración simplificada agrega este encabezado cuando el catálogo usa el modo de venta de credenciales. Para obtener más información, consulta la sección Encabezados en RESTCatalog de la documentación de Iceberg.

Sin servidores

Crea una sesión interactiva sin servidores de Managed Service para Apache Spark desde un notebook con la API de DataprocSparkSession, con propiedades de configuración simplificadas (recomendado) o especificando manualmente las propiedades del catálogo.

Configuración simplificada con propiedades (recomendado)

En un notebook que tenga instalado el paquete dataproc-spark-connect, como un notebook de BigQuery Studio o un notebook de Vertex AI Workbench, pasa la propiedad dataproc.lakehouse.catalog.CATALOG_NAME (sin el prefijo dataproc:) cuando crees la sesión:

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config(f'dataproc.lakehouse.catalog.{catalog_name}', 'projects/PROJECT_ID/catalogs/CATALOG_ID') \
.config('spark.sql.defaultCatalog', catalog_name) \
.getOrCreate()

Reemplaza lo siguiente:

  • CATALOG_NAME: Es un nombre para el catálogo local de Spark, por ejemplo, iceberg_catalog. Puede ser igual a la de CATALOG_ID.
  • RUNTIME_VERSION: Es la versión del entorno de ejecución sin servidores de Managed Service para Apache Spark, por ejemplo, 3.0. Los roles requeridos dependen de la versión del entorno de ejecución (consulta Versiones de imágenes y entornos de ejecución compatibles).
  • APP_NAME: Es el nombre de tu aplicación de Spark.
  • PROJECT_ID: Es el ID del proyecto deGoogle Cloud .
  • CATALOG_ID: Es el ID del catálogo que creaste en Antes de comenzar.

También puedes configurar un catálogo de Lakehouse en un perfil de entorno de ejecución. Para obtener más información, consulta la pestaña Perfil de entorno de ejecución.

Configuración manual

Si no usas la propiedad de configuración simplificada, especifica las propiedades del catálogo cuando crees la sesión:

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

Reemplaza RUNTIME_VERSION como se describe en el ejemplo de configuración simplificada que se encuentra antes en esta pestaña.

Reemplaza WAREHOUSE_PATH por la ruta de acceso a tu almacén. Para los catálogos de varios bucket (recomendado), usa bl://projects/PROJECT_ID/catalogs/CATALOG_ID. Para los catálogos de un solo bucket, usa gs://CLOUD_STORAGE_BUCKET_NAME.

Configura con la venta de credenciales

Para usar la venta de credenciales, debes usar un catálogo en modo de venta de credenciales y agregar el encabezado X-Iceberg-Access-Delegation a las solicitudes del catálogo de REST de Iceberg con un valor de vended-credentials agregando la siguiente línea al compilador de sesiones:

.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials')

En el siguiente ejemplo, se crea una sesión con venta de credenciales:

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

La configuración simplificada agrega este encabezado cuando el catálogo usa el modo de venta de credenciales. Para obtener más información, consulta la sección Encabezados en RESTCatalog de la documentación de Iceberg.

Sin servidores

Un perfil de entorno de ejecución, llamado plantilla de sesión en gcloud CLI y la API de Dataproc, almacena parámetros de configuración sin servidores reutilizables, incluido el metastore. Las sesiones interactivas que creas a partir del perfil de entorno de ejecución usan su configuración de catálogo.

Configuración mediante Console

  1. En la consola de Google Cloud , ve a la página Perfiles de entorno de ejecución.

    Ir a Perfiles de entorno de ejecución

  2. Haz clic en Crear o en el nombre de un perfil de entorno de ejecución existente y, luego, en Editar.

  3. Expande Configuración adicional y, luego, junto a Configuración del almacén de metadatos, haz clic en Editar.

  4. Selecciona Catálogo de tiempo de ejecución de Lakehouse. Esta es la selección predeterminada.

  5. Configura el catálogo:

    • ID del proyecto: Es el proyecto que contiene el catálogo. El valor predeterminado es el proyecto actual.
    • Extremo de REST de Iceberg: Se selecciona de forma predeterminada. Elige una de las siguientes opciones:
      • Define un catálogo nuevo para usar el catálogo de inicio regional, standard-lh-catalog-REGION.
      • Elige un ID de catálogo existente.
    • Opcional: Extremo de Hive: Selecciona esta casilla de verificación y especifica el ID del proyecto, el ID del catálogo y el Nombre del catálogo de un catálogo de Hive.
  6. Haz clic en Guardar y, luego, en Crear o Guardar.

Configuración de gcloud

  1. Crea un archivo YAML que establezca el catálogo predeterminado en runtimeConfig.properties:

    runtimeConfig:
    version: "RUNTIME_VERSION"
    properties:
      dataproc.lakehouse.defaultCatalog: projects/PROJECT_ID/catalogs/CATALOG_ID
    sparkConnectSession: {}

    En la versión 4.0 del entorno de ejecución y versiones posteriores, puedes omitir dataproc.lakehouse.defaultCatalog para usar el catálogo de inicio regional.

  2. Importa el archivo para crear o actualizar el perfil de entorno de ejecución:

    gcloud beta dataproc session-templates import RUNTIME_PROFILE_ID \
      --location=REGION \
      --source=FILE_NAME.yaml

Reemplaza lo siguiente:

  • RUNTIME_VERSION: Es la versión del entorno de ejecución sin servidores de Managed Service para Apache Spark, por ejemplo, 4.0.
  • PROJECT_ID: el proyecto que contiene el catálogo.
  • CATALOG_ID: Es el ID del catálogo.
  • RUNTIME_PROFILE_ID: Es el ID del perfil de entorno de ejecución.
  • REGION: Es la región del perfil de entorno de ejecución.
  • FILE_NAME: Es el nombre del archivo YAML.

Administra datos con Spark SQL

Después de configurar la sesión de Spark, usa Spark SQL para realizar operaciones de administración de datos.

Configura el catálogo: La propiedad dataproc.lakehouse.catalog. registra el catálogo con Spark, pero no lo convierte en el catálogo predeterminado. En los ejemplos de la sección anterior, se establece spark.sql.defaultCatalog (spark:spark.sql.defaultCatalog en un clúster) para que puedas usar nombres de tablas no calificados. Si omites esa propiedad, califica los nombres de las tablas con el nombre del catálogo, por ejemplo, CATALOG_NAME.NAMESPACE_NAME.base_table. En la versión de imagen y entorno de ejecución 4.0 y posteriores, si no configuras dataproc.lakehouse.defaultCatalog, los nombres de tablas no calificados se resuelven en el catálogo de tiempo de ejecución de Lakehouse predeterminado (default_catalog).

  1. Crea un espacio de nombres. En el catálogo de REST de Iceberg del catálogo de tiempo de ejecución de Lakehouse, un espacio de nombres corresponde a un conjunto de datos de BigQuery.

    spark.sql("CREATE NAMESPACE IF NOT EXISTS NAMESPACE_NAME")
    spark.sql("USE NAMESPACE_NAME")
    

    Reemplaza NAMESPACE_NAME por el nombre de tu espacio de nombres, por ejemplo, spark_lakehouse.

  2. Crear una tabla base en formato Iceberg y, luego, insertar datos

    spark.sql("DROP TABLE IF EXISTS base_table PURGE")
    spark.sql("CREATE TABLE base_table (id LONG) USING iceberg")
    spark.sql("INSERT INTO base_table VALUES 0, 1, 2, 3, 4")
    spark.sql("SELECT * FROM base_table").show()
    

    El resultado es similar a lo siguiente:

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       +---+
    
  3. Crea otra tabla para los datos nuevos.

    spark.sql("DROP TABLE IF EXISTS newdata PURGE")
    spark.sql("CREATE TABLE newdata(id LONG) USING iceberg")
    spark.sql("INSERT INTO newdata VALUES 3, 4, 5, 6")
    spark.sql("SELECT * FROM newdata").show()
    

    El resultado es similar a lo siguiente:

       +---+
       | id|
       +---+
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    
  4. Combina los datos nuevos en la tabla base.

    spark.sql("""MERGE INTO base_table USING newdata
               ON base_table.id = newdata.id
               WHEN MATCHED THEN
                 UPDATE SET base_table.id = newdata.id
               WHEN NOT MATCHED THEN INSERT * """)
    spark.sql("SELECT * FROM base_table").show()
    

    El resultado es similar a lo siguiente:

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    
  5. Actualiza los registros en la tabla base.

    spark.sql(
         "UPDATE base_table SET id = (id + 100) WHERE (id % 2 == 0)"
     )
    spark.sql("SELECT * FROM base_table").show()
    

    El resultado es similar a lo siguiente:

       +---+
       | id|
       +---+
       |  3|
       |104|
       |  5|
       |106|
       |100|
       |102|
       |  1|
       +---+
    
  6. Borra registros de la tabla base.

    spark.sql("DELETE FROM base_table WHERE (id % 2 == 0)")
    spark.sql("SELECT * FROM base_table").show()
    

    El resultado es similar a lo siguiente:

       +---+
       | id|
       +---+
       |  3|
       |  5|
       |  1|
       +---+
    

Consulta una instantánea histórica

Recupera una versión anterior de una tabla consultando un ID de instantánea. Esta operación también se conoce como viaje en el tiempo.

  1. Recupera el ID de instantánea de la versión de la tabla antes de las operaciones MERGE, UPDATE y DELETE.

    snapshot_ids = spark.sql(
         "SELECT snapshot_id FROM `NAMESPACE_NAME`.`base_table`.snapshots"
    ).collect()
    oldest_snapshot_id = snapshot_ids[1]["snapshot_id"]
    

    Reemplaza NAMESPACE_NAME por el espacio de nombres que creaste.

  2. Consulta la tabla con el ID de instantánea recuperado.

    df = (
         spark.read.format("iceberg")
         .option("versionAsOf", oldest_snapshot_id)
         .load("base_table")
     )
    df.show()
    

    El resultado muestra el estado de la tabla después de la operación MERGE, pero antes de las operaciones UPDATE o DELETE.

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    

Descubre el linaje de datos

Con las versiones de imagen 2.2 y posteriores de Managed Service para Apache Spark, puedes hacer un seguimiento del movimiento de datos entre las tablas del catálogo de REST de Iceberg del catálogo de tiempo de ejecución de Lakehouse con el linaje de datos.

Ejemplo de linaje de datos

  1. Crea tablas de Iceberg de origen y de destino y, luego, copia los datos.

    spark.sql("DROP TABLE IF EXISTS source_table PURGE")
    spark.sql("DROP TABLE IF EXISTS target_table PURGE")
    spark.sql("CREATE TABLE source_table (id LONG) USING iceberg")
    spark.sql("""CREATE TABLE target_table
      USING ICEBERG
      AS SELECT max(id) as top_id FROM source_table
      """)
    
  2. En la consola de Google Cloud , ve a la página Búsqueda de Knowledge Catalog.

    Ir a Búsqueda

  3. Busca una de las tablas y, luego, haz clic en la pestaña Lineage:

    Ejemplo de linaje de datos en la página Knowledge Catalog de la consola de Google Cloud .
    Ejemplo de un gráfico de linaje de datos en la página de Knowledge Catalog en la consola de Google Cloud .

    El linaje de datos reconoce las representaciones lógicas (tabla del catálogo de tiempo de ejecución de Lakehouse) y físicas (Cloud Storage) de las tablas del catálogo de REST de Iceberg del catálogo de tiempo de ejecución de Lakehouse.

Problemas conocidos del linaje de datos

En algunos clústeres de Managed Service para Apache Spark, es posible que no se genere el linaje de datos completo debido a un problema con la biblioteca de OpenLineage. Esta es una limitación conocida. Si afecta tus cargas de trabajo, comunícate con el equipo de Atención al cliente de Google Cloud.

¿Qué sigue?