Exporta datos a Bigtable (ETL inverso)

En este documento, se describe cómo configurar un ETL (RETL) inverso desde BigQuery a Bigtable. Puedes hacerlo mediante la declaración EXPORT DATA para exportar datos de una tabla de BigQuery a una tabla de Bigtable.

Los usuarios de BigQuery pueden configurar un flujo de trabajo de RETL en Bigtable que combina las capacidades de estadísticas de BigQuery con la latencia baja y la capacidad de procesamiento alta de Bigtable. Este flujo de trabajo te permite entregar datos a los usuarios de la aplicación sin agotar cuotas y límites en BigQuery.

Características de las tablas de Bigtable

Las tablas de Bigtable se diferencian de las tablas de BigQuery de varias formas:

  • Las tablas de Bigtable y BigQuery están compuestas por filas, pero una fila de Bigtable está compuesta por claves de fila y familias de columnas que tienen una cantidad arbitraria de columnas que pertenecen a la misma familia de columnas.
  • Las familias de columnas para una tabla determinada se crean en el momento de la creación de la tabla, pero también se pueden agregar o quitar más adelante. Cuando se crea una familia de columnas, no es necesario especificar las columnas que pertenecen a ella.
  • Las columnas de Bigtable no necesitan definirse con anticipación y se pueden usar para almacenar datos en su nombre (también conocido como calificador) dentro de los límites de tamaño de los datos dentro de las tablas.
  • Las columnas de Bigtable pueden tener cualquier valor binario dentro de los límites de tamaño de los datos dentro de las tablas.
  • Las columnas de Bigtable siempre tienen una dimensión temporal (también conocida como versión). Cualquier cantidad de valores puede almacenarse en cualquier fila para la misma columna, siempre que la marca de tiempo no sea idéntica.
  • Una marca de tiempo de Bigtable se mide en microsegundos desde el tiempo Unix, por ejemplo, 0 representa 1970-01-01T00:00:00 UTC. Las marcas de tiempo deben ser una cantidad no negativa de microsegundos con nivel de detalle de milisegundos (solo se aceptan múltiplos de 1,000). La marca de tiempo predeterminada de Bigtable es 0.
  • Los datos en Bigtable se leen por clave de fila, varias claves de fila, rango de claves de fila o mediante un filtro. En todos los tipos de solicitudes de lectura, se requiere al menos una clave de fila o un rango de claves de fila, excepto para un análisis completo de la tabla.

Si deseas obtener información sobre cómo preparar los resultados de BigQuery para la exportación a Bigtable, consulta Prepara los resultados de las consultas para la exportación.

Antes de comenzar

Otorga roles de Identity and Access Management (IAM) que les brindan a los usuarios los permisos necesarios para realizar cada tarea de este documento.

Roles obligatorios

Para obtener los permisos que necesitas a fin de exportar datos de BigQuery a Bigtable, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

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

También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.

Limitaciones

Tipos de BigQuery compatibles

Los siguientes tipos de datos son compatibles cuando se escriben en Bigtable:

Tipo de BigQuery Valor escrito de Bigtable
BYTES Se exporta tal como está.
STRING Se convierte en BYTES
INTEGER Si bigtable_options.column_families.encoding se configura como BINARY, el valor se escribe en un formato big-endian de 8 bytes (el byte más significativo primero). Si bigtable_options.column_families.encoding se configura como TEXT, el valor se escribe como una string legible por humanos que representa un número.
FLOAT Escribe el valor en el formato de salida de 8 bytes IEEE 754.
BOOLEAN Si bigtable_options.column_families.encoding se configura como BINARY, el valor se escribe como un valor de 1 byte (false = 0x00 o true = 0x01). Si bigtable_options.column_families.encoding se configura como TEXT, el valor se escribe como texto ("true" o "false").
JSON
Una columna exportada de tipo JSON se interpreta como un grupo de columnas que pertenecen a una familia de columnas específica de Bigtable. Los miembros del objeto JSON se interpretan como columnas y sus valores se deben escribir en Bigtable. El nombre de la columna que se escribirá se puede ajustar con la configuración bigtable_options.

Por ejemplo:

    JSON '{"FIELD1": "VALUE1", "FIELD2": "VALUE2"}' as MY_COLUMN_FAMILY
    
Donde los valores VALUE1 y VALUE2 se escriben en Bigtable como columnas FIELD1 y FIELD2 en la familia de columnas MY_COLUMN_FAMILY.
STRUCT
Una columna exportada de tipo STRUCT se interpreta como un grupo de columnas que pertenecen a una familia de columnas específica de Bigtable. Los miembros del struct se interpretan como columnas y sus valores se deben escribir en Bigtable. El nombre de la columna que se escribirá se puede ajustar con la configuración bigtable_options.

Por ejemplo:

    STRUCT<FIELD1  STRING, FIELD2 INTEGER> as MY_COLUMN_FAMILY
    
Donde los valores FIELD1 y FIELD2 se escriben en Bigtable como columnas FIELD1 y FIELD2 en la familia de columnas MY_COLUMN_FAMILY.

Estos tipos de datos compatibles son similares a la lectura de las tablas de Bigtable externas para BigQuery.

Valores NULL en Bigtable

Los valores de NULL en Bigtable tienen las siguientes restricciones:

  • Bigtable no tiene análogo para valores NULL. Exportar un valor NULL para una familia de columnas y una columna determinadas en Bigtable borra los valores actuales de una fila de Bigtable.

  • Si no existe un valor de Bigtable con una clave de fila, una familia de columnas, un calificador de columna y una marca de tiempo determinados antes de la exportación, los valores NULL exportados no tienen efecto en la fila de Bigtable.

  • Cuando se exporta un valor NULL de tipo STRUCT o JSON, se borran todos los valores de columna que pertenecen a la familia de columnas correspondiente de la fila afectada. Debes convertir el valor NULL en el tipo STRUCT o JSON para que el motor de SQL le adjunte un tipo correcto. La siguiente consulta borra todos los datos de la familia de columnas column_family1 con un conjunto de claves de filas determinadas:

    EXPORT DATA OPTIONS (...) AS
    SELECT
      rowkey,
    CAST(NULL as STRUCT) AS column_family1 FROM T
    
  • Las filas con claves de fila NULL se omiten durante la exportación. La cantidad de filas omitidas se muestra en las estadísticas de exportación al emisor.

Configura exportaciones con bigtable_options

Puedes usar la configuración bigtable_options durante una exportación para conectar las diferencias entre los modelos de almacenamiento de BigQuery y Bigtable. La configuración se expresa en la forma de una string JSON, como se muestra en el siguiente ejemplo:

EXPORT DATA OPTIONS(
   uri="https://bigtable.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/appProfiles/APP_PROFILE_ID/tables/TABLE",
   bigtable_options = """{
     "columnFamilies": [{
       "familyId": "COLUMN_FAMILY_NAME",
       "encoding": "ENCODING_VALUE",
       "columns": [
         {
           "qualifierString": "BIGTABLE_COLUMN_QUALIFIER",
           ["qualifierEncoded": "BASE_64_ENCODED_VALUE",]
           "fieldName": "BIGQUERY_RESULT_FIELD_NAME"
         }
       ]
    }]
   }"""
)

En la siguiente tabla, se describen los posibles campos usados en una configuración bigtable_options:

Nombre del campo Descripción
columnFamilies Un arreglo de descriptores de familia de columnas.
columnFamilies.familyId Identificador de la familia de columnas de Bigtable.
columnFamilies.encoding El valor se puede establecer en BINARY o TEXT. Si deseas obtener más información sobre cómo se codifican los tipos, consulta Tipos de BigQuery compatibles.
columnFamilies.columns Un arreglo de asignaciones de columnas de Bigtable.
columnFamilies.columns.qualifierString Opcional: Un calificador de columna de Bigtable. Especifica este valor si el calificador de columna no tiene códigos que no sean UTF-8. Los campos qualifierString y qualifierEncoding son mutuamente excluyentes. Si no se especifican qualifierString ni qualifierEncoded, fieldName se usa como calificador de columna.
columnFamilies.columns.qualifierEncoded Opcional: Calificador de columna codificado en Base64. Similar a qualifierString en caso de que el calificador de columna tenga códigos que no sean UTF-8.
columnFamilies.columns.fieldName Obligatorio: Nombre de campo del conjunto de resultados de BigQuery. Puede ser una string vacía en ciertos casos. Si deseas ver un ejemplo de cómo se usa un valor fieldName vacío con campos de tipos simples, consulta Prepara los resultados de las consultas para la exportación.

Prepara los resultados de la consulta para la exportación

Para exportar los resultados de las consultas a Bigtable, los resultados deben cumplir con los siguientes requisitos:

  • El conjunto de resultados debe contener una columna rowkey del tipo STRING o BYTES.
  • Las claves de fila, los calificadores de columna, los valores y las marcas de tiempo no deben exceder los límites de tamaño de los datos dentro de las tablas de Bigtable.
  • Debe haber al menos una columna distinta de rowkey en el conjunto de resultados.
  • Cada columna de conjunto de resultados debe ser uno de los tipos de BigQuery compatibles. Los tipos de columna no compatibles deben convertirse en uno de los tipos compatibles antes de exportar a Bigtable.

Bigtable no requiere que los calificadores de columna sean nombres de columna válidos de BigQuery, y Bigtable admite el uso de bytes. Si deseas obtener información sobre cómo anular los calificadores de columna de destino para una exportación, consulta Configura exportaciones con bigtable_options.

Si usas valores exportados con las API de Bigtable, como ReadModifyWriteRow, cualquier valor numérico debe usar la codificación binaria correcta.

De forma predeterminada, las columnas de resultados independientes de tipos distintos de STRUCT o JSON se interpretan como los valores para las familias de columnas de destino igual al nombre de la columna de resultados, y el calificador de columnas igual a una string vacía.

Para demostrar cómo se escriben estos tipos de datos, considera el siguiente ejemplo de SQL, en el que column y column2 son columnas de resultados independientes:

SELECT
  x as column1, y as column2
FROM table

En esta consulta de ejemplo, SELECT x as column1 escribe valores en Bigtable en la familia de columnas column1 y el calificador de columna '' (string vacía) cuando se manejan tipos distintos de JSON o STRUCT.

Puedes cambiar la forma en que se escriben estos tipos en una exportación con la configuración bigtable_options, como se muestra en el siguiente ejemplo:

EXPORT DATA OPTIONS (
  …
  bigtable_options="""{
   "columnFamilies" : [
      {
        "familyId": "ordered_at",
        "columns": [
           {"qualifierString": "order_time", "fieldName": ""}
        ]
      }
   ]
}"""
) AS
SELECT
  order_id as rowkey,
  STRUCT(product, amount) AS sales_info,
  EXTRACT (MILLISECOND FROM order_timestamp AT TIME ZONE "UTC") AS ordered_at
FROM T

En este ejemplo, la tabla de BigQuery T contiene la siguiente fila:

order_id order_timestamp product amount
101 2023-03-28T10:40:54Z Joystick 2

Si usas la configuración bigtable_options anterior con la tabla T, los siguientes datos se escriben en Bigtable:

rowkey sales_info (familia de columnas) ordered_at (familia de columnas)
101 calidad cantidad order_time
1970-01-01T00:00:00Z Joystick 1970-01-01T00:00:00Z 2 1680000054000

1680000054000 representa 2023-03-28T10:40:54Z en milisegundos desde el tiempo Unix en la zona horaria de UTC.

Establece la marca de tiempo para todas las celdas de una fila mediante _CHANGE_TIMESTAMP

Puedes agregar una columna _CHANGE_TIMESTAMP del tipo TIMESTAMP al resultado para la exportación. Cada celda escrita en Bigtable usa el valor de marca de tiempo de _CHANGE_TIMESTAMP de la fila de resultado exportada.

Bigtable no admite marcas de tiempo anteriores al tiempo Unix (1970-01-01T00:00:00Z). Si el valor de _CHANGE_TIMESTAMP es NULL, el tiempo Unix de 0 se usa como el valor de marca de tiempo predeterminado.

La siguiente consulta escribe celdas para las columnas product y amount con la marca de tiempo especificada en la columna order_timestamp de la tabla T.

EXPORT DATA OPTIONS (...) AS
SELECT
  rowkey,
  STRUCT(product, amount) AS sales_info,
  order_timestamp as _CHANGE_TIMESTAMP
FROM T

Exporta varios resultados con el mismo valor rowkey

Cuando exportas un resultado que contiene varias filas con el mismo valor rowkey, los valores escritos en Bigtable terminan en la misma fila de Bigtable.

Puedes usar este método para generar varias versiones de valores de columna en la misma fila. En este ejemplo, la tabla orders de BigQuery contiene los datos siguientes:

id customer order_timestamp amount_spent
100 Roberto 2023-01-01T10:10:54Z 10.99
101 Alicia 2023-01-02T12:10:50Z 102.7
102 Roberto 2023-01-04T15:17:01Z 11.1

Luego, el usuario ejecuta la siguiente sentencia EXPORT DATA:

EXPORT DATA OPTIONS (
uri="https://bigtable.googleapis.com/projects/PROJECT-ID/instances/INSTANCE-ID/appProfiles/APP_PROFILE_ID/tables/TABLE",
format="CLOUD_BIGTABLE"
) AS

SELECT customer as rowkey, STRUCT(amount_spent) as orders_column_family, order_timestamp as _CHANGE_TIMESTAMP
FROM orders

El uso de esta sentencia con la tabla orders de BigQuery da como resultado los siguientes datos escritos en Bigtable:

orders_column_family
Clave de fila amount_spent
Alicia 2023-01-02T12:10:50Z 102.7
Roberto 2023-01-01T10:10:54Z 10.99
2023-01-04T15:17:01Z 11.1

La exportación a Bigtable combina valores nuevos en la tabla en lugar de reemplazar filas completas. Si ya hay valores en Bigtable para una clave de fila, los valores nuevos pueden anular de forma parcial o total los valores anteriores según la familia de columnas, los nombres de las columnas y las marcas de tiempo de las celdas que se escriben.

Exporta varias columnas como valores de búfer de protocolo (Protobuf)

Los búferes de protocolo proporcionan un mecanismo flexible y eficiente para serializar datos estructurados. Exportar como Protobuf puede ser beneficioso si se considera cómo se manejan los diferentes tipos entre BigQuery y Bigtable. Puedes usar funciones definidas por el usuario (UDF) de BigQuery para exportar datos como valores binarios de Protobuf a Bigtable. Para obtener más información, consulta Exporta datos como columnas de Protobuf.

Optimización de exportaciones

Existen varias formas de aumentar la capacidad de procesamiento en la que se exportan los registros de BigQuery a Bigtable. Para optimizar el rendimiento de tu exportación, puedes hacer lo siguiente:

Precios

Para obtener información sobre los precios de la exportación de datos, consulta la página Precios de BigQuery.

Una vez que se exportan los datos, se te cobra por almacenarlos en Bigtable. Para obtener más información, consulta los precios de Bigtable.