Ejecuta algoritmos de Spanner Graph

En este documento, se explica cómo ejecutar algoritmos en Spanner Graph.

Estructura de la consulta del algoritmo de Spanner Graph

Una consulta de algoritmo de Spanner Graph tiene la siguiente estructura:

EXPORT DATA OPTIONS (export_option_list) AS
GRAPH graph_name
match_clause
call_statement algorithm_name(common_input, algorithm_specific_input)
  YIELD algorithm_specific_output
RETURN results
  • export_option_list: Son las opciones que definen cómo conservar los resultados de la consulta del algoritmo. Consulta Opciones de Cloud Storage y Opciones de Spanner.

  • graph_name: Es el nombre del gráfico.

  • match_clause: Son instrucciones MATCH opcionales para definir los elementos de entrada del algoritmo.

  • call_statement: Usa la sentencia CALL cuando omitas la variable match_clause y quieras operar en todo el grafo. Usa la sentencia CALL PER() cuando la variable match_clause esté presente y quieras operar en la tabla de trabajo. Para obtener más información, consulta GQL CALL.

  • algorithm_name: Es el nombre del algoritmo que se ejecutará. Para conocer los algoritmos disponibles, consulta Algoritmos de Spanner Graph.

  • common_input: Son los parámetros de entrada con nombre comunes a todas las consultas de algoritmos. Para obtener más información, consulta los parámetros de entrada comunes del algoritmo.

  • algorithm_specific_input: Son los parámetros de entrada con nombre para el algoritmo. Para obtener más información, consulta los parámetros de entrada definidos en Algoritmos de grafos de Spanner.

  • algorithm_specific_output: Es el resultado de la llamada al algoritmo. Para obtener más información, consulta los resultados definidos en Algoritmos de Spanner Graph y la cláusula YIELD en la declaración CALL.

  • results: Define qué se debe mostrar en los resultados de la consulta.

La consulta se compone de una sentencia EXPORT DATA, que define cómo conservar los resultados, y una CLÁUSULA GRAPH que produce el resultado de la consulta del algoritmo.

En su forma más simple, la cláusula graph identifica el grafo, usa una instrucción CALL para invocar un algoritmo que produce un resultado predefinido y, luego, usa una instrucción RETURN para especificar qué se debe devolver del resultado del algoritmo.

De manera opcional, la cláusula de grafo puede usar sentencias MATCH admitidas para seleccionar elementos de interés. En este caso, usa una cláusula PER () para agrupar todas las filas que muestra la declaración MATCH como entrada para el algoritmo. El algoritmo opera en un subgrafo lógico compuesto por el conjunto único de nodos y aristas seleccionados.

La consulta no devuelve ningún dato. La variable export_option_list determina cómo se conservan los resultados.

Para obtener más información sobre las consultas de algoritmos de Spanner Graph, consulta las siguientes secciones de este documento:

Parámetros de entrada de algoritmos comunes

Especifica estos parámetros de entrada con nombre en el siguiente formato: NAME => VALUE, ....

Nombre Tipo de valor Obligatorio Valor predeterminado Descripción
node_labels ARRAY No (ninguno) Solo se admite cuando se usa CALL. Es una lista de etiquetas de nodos que se incluirán en la entrada del algoritmo. Si se especifica, solo se incluyen los nodos con al menos una etiqueta coincidente.
edge_labels ARRAY No (ninguno) Solo se admite cuando se usa CALL. Es una lista de etiquetas de aristas que se incluirán en la entrada del algoritmo. Si se especifica, solo se incluyen los bordes con al menos una etiqueta coincidente.
edge_weight_property STRING No (ninguno) Es el nombre de la propiedad de borde que contiene los pesos. Si no se define, el sistema asigna un peso predeterminado de 1 a todas las aristas. El tipo de valor de la propiedad debe ser numérico.
machine_category STRING No predeterminado Es la categoría de máquina que se usará para la ejecución del algoritmo. Los valores admitidos son default y large.
fallback_compute_region STRING No (ninguno) Es la región de resguardo en la que se ejecuta el algoritmo si la región principal tiene restricciones de capacidad. Debe estar en la misma jurisdicción que la región de origen de la instancia de Spanner (por ejemplo, us-central1 si la región de origen es us-east1).
max_idle_time STRING No 30 min Especifica cuánto tiempo debe permanecer activa la instancia de procesamiento para su reutilización después de que se complete el algoritmo. El formato es una secuencia de números decimales, cada uno con un sufijo de unidad, como 4m, 1.5h o 1h45m. Las unidades de tiempo válidas son ns, us (o µs), ms, s, m y h.

Controla el resultado del algoritmo

Debes conservar los resultados de la consulta del algoritmo antes de poder inspeccionarlos. Usa el export_data_option para describir cómo conservar los resultados. Puedes conservar los resultados en Cloud Storage o en la misma instancia de Spanner de la que se originó la consulta.

Persiste los resultados en Cloud Storage

Para usar esta opción, asegúrate de que se otorgue el rol de administrador de objetos de almacenamiento (roles/storage.objectAdmin) a la cuenta de servicio de Spanner service-PROJECT_NUMBER@gcp-sa-spanner.iam.gserviceaccount.com administrada por Google.

Se admiten las siguientes opciones de EXPORT DATA cuando se conservan los resultados en Cloud Storage. Especifica las opciones en el siguiente formato: NAME=VALUE, ....

Nombre Tipo de valor Obligatorio Descripción
uri STRING Sí Es el URI de destino para la exportación, en formato gs://bucket/path/file. Si exportas una gran cantidad de datos, usa un comodín en uri para exportar datos a varios archivos. Por ejemplo, gs://bucket/path/file_*.csv.
format STRING Sí Es el formato de los datos exportados. Valores admitidos: CSV, PARQUET, AVRO.
header BOOL No Si es true, el sistema imprime los encabezados de columna para la primera fila de cada archivo de datos. El valor predeterminado es false. Solo se aplica a CSV.
overwrite BOOL No Si es true, el sistema reemplaza los archivos existentes con el mismo URI. De lo contrario, si existen archivos con el mismo URI, la sentencia devuelve un error. El valor predeterminado es false.
field_delimiter STRING No Es el delimitador que separa los campos. Valor predeterminado: , (coma). Solo se aplica a CSV.
compression STRING No Especifica el formato de compresión. Si no especificas un formato de compresión, los archivos permanecerán sin comprimir.
  • Para CSV, el valor admitido es GZIP.
  • Para PARQUET, los valores admitidos son SNAPPY, GZIP y ZSTD.
  • Para AVRO, los valores admitidos son DEFLATE y SNAPPY.

Los nombres de las columnas en la cláusula RETURN definen los nombres de las columnas en los archivos de salida de Cloud Storage.

Exporta datos a uno o más archivos

Las consultas de Spanner Graph admiten un solo operador comodín (*) en uri. El comodín puede aparecer en el componente del nombre de archivo, pero no en el nombre del bucket, el nombre de la carpeta ni la extensión de archivo. Si usas el operador comodín, le indicas a Spanner Graph que cree varios archivos fragmentados según el patrón que proporciones si el conjunto de resultados es grande. El sistema reemplaza el operador de comodín por un número, que comienza en cero, rellenado a la izquierda con 12 dígitos. Por ejemplo, un URI gs://my-bucket/file-*.csv crea archivos como gs://my-bucket/file-000000000000.csv, gs://my-bucket/file-000000000001.csv y otros similares.

Si usas uri sin comodín, el resultado es un solo archivo, como gs://my-bucket/file.csv.

Tipos de datos

Cuando exportas datos, los tipos de datos de grafos de Spanner se convierten de la siguiente manera, según el formato:

CSV

Todos los tipos de datos se convierten a su representación de cadena:

  • Los valores BOOL se convierten en true o false.
  • Los valores de BYTES se codifican en Base64.
  • Los valores de TIMESTAMP tienen el formato YYYY-MM-DD HH:MM:SS.ffffff UTC.
  • Los valores de NULL aparecen como cadenas vacías.

No puedes exportar datos anidados y repetidos en formato CSV.

Avro

Tipo de datos de Spanner Tipos de datos de Avro
BOOL BOOLEAN
INT64 LONG
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC BYTES con el tipo lógico DECIMAL(38,9)
STRING STRING
BYTES BYTES
TIMESTAMP LONG (microsegundos desde el ciclo de entrenamiento)
NULL null

Parquet

Tipo de datos de Spanner Tipo de datos de Parquet
BOOL BOOLEAN
INT64 INT64
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC DECIMAL(38,9)
STRING STRING
BYTES BYTE_ARRAY
TIMESTAMP TIMESTAMP_MICROS
NULL null

Conserva los resultados en Spanner

Se admiten las siguientes opciones de EXPORT DATA cuando se conservan los resultados en tu instancia de Spanner de origen. Especifica las opciones en el siguiente formato: NAME=VALUE, ....

Nombre Tipo de valor Obligatorio Descripción
format STRING Sí Es el formato de los datos exportados. Debe ser CLOUD_SPANNER.
table STRING Sí Nombre de la tabla de Spanner de destino en la que se escribirán los resultados. Puede ser cualquier tabla de la instancia de Spanner.
write_mode STRING Sí Es el modo de escritura que se usará. Los valores admitidos son los que se detallan a continuación:
  • update_ignore_all: Actualiza las filas existentes en la tabla de destino.
  • upsert_ignore_all: Inserta filas nuevas o actualiza las existentes en la tabla de destino.

En ambos modos, Spanner omite cualquier registro que introduzca un incumplimiento de restricción (por ejemplo, claves faltantes en una actualización, incumplimiento de índice único, incumplimiento de restricción de clave externa). Sin embargo, la escritura falla para los errores que no son de incumplimiento de restricciones (por ejemplo, discrepancia en el tipo de columna, falta de valores para las columnas NOT NULL).

Requisitos

Cuando conservas los resultados del algoritmo en Spanner, tu consulta de algoritmo debe cumplir con lo siguiente:

  • La tabla de destino debe existir.
  • Las columnas deben existir con un tipo coincidente: Todos los nombres de columna especificados en la cláusula RETURN ya deben existir en la tabla de destino con un tipo de datos coincidente. Usa alias para que coincidan con los nombres de las columnas de la tabla de destino si es necesario. Ejemplo: RETURN node.id AS person_id.
  • Incluye todas las columnas de clave primaria: La cláusula RETURN debe incluir todas las columnas de clave primaria de la tabla de destino.

Semántica de escritura

Conservar los resultados en Spanner es una operación no transaccional. Proporciona atomicidad a nivel de fila. Esto significa que el sistema escribe correctamente todas las columnas de la misma fila o no escribe ninguna de ellas. Sigue la semántica de al menos una vez. Esto significa que se puede escribir en una fila varias veces. Si lees desde la tabla de destino mientras se ejecuta el proceso, es posible que obtengas resultados incompletos.

Si falla la ejecución general, el sistema no revierte los cambios que ya se confirmaron. El proceso de escritura falla en el primer error que no se puede reintentar. Cuando se produce un error de escritura, el ERROR_MESSAGE en GRAPH_OPERATION_EXECUTION_STATUS indica la clave primaria de la fila que falló junto con el motivo específico del error.

El sistema vuelve a escribir los resultados del algoritmo en Spanner Graph con la prioridad MEDIUM.

Ejecuta consultas de ejemplo del algoritmo

En esta sección, se muestran ejemplos de consultas del algoritmo de Spanner Graph que puedes ejecutar en una instancia de prueba. Para obtener una lista completa de los algoritmos que admite Spanner Graph, consulta Algoritmos de Spanner Graph.

Antes de comenzar

Para ejecutar las consultas de ejemplo del algoritmo de Spanner Graph, primero debes completar lo siguiente:

  1. Sigue los pasos en Configurar y consultar Spanner Graph para crear un gráfico de Spanner.
  2. Asegúrate de tener los permisos necesarios.
  3. Opcional: Amplía el esquema de Spanner Graph si conservas el resultado en Spanner.

Agrega una columna nueva llamada page_rank a la tabla Account. Spanner escribe los resultados del algoritmo en esta columna nueva. Luego, actualiza la definición del gráfico para poder acceder a page_rank como una propiedad de nodo.

-- Add `page_rank` as a column. Data type of this column matches the data type defined in `PageRank` output signature.
ALTER TABLE Account ADD COLUMN page_rank FLOAT64;

-- Rerun the graph definition DDL to pickup `page_rank` as a new property.
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (`Account`, `Person`)
  EDGE TABLES (
    `PersonOwnAccount`
      SOURCE KEY (id) REFERENCES `Person` (id)
      DESTINATION KEY (account_id) REFERENCES `Account` (id)
      LABEL `Owns`,
    `AccountTransferAccount`
      SOURCE KEY (id) REFERENCES `Account` (id)
      DESTINATION KEY (to_id) REFERENCES `Account` (id)
      LABEL `Transfers`
  );

Ejecuta el algoritmo en el grafo completo con el filtro de etiquetas y conserva los resultados en Cloud Storage

En este ejemplo, se ejecuta la sentencia PageRank para clasificar las cuentas según las transferencias en las que participan. Los resultados de la consulta se conservan en un bucket de Cloud Storage en formato CSV como my-bucket-name/my-output.csv.

EXPORT DATA OPTIONS (
  uri = "gs://my-bucket-name/my-output.csv",
  format = "csv"
) AS
GRAPH FinGraph
CALL PageRank(node_labels => ['Account'], edge_labels => ['Transfers']) YIELD node, score
RETURN node.id, score AS page_rank

En Cloud Storage, deberías ver un archivo CSV con dos columnas (id y page_rank) cuando esta consulta se complete correctamente.

Ejecutar el algoritmo en el subgrafo definido por MATCH y conservar los resultados en el grafo

En este ejemplo, se usa el patrón MATCH para hacer coincidir de forma dinámica un subgrafo lógico que contiene todos los nodos Account y solo las aristas Transfer con un importe inferior a 500. Este subgrafo lógico es la entrada del algoritmo PageRank. Spanner conserva los resultados del algoritmo en la tabla Account.

EXPORT DATA OPTIONS (
  format = "CLOUD_SPANNER",
  table = "Account",
  write_mode = 'update_ignore_all'
) AS
GRAPH FinGraph
MATCH (n:Account)
RETURN n
FULL UNION ALL
MATCH -[e:Transfers WHERE e.amount < 500]->
RETURN e
NEXT
CALL PER () PageRank() YIELD node, score
RETURN node.id, score AS page_rank

Después de que la consulta se complete correctamente, ejecuta la siguiente consulta:

GRAPH FinGraph
MATCH (n:Account)
RETURN n.id, ROUND(n.page_rank, 2) AS page_rank
ORDER BY page_rank DESC, id ASC

Deberías ver resultados similares a los siguientes:

id page_rank
20 0.49
16 0.46
7 0.05

Verifica el estado de ejecución del algoritmo

Cuando una consulta de algoritmo de grafos se completa correctamente, devuelve cero filas y el estado Success. Según el tamaño del grafo de entrada y las configuraciones específicas del algoritmo, la ejecución del algoritmo puede tardar un tiempo en completarse. Puedes verificar el progreso y el estado de ejecución de una consulta de algoritmo de grafo en la tabla SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS. Esta tabla conserva la información durante 30 días.

GRAPH_OPERATION_EXECUTION_STATUS esquema

Nombre de la columna Tipo Descripción
QUERY_ID STRING Es el ID de la consulta del algoritmo de grafos.
QUERY_TEXT STRING El texto de la declaración de consulta.
START_TIMESTAMP TIMESTAMP Es la fecha y hora en que comenzó la ejecución de la búsqueda.
LAST_UPDATE_TIMESTAMP TIMESTAMP Es la hora en la que se actualizó el estado por última vez.
PROGRESS FLOAT64 Es el porcentaje de finalización estimado. El valor se encuentra entre 0 y 1, donde 0 significa que se inició y 1 significa que se completó.
STATUS STRING Es el estado actual de la ejecución. Los valores posibles incluyen PENDING, IN_PROGRESS, OK o un código de estado de error, como CANCELLED, DEADLINE_EXCEEDED, INVALID_ARGUMENT, FAILED_PRECONDITION, RESOURCE_EXHAUSTED, UNAVAILABLE o UNKNOWN.
ERROR_MESSAGE STRING Es el mensaje de error si falla la ejecución de la consulta.

La siguiente consulta de ejemplo enumera las consultas de gráficos que aún no se completaron correctamente:

SELECT
  query_id,
  query_text,
  start_timestamp,
  last_update_timestamp,
  progress,
  status,
  error_message
FROM
  SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS
WHERE
  status != "OK"
ORDER BY
  start_timestamp DESC;

Cancela la ejecución del algoritmo

Para cancelar una consulta de algoritmo de grafo en curso, busca el query_id en la tabla SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS y, luego, llama a cancel_query para ese query_id.

¿Qué sigue?