En este documento, se describen las prácticas recomendadas para ejecutar algoritmos en Spanner Graph. Abarca los siguientes temas:
- Prácticas recomendadas para el esquema de grafos para algoritmos
- Cómo controlar la salida del algoritmo
- Cómo especificar
machine_categorypara cargas de trabajo grandes - Cómo mitigar las restricciones de capacidad regional con
fallback_compute_region - Cómo reutilizar la capacidad de procesamiento para una iteración rápida
- Cómo diferenciar los tipos de elementos en la salida
Prácticas recomendadas para el esquema de grafos para algoritmos
Si usas etiquetas y
propiedades personalizadas en
Spanner Graph, te recomendamos que siempre expongas las claves
de los elementos como propiedades. De esta manera, puedes acceder a esas propiedades clave en la cláusula RETURN de la consulta del algoritmo y usarlas para identificar el elemento del grafo para el que el algoritmo genera la salida.
Cómo controlar la salida del algoritmo
En esta sección, se comparten recomendaciones sobre qué devolver de la salida del algoritmo y dónde conservar los resultados devueltos.
Qué devolver
Cuando la firma de salida del algoritmo contiene elementos de grafo, Spanner Graph te permite devolver cualquier propiedad de esos elementos. Para reducir el costo de procesamiento, te recomendamos que minimices la lista de propiedades que se devolverán. Por ejemplo, solo devuelve las propiedades que son claves de un elemento, ya que las claves son necesarias para identificar el elemento.
Dónde conservar
Spanner Graph admite la conservación del resultado de la consulta del algoritmo en Cloud Storage o en la misma instancia de Spanner Graph en la que inicias la consulta.
La conservación en Spanner hace que la salida del algoritmo sea accesible para todas las operaciones de Spanner de forma nativa. Por ejemplo, puedes ejecutar WeaklyConnectedComponents y conservar cluster_id en el grafo.
Posteriormente, ejecuta PageRank para un grafo de entrada con un cluster_id específico.
Las funciones de Spanner, como flujos de cambios, propagan los nuevos resultados del algoritmo a los sistemas downstream. Si deseas usar la salida del algoritmo en Spanner, te recomendamos que la conserves en Spanner.
Si bien Spanner Graph usa formas eficientes de procesar por lotes
y conservar la salida del algoritmo en Spanner, todas las escrituras deben pasar
por la misma réplica principal. Si ya tienes cargas de trabajo críticas que ocupan la capacidad principal, es posible que desees escalonar las ejecuciones del algoritmo para evitar competir con las cargas de trabajo críticas.
Considera conservar en Cloud Storage si no planeas usar la salida del algoritmo en Spanner o deseas evaluar la salida del algoritmo antes de incorporarla a tu fuente de datos principal. Consulta los formatos de archivo compatibles.
Consideraciones sobre el modelado de datos para aumentar el grafo
En esta sección, se analizan algunas consideraciones sobre el modelado de datos cuando se conserva la salida del algoritmo en Spanner.
Propiedades versus aristas
Los algoritmos pueden producir una variedad de estadísticas, incluidas las siguientes:
- Métricas a nivel del nodo (por ejemplo, la puntuación de centralidad). Se pueden conservar como propiedades nuevas en el nodo.
- Estadísticas por pares (por ejemplo, la similitud entre dos nodos). Se pueden conservar como aristas nuevas entre los dos nodos con el valor de salida como propiedad de arista.
- Los algoritmos de detección de comunidades identifican comunidades lógicas en el grafo y pueden asignar una o más comunidades a un nodo determinado. Puedes modelar la membresía de la comunidad como una propiedad nueva en el nodo etiquetando cada nodo miembro con el ID de su comunidad asignada. También puedes modelar la membresía de la comunidad como subgrafos nuevos y almacenar las comunidades lógicas como un nuevo tipo de nodos en el grafo con aristas que los conectan a los nodos miembros. La propiedad de la comunidad puede ser suficiente si deseas saber a qué comunidad pertenece un nodo cuando accedes a él. El subgrafo de la comunidad puede ser más adecuado cuando deseas navegar por la comunidad (por ejemplo, encontrar nodos en la misma comunidad que un nodo inicial). Según cómo planees usar la información de la comunidad, puedes elegir una o ambas opciones.
Esquema predefinido versus esquema flexible
Antes de conservar la salida del algoritmo en Spanner, define la columna o tabla de destino en el esquema de una de las siguientes maneras:
- Si tus casos de uso de algoritmos son estables y conocidos, puedes agregar columnas o tablas adicionales de antemano.
- Si estás iterando y experimentando con diferentes formas de extraer estadísticas (por ejemplo, probar diferentes algoritmos, parámetros, subgrafos de entrada), es posible que desees una forma flexible de conservar y diferenciar la salida de varias experimentaciones sin actualizar el esquema de Spanner para cada ejecución. En este caso, puedes considerar almacenar las nuevas propiedades y aristas producidas por los algoritmos en tablas secundarias genéricas.
Para almacenar las nuevas propiedades y aristas producidas por los algoritmos en tablas secundarias genéricas, sigue estos pasos:
Paso 1: Crea tablas secundarias genéricas
-- Create `AccountAlgoProperty` as a child table of `Account`, to store all
-- properties produced by algorithms for `Account`.
-- `algo_run_id`: a unique ID for a given algorithm run.
-- `int_val`: column to store integer algorithm output.
-- `float_val`: column to store float algorithm output.
CREATE TABLE AccountAlgoProperty (
id INT64 NOT NULL,
algo_run_id STRING(200) NOT NULL,
int_val INT64,
float_val FLOAT64
) PRIMARY KEY(id, algo_run_id),
INTERLEAVE IN PARENT Account;
-- Create `AccountAlgoEdge` as a child table of `Account`, to store all
-- outgoing edges produced by algorithms for `Account`.
-- `algo_run_id`: a unique ID for a given algorithm run.
-- `to_id`: destination `Account` id.
-- `int_val`: column to store integer algorithm output.
-- `float_val`: column to store float algorithm output.
CREATE TABLE AccountAlgoEdge (
id INT64 NOT NULL,
algo_run_id STRING(200) NOT NULL,
to_id INT64 NOT NULL,
int_val INT64,
float_val FLOAT64,
CONSTRAINT FK_AccountId FOREIGN KEY (to_id) REFERENCES Account (id) NOT ENFORCED,
) PRIMARY KEY(id, algo_run_id, to_id),
INTERLEAVE IN PARENT Account;
Paso 2: Almacena las propiedades y aristas producidas por los algoritmos como filas de la tabla secundaria, junto con el algo_run_id único que las produjo.
-- Store PageRank score as property in child table.
EXPORT DATA
OPTIONS (format = "CLOUD_SPANNER",
table = "AccountAlgoProperty",
write_mode = 'upsert_ignore_all' ) AS
GRAPH FinGraph
CALL PageRank(node_labels => ['Account'], edge_labels => ['Transfers'])
RETURN node.id, "page_rank_123" AS algo_run_id, score As float_val;
-- Store ShortestPath output as edge in child table.
EXPORT DATA
OPTIONS (format = "CLOUD_SPANNER",
table = "AccountAlgoEdge",
write_mode = 'upsert_ignore_all' ) AS
GRAPH FinGraph
CALL ShortestPath(
source_nodes => ARRAY {
MATCH (n:Account {id: 7})
RETURN n
},
target_nodes => ARRAY {
MATCH (n:Account {id: 16})
RETURN n
}
) YIELD source_node, target_node, path, cost
RETURN source_node.id AS id, "shortest_path_456" AS algo_run_id,
target_node.id AS to_id, PATH_LENGTH(path) AS int_val, cost AS float_val;
Paso 3: Accede a la salida del algoritmo con
GRAPH_TABLE
SELECT acct.id, prop.float_val AS page_rank_score
FROM GRAPH_TABLE(
FinGraph
MATCH (n:Account)
RETURN n.id
) acct JOIN AccountAlgoProperty prop ON acct.id = prop.id
AND prop.algo_run_id = 'page_rank_123';
SELECT acct.id, edge.to_id, edge.int_val AS path_len, edge.float_val AS cost
FROM GRAPH_TABLE(
FinGraph
MATCH (n:Account)
RETURN n.id
) acct JOIN AccountAlgoEdge edge ON acct.id = edge.id
AND edge.algo_run_id = 'shortest_path_456';
Paso 4: De manera opcional, crea un grafo lógico aumentado con propiedades y aristas generadas por el algoritmo para facilitar el acceso a la salida del algoritmo.
-- Create a view that aggregates non-null algorithm properties per node into
-- name-value pairs in JSON.
CREATE OR REPLACE VIEW AccountWithAlgoProperties SQL SECURITY INVOKER AS
SELECT
n.id, ANY_VALUE(n.create_time) AS create_time,
ANY_VALUE(n.is_blocked) AS is_blocked, ANY_VALUE(n.nick_name) AS nick_name,
JSON_OBJECT(
IF(COUNT(c.algo_run_id) = 0, [], ARRAY_AGG(c.algo_run_id)),
IF(COUNT(c.algo_run_id) = 0, [], ARRAY_AGG(
COALESCE(
IF (c.int_val IS NULL, NULL, TO_JSON(c.int_val)),
IF (c.float_val IS NULL, NULL, TO_JSON(c.float_val))
)))) AS algo_props
FROM Account AS n LEFT JOIN AccountAlgoProperty AS c ON n.id = c.id
GROUP BY n.id;
-- Create FinGraphAugmented with algorithm generated properties and edges.
CREATE OR REPLACE PROPERTY GRAPH FinGraphAugmented
NODE TABLES (
AccountWithAlgoProperties AS Account
KEY(id)
LABEL Account PROPERTIES(
create_time,
id,
is_blocked,
nick_name,
algo_props),
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,
AccountAlgoEdge
SOURCE KEY (id) REFERENCES Account (id)
DESTINATION KEY (to_id) REFERENCES Account (id)
);
Luego, puedes acceder directamente a las propiedades del algoritmo y navegar por las aristas generadas por el algoritmo en la consulta del grafo:
-- Retrieve PageRank score property in graph query.
GRAPH FinGraphAugmented
MATCH (a:Account)
RETURN a.id, a.algo_props.page_rank_123 AS page_rank
ORDER BY page_rank DESC
LIMIT 5;
-- Navigate through ShortestPath edge in graph query.
GRAPH FinGraphAugmented
MATCH (s:Account {id: 7})-[e:AccountAlgoEdge {algo_run_id : 'shortest_path_456'}]->(d:Account)
RETURN s.id AS src, d.id AS dst, e.int_val AS path_len, e.float_val AS cost
Especifica machine_category para cargas de trabajo grandes
Para la mayoría de las cargas de trabajo, la default machine_category es adecuada. Si tu grafo de entrada tiene más de 1,000 millones de nodos y más de 10,000 millones de aristas, te recomendamos que elijas explícitamente large para machine_category.
Mitiga las restricciones de capacidad regional con fallback_compute_region
Si la región de origen de tu instancia de Spanner experimenta restricciones temporales
de capacidad de procesamiento, especifica una
fallback_compute_region
dentro de la misma jurisdicción que la región de origen de tu instancia. Esto permite que Spanner Graph recurra automáticamente al aprovisionamiento de capacidad de procesamiento en la región de resguardo cuando la capacidad no está disponible en la región de origen.
Reutiliza la capacidad de procesamiento para una iteración rápida
Si estás experimentando con diferentes algoritmos o diferentes parámetros de entrada
en conjuntos de datos pequeños para una iteración rápida, te recomendamos que uses
max_idle_time.
Un max_idle_time más grande permite que Spanner Graph reutilice los recursos de procesamiento que ya aprovisionó para más cargas de trabajo de algoritmos. Esto reduce la sobrecarga del inicio en frío de la capacidad de procesamiento a pedido y mitiga el riesgo de no poder aprovisionar capacidad de procesamiento debido a la falta temporal de capacidad. Ten en cuenta que la capacidad de procesamiento del algoritmo es facturable cuando está inactiva.
Diferencia los tipos de elementos en la salida
Si la salida del algoritmo contiene varios tipos de elementos, es posible que desees incluir ELEMENT_DEFINITION_NAME en la salida para diferenciarlos. Por ejemplo:
EXPORT DATA OPTIONS (
uri = "gs://bucket-name/page_rank.csv",
format = "csv",
overwrite = TRUE) AS
GRAPH FinGraph
CALL PageRank()
YIELD node, score
RETURN ELEMENT_DEFINITION_NAME(node) AS node_type, node.id, score;