Este documento descreve as práticas recomendadas para executar algoritmos no Spanner Graph. Ele abrange os seguintes tópicos:
- Práticas recomendadas de esquema de gráfico para algoritmos
- Processar a saída do algoritmo
- Especificar
machine_categorypara cargas de trabalho grandes - Mitigar restrições de capacidade regional com
fallback_compute_region - Reutilizar a computação para iteração rápida
- Diferenciar tipos de elementos na saída
Práticas recomendadas de esquema de gráfico para algoritmos
Se você usar rótulos e
propriedades personalizados em
Spanner Graph, recomendamos sempre expor as chaves de
elementos como propriedades. Dessa forma, é possível acessar essas propriedades de chave na cláusula RETURN da consulta do algoritmo e usá-las para identificar o elemento do gráfico para o qual o algoritmo gera a saída.
Processar a saída do algoritmo
Esta seção compartilha recomendações sobre o que retornar da saída do algoritmo e onde persistir os resultados retornados.
O que retornar
Quando a assinatura de saída do algoritmo contém elementos de gráfico, o Spanner Graph permite retornar qualquer propriedade desses elementos. Para reduzir o custo de processamento, recomendamos minimizar a lista de propriedades a serem retornadas. Por exemplo, retorne apenas as propriedades que são chaves de um elemento, porque as chaves são necessárias para identificar o elemento.
Onde persistir
O Spanner Graph oferece suporte à persistência do resultado da consulta do algoritmo no Cloud Storage ou de volta à mesma instância do Spanner Graph em que você inicia a consulta.
A persistência de volta ao Spanner torna a saída do algoritmo acessível a todas as operações do Spanner de forma nativa. Por exemplo, é possível executar WeaklyConnectedComponents e persistir cluster_id de volta ao gráfico.
Em seguida, execute PageRank para um gráfico de entrada com cluster_id específico.
Recursos do Spanner, como o Change
Stream, propagam novas saídas de algoritmo
para sistemas downstream. Se você quiser usar a saída do algoritmo no Spanner, recomendamos persistir no Spanner.
Embora o Spanner Graph use maneiras eficientes de agrupar
e persistir a saída do algoritmo no Spanner, todas as gravações precisam passar
pela mesma réplica líder. Se você já tiver cargas de trabalho críticas que ocupam a capacidade do líder, talvez seja necessário escalonar as execuções de algoritmo para evitar a concorrência com cargas de trabalho críticas.
Considere persistir no Cloud Storage se você não planeja usar a saída do algoritmo no Spanner ou quer avaliar a saída do algoritmo antes de ingerir na sua fonte de dados principal. Consulte os formatos de arquivo com suporte .
Considerações sobre modelagem de dados para aumentar o gráfico
Esta seção discute algumas considerações sobre modelagem de dados ao persistir a saída do algoritmo no Spanner.
Propriedades versus arestas
Os algoritmos podem produzir uma variedade de insights, incluindo o seguinte:
- Métricas no nível do nó (por exemplo, pontuação de centralidade). Elas podem ser persistidas como novas propriedades no nó.
- Insights aos pares (por exemplo, semelhança entre dois nós). Eles podem ser persistidos como novas arestas entre os dois nós com o valor de saída como propriedade de aresta.
- Os algoritmos de detecção de comunidade identificam comunidades lógicas no gráfico e podem atribuir uma ou mais comunidades a um determinado nó. É possível modelar a associação à comunidade como uma nova propriedade no nó, marcando cada nó membro com o ID da comunidade atribuída. Também é possível modelar a associação à comunidade como novos subgráficos e armazenar as comunidades lógicas como um novo tipo de nós no gráfico com arestas que os conectam aos nós membros. A propriedade da comunidade pode ser suficiente se você quiser saber a comunidade a que um nó pertence ao acessar um nó. O subgráfico da comunidade pode ser mais adequado quando você quiser navegar por comunidade (por exemplo, encontrar nós na mesma comunidade que um nó inicial). Dependendo de como você planeja usar as informações da comunidade, é possível escolher um ou ambos.
Esquema predefinido versus esquema flexível
Antes de persistir a saída do algoritmo de volta ao Spanner, defina a coluna ou tabela de destino no esquema de uma das seguintes maneiras:
- Se os casos de uso do algoritmo forem estáveis e conhecidos, você poderá adicionar mais colunas ou tabelas com antecedência.
- Se você estiver iterando e fazendo experimentos com diferentes maneiras de extrair insights (por exemplo, testando diferentes algoritmos, parâmetros, subgráficos de entrada), talvez seja necessário uma maneira flexível de persistir e diferenciar a saída de vários experimentos sem atualizar o esquema do Spanner para cada execução. Nesse caso, considere armazenar novas propriedades e arestas produzidas por algoritmos em tabelas filhas genéricas.
Para armazenar novas propriedades e arestas produzidas por algoritmos em tabelas filhas genéricas, siga estas etapas:
Etapa 1: criar tabelas filhas 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;
Etapa 2: armazene propriedades e arestas produzidas por algoritmos como linhas de tabela filhas, juntamente com o algo_run_id exclusivo que as produziu.
-- 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;
Etapa 3: acesse a saída do algoritmo usando
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';
Etapa 4: opcionalmente, crie um gráfico lógico aumentado com propriedades e arestas geradas por algoritmos para facilitar o acesso à saída do 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)
);
Em seguida, é possível acessar diretamente as propriedades do algoritmo e navegar pelas arestas geradas pelo algoritmo na consulta de gráfico:
-- 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
Especificar machine_category para cargas de trabalho grandes
Para a maioria das cargas de trabalho, a default machine_category é adequada. Se o gráfico de entrada tiver mais de 1 bilhão de nós e mais de 10 bilhões de arestas, recomendamos que você escolha explicitamente large para machine_category.
Mitigar restrições de capacidade regional com fallback_compute_region
Se a região de origem da instância do Spanner tiver restrições temporárias
de capacidade de computação, especifique uma
fallback_compute_region
na mesma jurisdição da região de origem da instância. Isso permite que o Spanner Graph faça failback automaticamente para o provisionamento de computação na região de failback quando a capacidade não estiver disponível na região de origem.
Reutilizar a computação para iteração rápida
Se você estiver fazendo experimentos com diferentes algoritmos ou parâmetros de entrada
em conjuntos de dados pequenos para iteração rápida, recomendamos usar
max_idle_time.
Um max_idle_time maior permite que o Spanner Graph reutilize os recursos de computação já provisionados para mais cargas de trabalho de algoritmo. Isso reduz o overhead da computação de inicialização a frio sob demanda e mitiga o risco de não ser possível provisionar a computação devido à falta temporária de capacidade. A computação de algoritmo é faturável quando está inativa.
Diferenciar tipos de elementos na saída
Se a saída do algoritmo contiver vários tipos de elementos, inclua ELEMENT_DEFINITION_NAME na saída para diferenciá-los. Exemplo:
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;