Crea tablas de Apache Lace de Iceberg

Con BigLake, puede acceder a las tablas de Iceberg con un control de acceso más detallado. Para ello, primero debes crear una tabla de Iceberg BigLake.

Iceberg es un formato de tabla de código abierto que admite tablas de datos a escala de petabytes. La especificación abierta de Iceberg te permite ejecutar varios motores de búsqueda en una sola copia de los datos almacenados en un almacén de objetos.

Como administrador de BigQuery, puedes aplicar un control de acceso a nivel de fila y columna, incluido el enmascaramiento de datos en tablas. Para obtener información sobre cómo configurar el control de acceso a nivel de tabla, consulta Configura las políticas de control de acceso. Las políticas de acceso a las tablas también se aplican cuando usas la API de BigQuery Storage como fuente de datos para la tabla en Dataproc y Spark sin servidores. Las tablas de BigLake proporcionan integraciones adicionales con otros servicios de BigQuery. Para obtener una lista completa de las integraciones disponibles, consulta Introducción a las tablas de BigLake.

Puedes crear tablas de Iceberg BigLake de las siguientes maneras:

  • Con BigLake Metastore (recomendado). BigLake Metastore es un catálogo de Iceberg personalizado. El uso de BigLake Metastore es el método recomendado porque permite la sincronización de tablas entre las cargas de trabajo de Spark y BigQuery. Para hacerlo, puedes usar un procedimiento almacenado de BigQuery para que Apache Spark inicialice BigLake Metastore y cree la tabla de Iceberg Biglake. Sin embargo, las actualizaciones del esquema aún requieren que ejecutes una consulta de actualización en BigQuery. Para obtener una lista completa de limitaciones, consulta Limitaciones.

  • Con el archivo de metadatos JSON de Iceberg. Si usas un archivo de metadatos JSON de Iceberg, debes actualizar de forma manual el archivo de metadatos más reciente cada vez que haya alguna actualización de la tabla. Para evitar esto, usa BigLake Metastore. Puedes usar un procedimiento almacenado de BigQuery para Apache Spark a fin de crear tablas de Iceberg Biglake que hagan referencia a un archivo de metadatos de Iceberg.

Antes de comenzar

  • Habilita las API de BigQuery Connection, BigQuery Reservation y BigLake .

    Habilita las API

  • Si usas un procedimiento almacenado para Spark en BigQuery a fin de crear tablas de Iceberg BigLake, debes seguir estos pasos:

    1. Crea una conexión de Spark.
    2. Configurar el control de acceso para esa conexión.
  • Para almacenar los metadatos y los archivos de datos de la tabla de Iceberg BigLake en Cloud Storage, crea un bucket de Cloud Storage. Debes conectarte a tu bucket de Cloud Storage para acceder a los archivos de metadatos. Para hacerlo, sigue estos pasos:

    1. Crea una conexión de recurso de Cloud.
    2. Configura el acceso para esa conexión.
  • Si usas BigLake Metastore, instala el catálogo de Iceberg personalizado adecuado para Apache Spark. Selecciona la versión del catálogo personalizado que mejor se adapte a la versión de Iceberg que usas.

    1. Iceberg 1.5.0: gs://spark-lib/biglake/biglake-catalog-iceberg1.5.0-0.1.1-with-dependencies.jar
    2. Iceberg 1.2.0: gs://spark-lib/biglake/biglake-catalog-iceberg1.2.0-0.1.1-with-dependencies.jar
    3. Iceberg 0.14.0: gs://spark-lib/biglake/biglake-catalog-iceberg0.14.0-0.1.1-with-dependencies.jar

Roles obligatorios

A fin de garantizar que el llamador de la API de BigLake tenga los permisos necesarios para crear una tabla de BigLake, pídele al administrador que le otorgue al llamador de la API de BigLake los siguientes roles de IAM en el proyecto:

Si quieres obtener más información para otorgar roles, consulta Administra el acceso.

Estos roles predefinidos contienen los permisos necesarios para crear una tabla de BigLake. Para ver los permisos exactos que son necesarios, expande la sección Permisos requeridos:

Permisos necesarios

Se requieren los siguientes permisos para crear una tabla de BigLake:

  • bigquery.tables.create
  • bigquery.connections.delegate
  • bigquery.jobs.create

Es posible que tu administrador también pueda otorgar estos permisos al llamador de la API de BigLake con roles personalizados o con otros roles predefinidos.

Además, para permitir que los usuarios de BigQuery consulten la tabla, la cuenta de servicio asociada con la conexión debe tener el rol de visualizador de BigLake (roles/biglake.viewer) y acceso al bucket de Cloud Storage que contiene los datos.

Para crear tablas de Iceberg BigLake con BigLake Metastore, el llamador de la API de BigLake cambia. Debes otorgar acceso a la cuenta de servicio de Dataproc o Spark al bucket de Cloud Storage que contiene esos datos:

Crea tablas con BigLake Metastore

Te recomendamos crear tablas de Iceberg BigLake con BigLake Metastore. Puedes usar Apache Spark para crear estas tablas. Una forma conveniente de hacerlo es usar los procedimientos almacenados de Spark de BigQuery mediante los siguientes pasos:

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Explorador, haz clic en la conexión del proyecto que usaste para crear el recurso de conexión.

  3. A fin de crear un procedimiento almacenado para Spark, haz clic en Crear procedimiento almacenado.

  4. En el editor de consultas, modifica el código de muestra para inicializar BigLake Metastore y crear una tabla de Iceberg BigLake con la declaración CREATE PROCEDURE que aparece:

     # Creates a stored procedure that initializes BLMS and database.
     # Creates a table in the database and populates a few rows of data.
     CREATE OR REPLACE PROCEDURE iceberg_demo.iceberg_setup_3_3 ()
     WITH CONNECTION `PROCEDURE_CONNECTION_PROJECT_ID.PROCEDURE_CONNECTION_REGION.PROCEDURE_CONNECTION_ID`
     OPTIONS(engine="SPARK",
     jar_uris=["gs://spark-lib/biglake/biglake-catalog-iceberg1.2.0-0.1.0-with-dependencies.jar"],
     properties=[
     ("spark.jars.packages","org.apache.iceberg:iceberg-spark-runtime-3.3_2.12:1.2.0"),
     ("spark.sql.catalog.CATALOG", "org.apache.iceberg.spark.SparkCatalog"),
     ("spark.sql.catalog.CATALOG.catalog-impl", "org.apache.iceberg.gcp.biglake.BigLakeCatalog"),
     ("spark.sql.catalog.CATALOG.hms_uri: HMS_URI")
     ("spark.sql.catalog.CATALOG.gcp_project", "PROJECT_ID"),
     ("spark.sql.catalog.CATALOG.gcp_location", "LOCATION"),
     ("spark.sql.catalog.CATALOG.blms_catalog", "CATALOG"),
     ("spark.sql.catalog.CATALOG.warehouse", "DATA_WAREHOUSE_URI")
     ]
     )
     LANGUAGE PYTHON AS R'''
     from pyspark.sql import SparkSession
    
     spark = SparkSession \
       .builder \
       .appName("BigLake Iceberg Example") \
       .enableHiveSupport() \
       .getOrCreate()
    
     spark.sql("CREATE NAMESPACE IF NOT EXISTS CATALOG;")
     spark.sql("CREATE DATABASE IF NOT EXISTS CATALOG.CATALOG_DB;")
     spark.sql("DROP TABLE IF EXISTS CATALOG.CATALOG_DB.CATALOG_TABLE;")
    
     /* Create a BigLake Metastore table and a BigQuery Iceberg table. */
     spark.sql("CREATE TABLE IF NOT EXISTS CATALOG.CATALOG_DB.CATALOG_TABLE (id bigint, demo_name string)
               USING iceberg
               TBLPROPERTIES(bq_table='BQ_DATASET.BQ_TABLE', bq_connection='TABLE_CONNECTION_PROJECT_ID.TABLE_CONNECTION_REGION.TABLE_CONNECTION_ID');
               ")
    
     /* Copy a Hive Metastore table to BigLake Metastore. Can be used together with
        TBLPROPERTIES `bq_table` to create a BigQuery Iceberg table. */
     spark.sql("CREATE TABLE CATALOG.CATALOG_DB.CATALOG_TABLE (id bigint, demo_name string)
                USING iceberg
                TBLPROPERTIES(hms_table='HMS_DB.HMS_TABLE');")
     ''';
    

    Reemplaza lo siguiente:

    • PROCEDURE_CONNECTION_PROJECT_ID: el proyecto que contiene la conexión para ejecutar los procedimientos de Spark, por ejemplo, myproject.

    • PROCEDURE_CONNECTION_REGION: la región que contiene la conexión para ejecutar los procedimientos de Spark, por ejemplo, us.

    • PROCEDURE_CONNECTION_ID: el ID de conexión, por ejemplo, myconnection.

      Cuando ves los detalles de conexión en la consola de Google Cloud, el ID de conexión es el valor en la última sección del ID de conexión completamente calificado que se muestra en ID de conexión, por ejemplo projects/myproject/locations/connection_location/connections/myconnection.

    • CATALOG: el nombre del catálogo de Iceberg que se creará para BigLake Metastore.

      El valor predeterminado es iceberg.

    • HMS_URI: si deseas copiar tablas de Hive Metastore existentes a BigLake Metastore, especifica un URI de Hive Metastore.

      Por ejemplo, thrift://localhost:9083.

    • PROJECT_ID: el ID del proyecto en el que deseas crear la instancia de BigLake Metastore.

      Las tablas de Iceberg BigLake también se crean en el mismo proyecto.

    • LOCATION: la ubicación en la que deseas crear la instancia de BigLake Metastore.

      BigQuery solo puede acceder a las instancias de BigLake Metastore que se almacenan en la misma ubicación.

    • DATA_WAREHOUSE_URI: el URI del bucket de Cloud Storage que creaste para almacenar los metadatos y los archivos de datos de Iceberg.

      Por ejemplo, gs://mybucket/iceberg-warehouse.

    • CATALOG_DB: el nombre de la base de datos que deseas crear en BigLake Metastore.

      Esta base de datos es equivalente al conjunto de datos de BigQuery que contendrá la tabla de Iceberg BigLake.

    • CATALOG_TABLE: el nombre de la tabla que deseas crear en BigLake Metastore.

      Esta tabla es equivalente a la tabla de Iceberg BigLake que deseas crear.

    • BQ_DATASET: el conjunto de datos de BigQuery que contiene la tabla de Iceberg BigLake.

    • BQ_TABLE: la tabla de Iceberg BigLake que deseas crear.

    • TABLE_CONNECTION_PROJECT_ID: Es el proyecto que contiene la conexión para crear la tabla de BigLake, por ejemplo, myproject.

    • TABLE_CONNECTION_REGION: Es la región que contiene la conexión para crear la tabla de BigLake, por ejemplo, us.

    • TABLE_CONNECTION_ID: el ID de conexión, por ejemplo, myconnection.

      Cuando ves los detalles de conexión en la consola de Google Cloud, el ID de conexión es el valor en la última sección del ID de conexión completamente calificado que se muestra en ID de conexión, por ejemplo projects/myproject/locations/connection_location/connections/myconnection.

      La cuenta de servicio asociada con la conexión debe tener roles/biglake.viewer para permitir que los usuarios de BigQuery consulten la tabla.

    • HMS_DB: Si deseas copiar las tablas existentes de Hive Metastore en BigLake Metastore, especifica una base de datos de Hive Metastore.

    • HMS_TABLE: Si deseas copiar las tablas existentes de Hive Metastore en BigLake Metastore, especifica una tabla de Hive Metastore.

    Para obtener más información sobre las configuraciones de catálogos de Iceberg, consulta Catálogos de Spark.

  5. Para ejecutar el procedimiento almacenado, haz clic en Ejecutar. Para obtener más información, consulta Llama al procedimiento almacenado de Spark. Se crea una tabla de Iceberg BigLake en BigQuery.

Crea tablas con un archivo de metadatos

Puedes crear tablas de Iceberg BigLake con un archivo de metadatos JSON. Sin embargo, este no es el método recomendado porque tienes que actualizar el URI del archivo de metadatos JSON de forma manual para mantener actualizada la tabla de BigLake. Si el URI no se mantiene actualizado, las consultas en BigQuery pueden fallar o proporcionar resultados diferentes de otros motores de consulta que usan directamente un catálogo de Iceberg. Para evitar esto, haz referencia a una instancia de BigLake Metastore cuando crees una tabla de Iceberg BigLake.

Los archivos de metadatos de tablas de Iceberg se crean en el bucket de Cloud Storage que especificas cuando creas una tabla de Iceberg mediante Spark.

Selecciona una de las opciones siguientes:

SQL

Usa la sentencia CREATE EXTERNAL TABLE: En el siguiente ejemplo, se crea una tabla de BigLake llamada myexternal-table:

  CREATE EXTERNAL TABLE myexternal-table
  WITH CONNECTION `myproject.us.myconnection`
  OPTIONS (
         format = 'ICEBERG',
         uris = ["gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json"]
   )

Reemplaza el valor uris por el archivo de metadatos JSON más reciente para una instantánea de tabla específica.

Puedes habilitar requerir filtro de partición si configuras la marca require_partition_filter.

bq

En un entorno de línea de comandos, usa el comando bq mk --table con el decorador @connection para especificar la conexión que se usará al final del parámetro --external_table_definition. Para habilitar la opción de requerir filtro de partición, usa --require_partition_filter.

bq mk 
--table
--external_table_definition=TABLE_FORMAT=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID
PROJECT_ID:DATASET.EXTERNAL_TABLE

Reemplaza lo siguiente:

  • TABLE_FORMAT: el formato de la tabla que deseas crear

    En este caso: ICEBERG.

  • URI: el archivo de metadatos JSON más reciente para una instantánea de tabla específica.

    Por ejemplo, gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json.

  • CONNECTION_PROJECT_ID: el proyecto que contiene la conexión para crear la tabla de BigLake, por ejemplo, myproject

  • CONNECTION_REGION: la región que contiene la conexión para crear la tabla de BigLake, por ejemplo, us

  • CONNECTION_ID: el ID de conexión a la tabla, por ejemplo, myconnection

    Cuando ves los detalles de conexión en la consola de Google Cloud, el ID de conexión es el valor en la última sección del ID de conexión completamente calificado que se muestra en ID de conexión, por ejemplo projects/myproject/locations/connection_location/connections/myconnection.

  • DATASET: el nombre del conjunto de datos de BigQuery en el que deseas crear una tabla

    Por ejemplo, mydataset.

  • EXTERNAL_TABLE: el nombre de la tabla que deseas crear

    Por ejemplo, mytable.

Actualizar metadatos de tablas

Si usas un archivo de metadatos JSON para crear tablas de Iceberg BigLake, actualiza la definición de tabla con los metadatos más recientes de la tabla. Para actualizar el esquema o el archivo de metadatos, selecciona una de las siguientes opciones:

bq

  1. Crea un archivo de definición de tabla:

    bq mkdef --source_format=ICEBERG \
    "URI" > TABLE_DEFINITION_FILE
    
  2. Usa el comando bq update con la marca --autodetect_schema:

    bq update --autodetect_schema --external_table_definition=TABLE_DEFINITION_FILE
    PROJECT_ID:DATASET.TABLE
    

    Reemplaza lo siguiente:

    • URI: tu URI de Cloud Storage con el archivo de metadatos JSON más reciente

      Por ejemplo, gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json.

    • TABLE_DEFINITION_FILE: el nombre del archivo que contiene el esquema de la tabla

    • PROJECT_ID: el ID del proyecto que contiene la tabla que deseas actualizar

    • DATASET: el conjunto de datos que contiene la tabla que deseas actualizar

    • TABLE: la tabla que deseas actualizar

API

Usa el método tables.patch con la propiedad autodetect_schema establecida como true:

PATCH https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET/tables/TABLE?autodetect_schema=true

Reemplaza lo siguiente:

  • PROJECT_ID: el ID del proyecto que contiene la tabla que deseas actualizar
  • DATASET: el conjunto de datos que contiene la tabla que deseas actualizar
  • TABLE: la tabla que deseas actualizar

En el cuerpo de la solicitud, especifica los valores actualizados para los siguientes campos:

{
     "externalDataConfiguration": {
      "sourceFormat": "ICEBERG",
      "sourceUris": [
        "URI"
      ]
    },
    "schema": null
  }'

Reemplaza URI por el archivo de metadatos de Iceberg más reciente. Por ejemplo, gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json

Configura las políticas de control de acceso

Puedes usar varios métodos para controlar el acceso a las tablas de BigLake:

Por ejemplo, supongamos que deseas limitar el acceso a las filas de la tabla mytable en el conjunto de datos mydataset:

+---------+---------+-------+
| country | product | price |
+---------+---------+-------+
| US      | phone   |   100 |
| JP      | tablet  |   300 |
| UK      | laptop  |   200 |
+---------+---------+-------+

Puedes crear un filtro a nivel de fila para Kim (kim@example.com) que restrinja su acceso a las filas en las que country es igual a US.

CREATE ROW ACCESS POLICY only_us_filter
ON mydataset.mytable
GRANT TO ('user:kim@example.com')
FILTER USING (country = 'US');

Luego, Kim ejecuta la siguiente consulta:

SELECT * FROM projectid.mydataset.mytable;

En el resultado, solo se muestran las filas en las que country es igual a US:

+---------+---------+-------+
| country | product | price |
+---------+---------+-------+
| US      | phone   |   100 |
+---------+---------+-------+

Consulta tablas de BigLake

Para obtener más información, visita Consulta datos de Iceberg.

Asignación de datos

BigQuery convierte los tipos de datos de Iceberg en tipos de datos de BigQuery, como se muestra en la siguiente tabla:

Tipo de datos Iceberg Tipo de datos de BigQuery
boolean BOOL
int INT64
long INT64
float FLOAT64
double FLOAT64
Decimal(P/S) NUMERIC or BIG_NUMERIC depending on precision
date DATE
time TIME
timestamp DATETIME
timestamptz TIMESTAMP
string STRING
uuid BYTES
fixed(L) BYTES
binary BYTES
list<Type> ARRAY<Type>
struct STRUCT
map<KeyType, ValueType> ARRAY<Struct<key KeyType, value ValueType>>

Limitaciones

Las tablas de Iceberg BigLake tienen limitaciones de tablas de BigLake y, también, las siguientes limitaciones:

  • Se admite la configuración de copy-on-write, pero no la de merge-on-read. Para obtener más información, consulta Configuración de Iceberg.

  • BigQuery admite la reducción de manifiestos mediante todas las funciones de transformación de partición de Iceberg, excepto Bucket. Para obtener información sobre cómo reducir las particiones, lee Consulta tablas particionadas. Las consultas que hacen referencia a las tablas de Iceberg BigLake deben contener literales en predicados en comparación con las columnas particionadas.

  • No se admite la creación de tablas de Iceberg BigLake en la región de BigQuery Omni de Azure (azure-eastus2).

  • Solo se admiten archivos de datos de Apache Parquet.

  • Todos los archivos de datos de Iceberg deben tener la propiedad field_id establecida en sus metadatos para asociar las columnas con el esquema de Iceberg. Las tablas con la propiedad schema.name-mapping.default no son compatibles.

  • No se admiten las tablas de Hive migradas a tablas de Iceberg mediante los procedimientos almacenados de Spark de Iceberg.

  • Si usas BigLake Metastore, se aplican las siguientes limitaciones:

    • BigLake Metastore no es compatible con las regiones de BigQuery Omni.
    • Cuando cambias el nombre de una tabla, la tabla de destino debe estar en la misma base de datos que la tabla de origen. La base de datos de la tabla de destino debe especificarse de forma explícita.
    • Cuando inspeccionas una tabla de metadatos de Iceberg, debes usar un nombre de tabla completamente calificado. Por ejemplo, prod.db.table.history

Costos

Se te cobrará por 1 TB a precios de consultas según demanda (por TB) por cada 6,250,000 solicitudes a BigLake Metastore y por cada 625,000 objetos almacenados en BigLake Metastore. Las tarifas de precios de consultas según demanda varían por región. Para una cantidad menor de solicitudes o de objetos, se te cobrará la fracción de 1 TB correspondiente.

Por ejemplo, si realizaste 6,250,000 solicitudes a BigLake Metastore y también almacenaste 312,500 objetos allí, se te cobrarían 1.5 TB a la tarifa de precios de consultas según demanda de la región en la que creaste la instancia de BigLake Metastore.

Exigir filtro de partición

Puedes exigir el uso de filtros de predicado si habilitas la opción Requerir filtro de partición para tu tabla de Iceberg. Si habilitas esta opción, los intentos de consultar la tabla sin especificar una cláusula WHERE que se alinee con cada archivo de manifiesto producirán el siguiente error:

Cannot query over table project_id.dataset.table without a
filter that can be used for partition elimination.

Cada archivo de manifiesto requiere al menos un predicado adecuado para eliminar particiones.

Puedes habilitar require_partition_filter de las siguientes maneras mientras creas una tabla de Iceberg:

SQL

Usa la sentencia CREATE EXTERNAL TABLE. En el siguiente ejemplo, se crea una tabla de BigLake llamada TABLE con requerir filtro de partición habilitado:

  CREATE EXTERNAL TABLE TABLE
  WITH CONNECTION `PROJECT_ID.REGION.CONNECTION_ID`
  OPTIONS (
         format = 'ICEBERG',
         uris = [URI],
         require_partition_filter = true
   )

Reemplaza lo siguiente:

  • TABLE: el nombre de la tabla que deseas crear.
  • PROJECT_ID: el ID del proyecto que contiene la tabla que deseas crear.
  • REGION: la ubicación en la que deseas crear la tabla de Iceberg.
  • CONNECTION_ID: el ID de conexión. Por ejemplo, myconnection.

  • URI: el URI de Cloud Storage con el archivo de metadatos JSON más reciente.

    Por ejemplo, gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json.

bq

Usa el comando bq mk --table con el decorador @connection para especificar la conexión que se usará al final del parámetro --external_table_definition. Usa --require_partition_filter para habilitar el filtro de requerir partición. En el siguiente ejemplo, se crea una tabla de BigLake llamada TABLE con el filtro de partición habilitado:

bq mk \
    --table \
    --external_table_definition=ICEBERG=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID \
    PROJECT_ID:DATASET.EXTERNAL_TABLE \
    --require_partition_filter

Reemplaza lo siguiente:

  • URI: el archivo de metadatos JSON más reciente para una instantánea de tabla específica

    Por ejemplo, gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json.

  • CONNECTION_PROJECT_ID: el proyecto que contiene la conexión para crear la tabla de BigLake, por ejemplo, myproject

  • CONNECTION_REGION: la región que contiene la conexión para crear la tabla de BigLake. Por ejemplo, us.

  • CONNECTION_ID: el ID de conexión. Por ejemplo, myconnection.

    Cuando ves los detalles de conexión en la consola de Google Cloud, el ID de conexión es el valor en la última sección del ID de conexión completamente calificado que se muestra en ID de conexión, por ejemplo projects/myproject/locations/connection_location/connections/myconnection.

  • DATASET: el nombre del conjunto de datos de BigQuery

    que contiene la tabla que deseas actualizar. Por ejemplo, mydataset.

  • EXTERNAL_TABLE: el nombre de la tabla que deseas crear

    Por ejemplo, mytable.

También puedes actualizar tu tabla de Iceberg para habilitar el filtro de partición requerida.

Si no habilitas la opción exigir filtro de partición cuando creas la tabla particionada, puedes actualizar la tabla para agregar la opción.

bq

Usa el comando bq update y proporciona la marca --require_partition_filter.

Por ejemplo:

Para actualizar mypartitionedtable en mydataset en tu proyecto predeterminado, ingresa el siguiente código:

bq update --require_partition_filter PROJECT_ID:DATASET.TABLE

¿Qué sigue?