Best practice per l'esecuzione di algoritmi su Spanner Graph

Questo documento descrive le best practice per l'esecuzione di algoritmi su Spanner Graph. Vengono trattati i seguenti argomenti:

Best practice per lo schema del grafo per gli algoritmi

Se utilizzi etichette e proprietà personalizzate in Spanner Graph, ti consigliamo di esporre sempre le chiavi degli elementi come proprietà. In questo modo, puoi accedere a queste proprietà chiave nella clausola RETURN della query dell'algoritmo e utilizzarle per identificare l'elemento del grafo per cui l'algoritmo genera l'output.

Gestire l'output dell'algoritmo

Questa sezione condivide i consigli su cosa restituire dall'output dell'algoritmo e dove conservare i risultati restituiti.

Cosa restituire

Quando la firma dell'output dell'algoritmo contiene elementi del grafo, Spanner Graph ti consente di restituire qualsiasi proprietà di questi elementi. Per ridurre i costi di elaborazione, ti consigliamo di ridurre al minimo l'elenco delle proprietà da restituire. Ad esempio, restituisci solo le proprietà che sono chiavi di un elemento, perché le chiavi sono necessarie per identificare l'elemento.

Dove conservare

Spanner Graph supporta la persistenza del risultato della query dell'algoritmo in Cloud Storage o nella stessa istanza di Spanner Graph in cui avvii la query.

La persistenza in Spanner rende l'output dell'algoritmo accessibile a tutte le operazioni di Spanner in modo nativo. Ad esempio, puoi eseguire WeaklyConnectedComponent e conservare cluster_id nel grafo. Successivamente, esegui PageRank per un grafo di input con cluster_id specifico. Le funzionalità di Spanner, come Change Stream, propagano i nuovi output dell'algoritmo ai sistemi downstream. Se vuoi utilizzare l'output dell'algoritmo in Spanner, ti consigliamo di conservarlo in Spanner. Anche se Spanner Graph utilizza modi efficienti per raggruppare e conservare l'output dell'algoritmo in Spanner, tutte le scritture devono passare attraverso la stessa replica leader. Se hai già carichi di lavoro critici che occupano la capacità del leader, potresti voler scaglionare le esecuzioni dell'algoritmo per evitare di competere con i carichi di lavoro critici.

Valuta la possibilità di conservare i dati in Cloud Storage se non prevedi di utilizzare l'output dell'algoritmo in Spanner o se vuoi valutare l'output dell'algoritmo prima di importarlo nell'origine dati principale. Consulta i formati di file supportati.

Considerazioni sulla modellazione dei dati per l'aumento del grafo

Questa sezione illustra alcune considerazioni sulla modellazione dei dati quando si conserva l'output dell'algoritmo in Spanner.

Proprietà rispetto ai bordi

Gli algoritmi possono produrre una serie di approfondimenti, tra cui:

  • Metriche a livello di nodo (ad esempio, punteggio di centralità). Questi possono essere conservati come nuove proprietà del nodo.
  • Approfondimenti a coppie (ad esempio, somiglianza tra due nodi). Questi possono essere conservati come nuovi bordi tra i due nodi con il valore di output come proprietà del bordo.
  • Gli algoritmi di rilevamento della community identificano le community logiche nel grafo e possono assegnare una o più community a un determinato nodo. Puoi modellare l'appartenenza alla community come una nuova proprietà del nodo taggando ogni nodo membro con l'ID della community assegnata. Puoi anche modellare l'appartenenza alla community come nuovi sottografi e archiviare le community logiche come un nuovo tipo di nodi nel grafo con archi che li collegano ai nodi membri. La proprietà della community potrebbe essere sufficiente se vuoi sapere a quale community appartiene un nodo quando accedi a un nodo. Il sottografo della community potrebbe essere più appropriato quando vuoi navigare per community (ad esempio, trovare i nodi nella stessa community di un nodo iniziale). A seconda di come prevedi di utilizzare le informazioni sulla community, puoi scegliere una o entrambe le opzioni.

Schema predefinito rispetto a schema flessibile

Prima di conservare l'output dell'algoritmo in Spanner, definisci la colonna o la tabella di destinazione nello schema in uno dei seguenti modi:

  • Se i casi d'uso dell'algoritmo sono stabili e noti, puoi aggiungere in anticipo colonne o tabelle aggiuntive.
  • Se stai eseguendo l'iterazione e la sperimentazione con diversi modi per estrarre approfondimenti (ad esempio, provando diversi algoritmi, parametri, sottografi di input), potresti voler conservare e differenziare l'output di più sperimentazioni in modo flessibile senza aggiornare lo schema di Spanner per ogni esecuzione. In questo caso, puoi prendere in considerazione l'archiviazione di nuove proprietà e archi prodotti dagli algoritmi nelle tabelle secondarie generiche.

Per archiviare nuove proprietà e archi prodotti dagli algoritmi nelle tabelle secondarie generiche, segui questi passaggi:

Passaggio 1: crea tabelle secondarie generiche

-- 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;

Passaggio 2: archivia le proprietà e i bordi prodotti dagli algoritmi come righe della tabella secondaria, insieme all'elemento algo_run_id univoco che li ha prodotti.

-- 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;

Passaggio 3: accedi all'output dell'algoritmo utilizzando 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';

Passaggio 4: facoltativamente, crea un grafo logico aumentato con le proprietà e i bordi generati dall'algoritmo per semplificare l'accesso all'output dell'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)
  );

Puoi quindi accedere direttamente alle proprietà dell'algoritmo e navigare tra i bordi generati dall'algoritmo nella query 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

Specificare machine_category per carichi di lavoro di grandi dimensioni

Per la maggior parte dei carichi di lavoro, la `machine_category` default è appropriata. Se il grafo di input ha più di 1 miliardo di nodi e più di 10 miliardi di bordi, ti consigliamo di scegliere esplicitamente large per machine_category.

Riutilizzare il calcolo per un'iterazione rapida

Se stai sperimentando diversi algoritmi o parametri di input diversi su piccoli set di dati per un'iterazione rapida, ti consigliamo di utilizzare max_idle_time. Un valore max_idle_time più grande di Spanner Graph ti consente di riutilizzare le risorse di calcolo di cui è già stato eseguito il provisioning per più carichi di lavoro dell'algoritmo. In questo modo si riduce il sovraccarico dell'avvio a freddo del calcolo on demand e si mitiga il rischio di non riuscire a eseguire il provisioning del calcolo a causa di una mancanza temporanea di capacità. Tieni presente che il calcolo dell'algoritmo è fatturabile quando è inattivo.

Differenziare i tipi di elementi nell'output

Se l'output dell'algoritmo contiene più tipi di elementi, potresti voler includere ELEMENT_DEFINITION_NAME nell'output per distinguerli. Ad esempio:

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;

Passaggi successivi