Una funzione remota Spanner consente di implementare la funzione in linguaggi diversi da SQL. Le funzioni devono essere ospitate in Cloud Run Functions o Cloud Run. L'hosting delle funzioni in questo modo consente di suddividere la complessa logica di business in funzioni remote separate.
Un tipico deployment di una funzione remota prevede i seguenti passaggi:
Crea un endpoint HTTPS in Cloud Run Functions o Cloud Run.
- Se non hai mai utilizzato le funzioni remote, ti consigliamo di utilizzare le funzioni Cloud Run.
Crea una funzione remota in Spanner che rimanda a quell'endpoint HTTPS.
Utilizza la funzione remota in una query.
Ruoli obbligatori
Per assicurarti che il tuo account di servizio agente Spanner (service-PROJECT_ID@gcp-sa-spanner.iam.gserviceaccount.com) disponga delle autorizzazioni necessarie per utilizzare le funzioni remote di Spanner,
chiedi all'amministratore di concedere al tuo account di servizio agente Spanner (service-PROJECT_ID@gcp-sa-spanner.iam.gserviceaccount.com) il ruolo IAM Agente di servizio API Spanner (roles/spanner.serviceAgent) sul progetto.
L'amministratore potrebbe anche essere in grado di concedere al account di servizio dell'agente Spanner (service-PROJECT_ID@gcp-sa-spanner.iam.gserviceaccount.com) le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Tipi supportati
Le funzioni remote supportano i seguenti tipi di dati come tipi di argomenti o di ritorno:
ARRAY(di uno dei seguenti tipi supportati)BOOLEANBYTESDATEJSONINTEGERNUMERICSTRINGTIMESTAMP
Limitazioni
Non puoi creare funzioni remote con valori di tabella.
Le funzioni remote non sono supportate nelle espressioni delle colonne generate.
Potresti visualizzare richieste ripetute con gli stessi dati al tuo endpoint, a volte anche dopo risposte riuscite, a causa di errori di rete temporanei o riavvii interni di Spanner.
L'esecuzione di funzioni remote in istanze Spanner frazionarie non è supportata.
Le funzioni remote non sono supportate per le funzioni Cloud Run dietro domini personalizzati.
Le funzioni remote non sono supportate nel dialetto PostgreSQL.
Creazione di un endpoint
La logica di business deve essere implementata come funzione Cloud Run o Cloud Run. L'endpoint deve essere in grado di elaborare un batch di righe in una singola richiesta POST HTTPS e restituire il risultato del batch come risposta HTTPS.
Se hai creato funzioni remote per BigQuery, puoi riutilizzarle per Spanner.
Consulta il tutorial su Cloud Run Functions e l'altra documentazione di Cloud Run Functions su come scrivere, eseguire il deployment, testare e gestire una funzione Cloud Run.
Consulta la guida rapida di Cloud Run e altra documentazione di Cloud Run su come scrivere, eseguire il deployment, testare e gestire un servizio Cloud Run.
Ti consigliamo di mantenere l'autenticazione predefinita per la tua funzione Cloud Run o il tuo servizio Cloud Run. Evita di configurare il servizio per consentire chiamate non autenticate.
Formato di input
Spanner invia richieste POST HTTPS con corpi JSON nel seguente formato:
| Nome campo | Descrizione | Tipo di campo |
|---|---|---|
requestId
|
Identificatore della richiesta. Unico in più richieste inviate all'endpoint in una query GoogleSQL. | Sempre fornito. Stringa. |
calls
|
Un batch di dati di input. | Sempre fornito. Un array JSON.
Ogni elemento è un array JSON che rappresenta un elenco di argomenti con codifica JSON per una singola chiamata di funzione remota. |
Esempio di richiesta:
// Sample request to a Cloud Run functions to calculate sum of two numbers. This request
// has two calls batched together into a single request.
{
"requestId": "124ab1c",
"calls": [
[1, 2],
[3, 4]
]
}
Formato di output
Spanner prevede che l'endpoint restituisca una risposta HTTPS nel seguente formato; in caso contrario, Spanner non può utilizzare la risposta e la query non riesce a chiamare la funzione remota.
| Nome campo | Descrizione | Intervallo di valori |
replies
|
Un batch di valori restituiti. | Array JSON.
Ogni elemento corrisponde a un valore restituito con codifica JSON della funzione esterna. La dimensione dell'array deve corrispondere a quella dell'array JSON dicalls nella richiesta HTTPS. Ad esempio, se la matrice JSON in calls ha 4 elementi, anche questa matrice JSON deve averne 4. Obbligatorio per una risposta corretta.
|
errorMessage
|
Messaggio di errore quando viene restituito il codice di risposta HTTPS diverso da 200. Per gli errori non riproducibili, Spanner restituisce questo messaggio di errore all'utente. Obbligatorio nelle risposte non riuscite. In genere meno di 1 kB. | Stringa. |
Esempio di risposta corretta:
// Sample response from the Cloud Run functions which has the sum of the two numbers. Note
// that the order of the values within `replies` field matches the `calls` field from
// the request.
{
"replies": [
3, // 1 + 2 = 3
7 // 3 + 4 = 7
]
}
Esempio di risposta non riuscita:
{
// The error message returned by your Cloud Run functions to indicate an error.
// In this sample, the error message states that an overflow occurred when summing two numbers.
"errorMessage": "Overflow detected when calculating sum of two numbers."
}
Codice di risposta HTTPS
L'endpoint restituisce un codice HTTPS 200 per una risposta riuscita. Quando Spanner riceve qualsiasi altro valore, considera la risposta un errore e riprova quando il codice di risposta HTTPS è 408, 429, 500, 503 o 504 fino al raggiungimento di un limite interno.
Codice di esempio
Funzione Cloud Run
Il seguente esempio di codice Python implementa l'aggiunta di tutti gli argomenti interi della funzione remota. Gestisce una richiesta con gli argomenti per le chiamate batch e restituisce tutti i risultati in una risposta.
"""
Python script which uses Flask framework to spin up a HTTP server to take
integers and return their sum. In case of overflow, it returns the error
as part of the response.
"""
import functions_framework
from flask import jsonify
# Max INT64 value encoded as a number in JSON by TO_JSON_STRING. Larger values are encoded as
# strings.
_MAX_LOSSLESS=9007199254740992
@functions_framework.http
def batch_add(request):
try:
return_value = []
request_json = request.get_json()
calls = request_json['calls']
for call in calls:
return_value.append(sum([int(x) if isinstance(x, str) else x for x in call if x is not None]))
replies = [str(x) if x > _MAX_LOSSLESS or x < -_MAX_LOSSLESS else x for x in return_value]
return_json = jsonify( { "replies": replies } )
return return_json
except Exception as e:
return jsonify( { "errorMessage": str(e) } ), 400
Supponendo che la funzione venga implementata nel progetto PROJECT_ID
nella regione us-east1 con il nome remote_add, è possibile accedervi utilizzando l'endpoint https://us-east1-PROJECT_ID.cloudfunctions.net/remote_add.
Cloud Run
Il seguente codice Python di esempio implementa un servizio web che può essere creato e distribuito in Cloud Run per la stessa funzionalità.
"""
Python script which uses Flask framework to spin up a HTTP server to take
integers and return their sum. In case of overflow, it returns the error
as part of the response.
"""
import os
from flask import Flask, request, jsonify
# Max INT64 value encoded as a number in JSON by TO_JSON_STRING. Larger values are encoded as
# strings.
_MAX_LOSSLESS=9007199254740992
app = Flask(__name__)
@app.route("/", methods=['POST'])
def batch_add():
try:
return_value = []
request_json = request.get_json()
calls = request_json['calls']
for call in calls:
return_value.append(sum([int(x) if isinstance(x, str) else x for x in call if x is not None]))
replies = [str(x) if x > _MAX_LOSSLESS or x < -_MAX_LOSSLESS else x for x in return_value]
return jsonify( { "replies" : replies } )
except Exception as e:
return jsonify( { "errorMessage": str(e) } ), 400
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
Per creare ed eseguire il deployment del codice, consulta la guida rapida: crea ed esegui il deployment di un'app web Python (Flask) in Cloud Run.
Supponendo che il servizio Cloud Run venga eseguito il deployment nel progetto PROJECT_ID nella regione us-east1 con il nome del servizio remote_add, è possibile accedervi utilizzando l'endpoint https://remote_add-<project_id_hash>-ue.a.run.app.
Crea una funzione remota
Per creare una funzione remota:
SQL
Esegui questa istruzione CREATE FUNCTION in Spanner:
CREATE FUNCTION REMOTE_FUNCTION_NAME(x INT64, y INT64) RETURNS INT64 NOT DETERMINISTIC LANGUAGE REMOTE OPTIONS (
endpoint = `ENDPOINT_URL`,
max_batching_rows = MAX_BATCHING_ROWS
);
Sostituisci quanto segue:
REMOTE_FUNCTION_NAME: il nome della funzione remota. Ad esempio,sum_func.ENDPOINT_URL: l'endpoint Cloud Run Functions o Cloud Run creato nel passaggio precedente.MAX_BATCHING_ROWS(facoltativo): il numero massimo di righe da inviare nell'ambito di una richiesta. Se non specificata, Spanner determina automaticamente le dimensioni del batch.
Utilizzare la funzione remota in una query
Per chiamare la funzione remota del passaggio precedente all'interno di una query, utilizza il seguente esempio:
SELECT REMOTE_FUNCTION_NAME(1, 2); -- 1 + 2 = 3
Prezzi
Vengono applicati i prezzi standard di Spanner.
Spanner fattura i byte inviati e ricevuti da Cloud Run Functions o Cloud Run.
Questa funzionalità potrebbe comportare costi per Cloud Run Functions e Cloud Run. Per i dettagli, consulta le pagine sui prezzi di Cloud Run Functions e Cloud Run.