Snowpark Container Services: Verwenden von Diensten¶
Snowpark Container Services ermöglicht Ihnen die einfache Bereitstellung, Verwaltung und Skalierung von containerisierten Anwendungen. Nachdem Sie eine Anwendung erstellt und das Anwendungsimage in ein Repository Ihres Snowflake-Kontos hochgeladen haben, können Sie Ihre Anwendungscontainer als Dienst oder als Job ausführen. Unter diesem Thema wird erklärt, wie Sie Dienste verwenden.
Ein Dienst hat eine lange Ausführungszeit und endet, wie ein Webdienst, nicht automatisch. Nachdem Sie einen Dienst erstellt haben, verwaltet Snowflake den aktiven Dienst. Wenn z. B. ein Dienstcontainer aus irgendeinem Grund anhält, startet Snowflake diesen Container neu, damit der Dienst ohne Unterbrechung ausgeführt wird. Wenn Ihr Dienst mehr Ressourcen benötigt, z. B. mehr Rechenleistung, stellt Snowflake zusätzliche Knoten im Computepool bereit.
Grundlegende Operationen von Diensten¶
Snowpark Container Services stellt einen Satz von SQL-Befehlen zur Verfügung, mit denen Sie einen Dienst erstellen und verwalten können. Dazu zählen: CREATE SERVICE, ALTER SERVICE, DROP SERVICE, SHOW SERVICES und DESC[RIBE] SERVICE.
Für das Erstellen eines Dienstes sind mindestens folgende Informationen erforderlich:
Eine Dienstspezifikation: Diese Spezifikation liefert Snowflake die Informationen, die zum Konfigurieren und Ausführen Ihres Dienstes erforderlich sind. Die Spezifikation ist eine YAML-Datei. Sie können die Spezifikation direkt in einer CREATE SERVICE-Anweisung definieren oder die Spezifikation in einen Snowflake-Stagingbereich hochladen und auf den Stagingbereich in der CREATE SERVICE-Anweisung verweisen.
In den meisten Fällen werden Sie sich während der Entwicklungsphase für die Inline-Spezifikation entscheiden. Wenn Sie den Dienst jedoch in einer Produktionsumgebung einsetzen, ist es ratsam, das Designprinzip von der Trennung der Zuständigkeiten („Separation of Concerns“) anzuwenden und die Spezifikation in einen Stagingbereich hochzuladen.
Ein Computepool: Snowflake führt Ihren Dienst in dem angegebenen Computepool aus.
Beispiele
Erstellen eines Dienstes mit einer Inline-Spezifikation:
CREATE SERVICE echo_service IN COMPUTE POOL tutorial_compute_pool FROM SPECIFICATION $$ spec: containers: - name: echo image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial readinessProbe: port: 8000 path: /healthcheck endpoints: - name: echoendpoint port: 8000 public: true $$;
Erstellen eines Dienstes unter Verwendung von Stagingbereichsinformationen:
CREATE SERVICE echo_service IN COMPUTE POOL tutorial_compute_pool FROM @tutorial_stage SPECIFICATION_FILE='echo_spec.yaml';
Nachdem Sie einen Dienst erstellt haben, können Sie den Befehl ALTER SERVICE verwenden, um den Dienst anzuhalten bzw. fortzusetzen.
Mehrerer Dienstinstanzen erstellen und automatische Skalierung konfigurieren¶
Standardmäßig führt Snowflake eine Instanz des Dienstes in dem angegebenen Computepool aus. Um umfangreiche Workloads zu bewältigen, können Sie mehrere Dienstinstanzen ausführen, indem Sie die Eigenschaften MIN_INSTANCES und MAX_INSTANCES spezifizieren, die die Mindestanzahl der zu startenden Instanzen des Dienstes und die maximale Anzahl der Instanzen angeben, auf die Snowflake bei Bedarf skalieren kann.
Beispiel
CREATE SERVICE echo_service
IN COMPUTE POOL tutorial_compute_pool
FROM @tutorial_stage
SPECIFICATION_FILE='echo_spec.yaml'
MIN_INSTANCES=2
MAX_INSTANCES=4;
Wenn mehrere Dienstinstanzen ausgeführt werden, stellt Snowflake automatisch einen Load Balancer zum Verteilen der eingehenden Anforderungen bereit.
Führen Sie die folgenden Schritte aus, um Snowflake für die automatische Skalierung der Anzahl der ausgeführten Dienstinstanzen zu konfigurieren:
Geben Sie in der Dienstspezifikationsdatei die Anforderungen an Arbeitsspeicher und CPU für Ihre Dienstinstanz an. Weitere Informationen dazu finden Sie unter Feld „container.resources“.
Beispiel
resources: requests: memory: <memory-reserved> cpu: <cpu-units>
Wenn Sie den Befehl CREATE SERVICE ausführen, legen Sie die Parameter MIN_INSTANCES und MAX_INSTANCES fest. Sie können auch ALTER SERVICE verwenden, um diese Werte zu ändern.
Snowflake erstellt zunächst die Mindestanzahl von Dienstinstanzen auf dem angegebenen Computepool und skaliert dann automatisch die Anzahl der Instanzen nach Bedarf. Snowflake verwendet einen Schwellenwert von 80 % (sowohl für CPU als auch für den Arbeitsspeicher), um die Anzahl der Dienstinstanzen zu erhöhen oder zu verringern.
Zu einem bestimmten Zeitpunkt können eine oder mehrere Dienstinstanzen auf dem angegebenen Computepool ausgeführt werden. Snowflake überwacht kontinuierlich die Ressourcennutzung (Arbeitsspeicher oder CPU) innerhalb des Computepools und aggregiert die Nutzungsdaten aller aktuell ausgeführten Dienstinstanzen.
Wenn die aggregierte Ressourcennutzung (für alle Dienstinstanzen) 80 % übersteigt, stellt Snowflake eine zusätzliche Dienstinstanz im Computepool bereit. Wenn die aggregierte Ressourcennutzung unter 80 % fällt, skaliert Snowflake herunter, indem eine der aktiven Dienstinstanzen entfernt wird. Snowflake verwendet ein fünfminütiges Stabilisierungsfenster, um häufiges Skalieren zu verhindern.
Beachten Sie das folgende Skalierungsverhalten:
Die Skalierung der Dienstinstanzen wird durch die für den Dienst konfigurierten Parameter MIN_INSTANCES und MAX_INSTANCES eingeschränkt.
Wenn ein Hochskalieren erforderlich ist und die Knoten des Computepools nicht über die erforderliche Ressourcenkapazität verfügen, um eine weitere Dienstinstanz zu starten, kann die automatische Skalierung des Computepools ausgelöst werden. Weitere Informationen dazu finden Sie unter Automatisches Skalieren von Computepool-Knoten.
Wenn Sie beim Erstellen eines Dienstes die Parameter MAX_INSTANCES und MIN_INSTANCES angeben, aber in der Dienstspezifikationsdatei Ihrer Dienstinstanz keine Arbeitsspeicher- und CPU-Anforderungen spezifiziert sind, erfolgt keine automatische Skalierung. Snowflake beginnt dann mit der durch die Eigenschaft MIN_INSTANCES angegebenen Anzahl von Instanzen und führt keine automatische Skalierung durch.
Dienste auflisten¶
Sie können verschiedene SHOW SERVICES-Befehle verwenden, um die aktuellen Dienste aufzulisten:
SHOW SERVICES: Listet die Dienste in der aktuellen Datenbank und im aktuellen Schema auf, für die Sie Berechtigungen haben.
SHOW SERVICES IN ACCOUNT: Listet die Dienste in Ihrem Snowflake-Konto auf, unabhängig davon, zu welcher Datenbank oder welchem Schema die Dienste gehören. Dies ist nützlich, wenn Sie Snowflake-Dienste in mehreren Datenbanken und Schemas Ihres Kontos erstellt haben. Wie alle anderen Befehle ist auch SHOW SERVICES IN ACCOUNTS von den Berechtigungen abhängig und gibt nur die Dienste zurück, für die die von Ihnen verwendete Rolle über Anzeigeberechtigungen verfügt.
SHOW SERVICES IN SCHEMA: Listet die Dienste im angegebenen Schema auf.
Das Auflisten von Diensten in einem bestimmten Computepool ist ein zweistufiger Prozess:
Führen Sie SHOW SERVICES aus, um eine Liste der Dienste zu erhalten.
Durchsuchen Sie die Liste aus der vorherigen Abfrage (mit RESULT_SCAN) nach Diensten in dem spezifischen Computepool.
Beispiel
Im folgenden Beispielskript listet der Befehl SHOW SERVICES zunächst die Dienste in der aktuellen Datenbank und im aktuellen Schema auf, die eine bestimmte Zeichenfolge im Dienstnamen enthalten.
Anschließend filtert die SELECT-Abfrage das Resultset so, dass nur die Dienste im angegebenen Computepool zurückgegeben werden. Beachten Sie, dass die Abfrage die Funktion RESULT_SCAN verwendet, um das Resultset des vorangegangenen SHOW SERVICES-Befehls zu erhalten.
SHOW SERVICES like '%tutorial%' in account;
SELECT *
FROM TABLE(RESULT_SCAN(last_query_id()))
WHERE "compute_pool" = 'TUTORIAL_COMPUTE_POOL';
Überwachen von Diensten¶
Verwenden Sie SYSTEM$GET_SERVICE_STATUS, um den detaillierten Laufzeitstatus eines Dienstes zu erhalten. Sie können diese Funktion zum Beispiel aufrufen, um festzustellen, ob der Dienst noch ausgeführt wird oder ob er nicht gestartet werden konnte. Wenn der Dienst nicht gestartet werden konnte, gibt die Funktion weitere Einzelheiten zu dem Fehler zurück.
Beim Aufrufen dieser Funktion geben Sie den Namen des Dienstes an.
Beispiel
CALL SYSTEM$GET_SERVICE_STATUS('echo_service');
Nachfolgend finden Sie Beispielausgaben für den Befehl:
Beispielausgabe eines Dienstes, der eine Instanz und einen Container hat:
[ { "status":"READY", "message":"Running", "containerName":"echo", "instanceId":"0", "serviceName":"ECHO_SERVICE", "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial", "restartCount":0, "startTime":"2023-01-01T00:00:00Z" } ]
instanceId
ist die Dienstinstanz-ID, zu der der Container gehört. Wenn Sie zwei Instanzen dieses Dienstes ausführen, enthält die Ausgabe zwei solcher Objekte und gibt den Containerstatus für jede Dienstinstanz an. In diesem Fall sind die Instanzen-IDs 0 und 1.Beispielausgabe für einen Dienst, der mit einer Instanz ausgeführt wird und drei Container hat:
[ { "status":"READY", "message":"Running", "containerName":"some-proxy", "instanceId":"0", "serviceName":"example_service", "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_service_image_proxy:tutorial", "restartCount":0, "startTime":"2023-01-01T00:00:00Z" }, { "status":"READY", "message":"Running", "containerName":"some-server", "instanceId":"0", "serviceName":"example_service", "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_server:tutorial", "restartCount":0, "startTime":"2023-01-01T00:00:00Z" }, { "status":"READY", "message":"Running", "containerName":"movies", "instanceId":"0", "serviceName":"example_service", "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_movies:tutorial", "restartCount":0, "startTime":"2023-01-01T00:00:00Z" } ]
Die Ausgabe enthält Statusinformationen für jeden Container. Alle diese Container gehören zu einer einzigen Dienstinstanz, der Instanz mit Instanz-ID 0.
SYSTEM$GET_SERVICE_STATUS kann optional ein Argument timeout_secs
übergeben werden. Wenn timeout_secs
nicht oder mit dem Wert 0 angegeben wird, gibt die Funktion sofort den aktuellen Status zurück. Wenn timeout_secs
angegeben wird, wartet Snowflake, bis der Dienst innerhalb der spezifizierten Zeit einen Endzustand (READY oder FAILED) erreicht hat, bevor es den Dienststatus zurückgibt. Wenn der Dienst den Endzustand nicht innerhalb der spezifizierten Zeit erreicht, gibt Snowflake am Ende des angegebenen Zeitintervalls den aktuellen Status zurück.
Die von Ihnen angegebene Zeitüberschreitung (Timeout) ist ein Näherungswert, der darauf basiert, wann Sie erwarten, dass der Dienst bereit ist. Dies kann dazu beitragen, Situationen zu erkennen, in denen Snowflake darauf wartet, dass andere Dienste und Jobs beendet werden und Ressourcen im angegebenen Computepool freigeben, bevor ein anderer Dienst gestartet wird. Die folgende SYSTEM$GET_SERVICE_STATUS-Funktion spezifiziert ein Timeout von 10 Sekunden:
call SYSTEM$GET_SERVICE_STATUS('echo_service', 10);
Zugriff auf lokale Containerprotokolle¶
Snowflake erfasst alle Daten, die Ihr Code in Ihrem Anwendungscontainer an die Standardausgabe oder die Standardfehler ausgibt. Sie müssen sicherstellen, dass Ihr Code nützliche Informationen zur Fehlersuche in einem Dienst ausgibt.
Snowflake bietet zwei Möglichkeiten, auf diese Containerprotokolle zuzugreifen:
Systemfunktion SYSTEM$GET_SERVICE_LOGS: Ermöglicht den Zugriff auf Protokolle eines bestimmten Containers. Nach dem Beenden eines Containers können Sie noch eine kurze Zeit lang mithilfe der Systemfunktion auf die Protokolleinträge zugreifen. Systemfunktionen sind am nützlichsten während der Entwicklungs- und Testphase, wenn Sie einen neuen Dienst oder Job entwickeln. Weitere Informationen dazu finden Sie unter SYSTEM$GET_SERVICE_LOGS.
Ereignistabelle: Eine Ereignistabelle ermöglicht Ihnen den Zugriff auf Protokolleinträge von mehreren Containern über alle Dienste hinweg. Snowflake speichert die Protokolleinträge in der Ereignistabelle für den späteren Zugriff. Ereignistabellen eignen sich am besten für die rückblickende Analyse von Diensten und Jobs. Weitere Informationen dazu finden Sie unter Verwenden einer Ereignistabelle.
Verwenden von SYSTEM$GET_SERVICE_LOGS¶
Sie geben den Dienstnamen, die Instanz-ID, den Containernamen und optional die Anzahl der letzten Protokollzeilen an, die abgerufen werden sollen. Wenn nur eine Dienstinstanz ausgeführt wird, ist die Dienstinstanz-ID 0. Der folgende GET_SERVICE_LOGS-Befehl ruft beispielsweise die letzten 10 Zeilen aus dem Protokoll eines Containers namens echo
ab, der zur Instanz 0 eines Dienstes namens echo_service
gehört:
CALL SYSTEM$GET_SERVICE_LOGS('echo_service', '0', 'echo', 10);
Wenn Sie die Dienstinformationen nicht kennen (z. B. die Instanz-ID oder den Containernamen), können Sie zunächst GET_SERVICE_STATUS ausführen, um Informationen zu den in jeder Instanz ausgeführten Dienstinstanzen und Containern zu erhalten.
Beispielausgabe:
+--------------------------------------------------------------------------+
| SYSTEM$GET_SERVICE_LOGS |
|--------------------------------------------------------------------------|
| 10.16.6.163 - - [11/Apr/2023 21:44:03] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:08] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:13] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:18] "GET /healthcheck HTTP/1.1" 200 - |
+--------------------------------------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.878s
Die Ausgabe von SYSTEM$GET_SERVICE_LOGS hat die folgenden Einschränkungen:
Sie führt einfach die Standardausgabe- und Standardfehlerstreams zusammen, wodurch es unmöglich ist, zwischen regulären Ausgaben und Fehlermeldungen zu unterscheiden.
Sie berichtet die erfassten Daten für einen bestimmten Container in einer einzigen Dienstinstanz.
Sie werden nur Protokolle für einen in Ausführung befindlichen Container berichtet. Die Funktion kann keine Protokolle von einem früheren Container abrufen, der neu gestartet wurde, oder von einem Container eines Dienstes, der angehalten oder gelöscht wurde.
Die Funktion gibt bis zu 100 KB an Daten zurück.
Verwenden einer Ereignistabelle¶
Snowflake kann Standardausgaben und Standardfehler von Ihren Containern erfassen und in der für Ihr Konto konfigurierten Ereignistabelle erfassen. Weitere Informationen dazu finden Sie unter Übersicht zu Protokollierung und Ablaufverfolgung.
Die folgende SELECT-Abfrage ruft beispielsweise Dienst- und Job-Ereignisse in Snowflake ab, die in der letzten Stunde erfasst wurden:
SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD_ATTRIBUTES, VALUE
FROM <current-event-table-for-your-account>
WHERE timestamp > dateadd(hour, -1, current_timestamp())
AND RESOURCE_ATTRIBUTES:"snow.executable.type" = 'SnowparkContainers'
ORDER BY timestamp DESC
LIMIT 10;
Snowflake empfiehlt, einen Zeitstempel in die WHERE-Klausel von Ereignistabellenabfragen aufzunehmen, wie in diesem Beispiel gezeigt. Dies ist besonders wichtig wegen der potenziellen Datenmenge, die von verschiedenen Snowflake-Komponenten generiert wird. Durch die Anwendung von Filtern können Sie eine kleinere Teilmenge von Daten abrufen, was die Abfrageleistung verbessert.
Sie steuern die Ebene der Protokolleinträge (alle oder nur Fehler oder keine), die in einer Ereignistabelle gespeichert werden sollen, indem Sie das Feld spec.logExporters in der Dienstspezifikationsdatei verwenden.
Die Ereignistabelle enthält die folgenden Spalten, die nützliche Informationen zu den von Snowflake erfassten Protokolleinträgen zu Ihrem Container bereitstellen:
TIMESTAMP: Zeigt an, wann Snowflake das Protokoll erfasst hat.
RESOURCE_ATTRIBUTES: Jedes Objekt in dieser Spalte gibt an, welcher Snowflake-Dienst und -Container des Dienstes den Protokolleintrag generiert hat. Er gibt beispielsweise Details wie den Dienstnamen, den Containernamen und den Namen des Computepools an, die bei Ausführung des Dienstes angegeben wurden.
{ "snow.containers.compute_pool.id": 549816068, "snow.containers.compute_pool.name": "TUTORIAL_COMPUTE_POOL", "snow.containers.container.name": "echo", "snow.containers.instance.name": "0", "snow.containers.restart.id": "cd0cf2", "snow.database.id": 549816076, "snow.database.name": "TUTORIAL_DB", "snow.executable.id": 980991015, "snow.executable.name": "ECHO_SERVICE", "snow.executable.type": "SnowparkContainers", "snow.schema.id": 549816076, "snow.schema.name": "DATA_SCHEMA" }
RECORD_ATTRIBUTES: Gibt für einen Snowflake-Dienst die Fehlerquelle an (Standardausgabe oder Standardfehler).
{ "log.iostream": "stdout" }
VALUE: Standardausgabe und Standardfehler sind in Zeilen unterteilt, und jede Zeile generiert einen Datensatz in der Ereignistabelle.
"echo-service [2023-10-23 17:52:27,429] [DEBUG] Sending response: {'data': [[0, 'Joe said hello!']]}"
Konfigurieren einer Ereignistabelle¶
Weitere Informationen dazu finden Sie unter Übersicht zu Protokollierung und Ablaufverfolgung.
Verwenden eines Dienstes¶
Sie können einer Rolle die Berechtigung zur Nutzung von zukünftigen Diensten (noch nicht erstellte Dienste) erteilen. Beispiel:
GRANT USAGE ON FUTURE SERVICES IN [DATABASE <name> | SCHEMA <name>]TO ROLE <name>
Nachdem Sie einen Dienst erstellt haben, können Sie eine der folgenden drei unterstützten Methoden verwenden, um mit ihm zu kommunizieren:
Dienstfunktion: Erstellen Sie eine Dienstfunktion (UDF), die dem Dienst zugeordnet ist. Verwenden Sie dann die Dienstfunktion zur Kommunikation mit einem Dienst aus einer SQL-Abfrage. Ein Beispiel dazu finden Sie unter Tutorial 1.
Dateneingang: Verwenden Sie öffentliche Endpunkte, die vom Dienst bereitgestellt werden, um von außerhalb von Snowflake auf den Dienst zuzugreifen. In diesem Fall verwaltet Snowflake die Zugriffssteuerung. Ein Beispiel dazu finden Sie unter Tutorial 1.
Dienst-zu-Dienst-Kommunikation: Verwenden Sie einen von Snowflake zugewiesenen DNS-Dienstnamen für die Kommunikation zwischen Diensten. Ein Beispiel dazu finden Sie unter Tutorial 3.
Die folgenden Abschnitte enthalten weitere Details.
Dienstfunktionen: Verwenden eines Dienstes aus einer SQL-Abfrage¶
Eine Dienstfunktion ist eine benutzerdefinierte Funktion (UDF), die Sie mit CREATE FUNCTION erstellen. Anstatt jedoch den UDF-Code direkt zu schreiben, verknüpfen Sie die UDF mit Ihrem Dienst. In Tutorial 1 erstellen Sie beispielsweise einen Dienst namens echo_service
, der einen Endpunkt (echoendoint) gemäß der Definition in der Dienstspezifikation bereitstellt:
spec:
…
endpoints:
- name: echoendpoint
port: 8080
echoendpoint
ist ein benutzerfreundlicher Endpunktname, der den entsprechenden Port (8080) darstellt. Um mit diesem Dienstendpunkt zu kommunizieren, erstellen Sie eine Dienstfunktion, indem Sie die Parameter SERVICE und ENDPOINT wie gezeigt angeben:
CREATE FUNCTION my_echo_udf (text varchar)
RETURNS varchar
SERVICE=echo_service
ENDPOINT=echoendpoint
AS '/echo';
Der Parameter AS
stellt den HTTP-Pfad zum Dienstcode bereit. Sie erhalten diesen Pfadwert aus dem Dienstcode (siehe z. B. „service.py“ in Tutorial 1).
@app.post("/echo")
def echo():
...
Wenn Sie die Dienstfunktion aufrufen, leitet Snowflake die Anforderung an den zugehörigen Dienstendpunkt und -pfad weiter.
Bemerkung
Eine Dienstfunktion wird zur Kommunikation mit einem Dienst, aber nicht mit einem Job verwendet. Mit anderen Worten: Sie können nur einen Dienst (keinen Job) mit einer Dienstfunktion verknüpfen.
Wenn Sie mehrere Instanzen Ihres Dienstes ausführen, können Sie eine Dienstfunktion erstellen, indem Sie den optionalen Parameter MAX_BATCH_ROWS
angeben, um die Batchgröße zu begrenzen, d. h. die maximale Anzahl von Zeilen, die Snowflake in einem Batch an den Dienst sendet. Angenommen, MAX_BATCH_ROWS
ist 10 und Sie rufen die Dienstfunktion my_echo_udf
mit 100 Eingabezeilen auf. Snowflake unterteilt die Eingabezeilen in Batches, wobei jeder Stapel höchstens 10 Zeilen enthält, und sendet eine Serie von Anforderungen an den Dienst mit dem Batch von Zeilen im Anforderungstext. Die Konfiguration der Batchgröße kann hilfreich sein, wenn die Verarbeitung eine nicht unerhebliche Zeit in Anspruch nimmt, und das Verteilen der Zeilen auf alle verfügbaren Server kann ebenfalls hilfreich sein.
Sie können ALTER FUNCTION verwenden, um eine Dienstfunktion zu ändern. Der folgende ALTER FUNCTION-Befehl ändert den Dienstendpunkt, mit dem er verknüpft ist, und die Batchgröße:
ALTER FUNCTION my_echo_udf(VARCHAR)
SET SERVICE=other_service
ENDPOINT=otherendpoint
MAX_BATCH_ROWS=100
Datenaustauschformat¶
Beim Datenaustausch zwischen einer Dienstfunktion und einem Container folgt Snowflake demselben Format, das auch externe Funktionen verwenden (siehe Datenformate). Angenommen, Sie haben Datenzeilen in einer Tabelle (input_table
) gespeichert:
"Alex", "2014-01-01 16:00:00"
"Steve", "2015-01-01 16:00:00"
…
Um diese Daten an Ihren Dienst zu senden, rufen Sie die Dienstfunktion auf, indem Sie diese Zeilen als Parameter übergeben:
SELECT service_func(col1, col2) FROM input_table;
Snowflake sendet eine Reihe von Anforderung an den Container, wobei die Batches von Datenzeilen im Anforderungstext in diesem Format vorliegen:
{
"data":[
[
0,
"Alex",
"2014-01-01 16:00:00"
],
[
1,
"Steve",
"2015-01-01 16:00:00"
],
…
[
<row_index>,
"<column1>",
"<column2>"
],
]
}
Der Container gibt dann die Ausgabe in folgendem Format zurück:
{
"data":[
[0, "a"],
[1, "b"],
…
[ row_index, output_column1]
]
}
Die gezeigte Beispielausgabe geht davon aus, dass das Ergebnis eine einspaltige Tabelle mit Zeilen („a“, „b“ …) ist.
Wenn mehrere Dienstinstanzen ausgeführt werden, können Sie eine Dienstfunktion mit dem Parameter MAX_BATCH_ROWS
erstellen, um die Eingabezeilen für die Verarbeitung auf alle verfügbaren Server zu verteilen.
Erforderliche Berechtigungen zum Erstellen und Verwalten von Dienstfunktionen¶
Um Dienstfunktionen zu erstellen und zu verwalten, benötigt eine Rolle die folgenden Berechtigungen:
Erstellen einer Dienstfunktion: Die aktuelle Rolle muss die Berechtigung USAGE für den Dienst haben, auf den verwiesen wird.
Ändern einer Dienstfunktion: Sie können eine Dienstfunktion ändern und sie mit einem anderen Dienst verknüpfen. Die aktuelle Rolle muss die Berechtigung USAGE für den neuen Dienst haben.
Verwenden einer Dienstfunktion: Die aktuelle Rolle muss die USAGE-Berechtigung für die Dienstfunktion haben, und die Eigentümerrolle der Dienstfunktion muss die USAGE-Berechtigung für den zugehörigen Dienst haben.
Das folgende Beispielskript zeigt, wie Sie die Berechtigung zum Verwenden einer Dienstfunktion erteilen können:
USE ROLE service_owner;
GRANT USAGE ON service service_db.my_schema.my_service TO ROLE func_owner;
USE ROLE func_owner;
CREATE OR REPLACE test_udf(v VARCHAR)
RETURNS VARCHAR
SERVICE=service_db.my_schema.my_service
ENDPOINT=endpointname1
AS '/run';
SELECT test_udf(col1) FROM some_table;
ALTER FUNCTION test_udf(VARCHAR) SET
SERVICE = service_db.other_schema.other_service
ENDPOINT=anotherendpoint;
GRANT USAGE ON FUNCTION test_udf(varchar) TO ROLE func_user;
USE ROLE func_user;
SELECT my_test_udf('abcd');
Dateneingang: Verwenden eines Dienstes von außerhalb von Snowflake¶
Ein Dienst kann einen oder mehrere Endpunkte als öffentlich bereitstellen, damit Benutzer den Dienst über das öffentliche Web nutzen können.
Bemerkung
Für die öffentliche private Vorschau muss der ACCOUNTADMIN Ihres Snowflake-Kontos den folgenden Befehl ausführen:
CREATE SECURITY INTEGRATION SNOWSERVICES_INGRESS_OAUTH
TYPE=oauth
OAUTH_CLIENT=snowservices_ingress
ENABLED=true;
Markieren Sie den Endpunkt in Ihrer Dienstspezifikationsdatei als öffentlich:
spec
...
endpoints
- name: <endpoint name>
port: <port number>
public: true
Weitere Informationen zu Dienstspezifikationen finden Sie unter Referenz der Dienstspezifikation.
Zugriff auf öffentliche Endpunkte und Authentifizierung¶
Snowpark Container Services benötigt Snowflake OAuth zum Authentifizieren von Anforderungen an öffentliche Endpunkte. Sie müssen sich zum Beispiel mit Benutzername und Kennwort anmelden. Im Hintergrund generiert Ihre Anmeldung ein OAuth-Token von Snowflake. Das OAuth-Token wird dann verwendet, um eine Anforderung an den Dienstendpunkt zu senden.
Bemerkung
Da Snowpark-Container Snowflake OAuth zum Aktivieren der Dateneingabe verwendet, kann die Standardrolle des Benutzers keine der berechtigten Rollen sein, einschließlich ACCOUNTADMIN, SECURITYADMIN und ORGADMIN. Weitere Informationen dazu finden Sie unter Blockieren bestimmter Rollen für die Verwendung der Integration.
Nicht jeder kann auf die von einem Dienst bereitgestellten öffentlichen Endpunkte zugreifen. Nur Benutzer desselben Snowflake-Kontos, die eine Rolle mit der Berechtigung USAGE für einen Dienst haben, können auf die öffentlichen Endpunkte des Dienstes zugreifen.
Sie können auf den öffentlichen Endpunkt über einen Browser oder programmgesteuert zugreifen:
Zugriff auf einen öffentlichen Endpunkt mit einem Browser: Wenn für den Zugriff auf einen öffentlichen Endpunkt ein Browser verwendet wird, erfolgt eine automatische Umleitung für die Benutzerauthentifizierung. Sie können Tutorial 1 ausführen, um diese Erfahrung zu testen.
Programmgesteuerter Zugriff auf einen öffentlichen Endpunkt: Der folgende Python-Beispielcode verwendet den Snowflake-Konnektor für Python, um zunächst ein Sitzungs-Token zu generieren, das Ihre Identität repräsentiert. Der Code verwendet dann das Sitzungs-Token, um sich bei dem öffentlichen Endpunkt anzumelden.
import snowflake.connector import requests ctx = snowflake.connector.connect( user="<username>",# username password="<password>", # insert password here account="<orgname>-<acct-name>", session_parameters={ 'PYTHON_CONNECTOR_QUERY_RESULT_FORMAT': 'json' }) # Obtain a session token. token_data = ctx._rest._token_request('ISSUE') token_extract = token_data['data']['sessionToken'] # Create a request to the ingress endpoint with authz. token = f'\"{token_extract}\"' headers = {'Authorization': f'Snowflake Token={token}'} # Set this to the ingress endpoint URL for your service url = 'http://<ingress_url>' # Validate the connection. response = requests.get(f'{url}', headers=headers) print(response.text) # Insert your code to interact with the application here
Erläuterungen zum Code:
Wenn Sie Ihre Kontoinformationen nicht kennen (
<Organisationsname>-<Kontoname>
), lesen Sie das Tutorial Grundlegende Einrichtung.Sie können den
ingress_url
-Wert des öffentlichen Endpunkts, der vom Dienst bereitgestellt wird, mit SHOW ENDPOINTS abrufen.
Benutzerspezifische Header bei Dateneingangsanforderungen¶
Wenn eine Anforderungen für einen Eingangsendpunkt eingeht, übergibt Snowflake automatisch die folgenden Header zusammen mit der HTTP-Anforderung an den Container.
Sf-Context-Current-User: <user_name> Sf-Context-Current-User-Email: <email>
Der Containercode kann diese Header optional lesen, weiß, wer der Aufrufer ist, und kann kontextspezifische Anpassungen für verschiedene Benutzer vornehmen.
Dienst-zu-Dienst-Kommunikation¶
Dienste können über den DNS-Namen, den Snowflake jedem Dienst automatisch zuweist, miteinander kommunizieren. Ein Beispiel dazu finden Sie unter Tutorial 3.
Das DNS-Namensformat ist:
<service-name>.<schema-name>.<db-name>.snowflakecomputing.internal
Verwenden Sie SHOW SERVICES (oder DESCRIBE SERVICE), um den DNS-Namen eines Dienstes zu erhalten. Der obige DNS-Name ist ein vollständiger Name. Dienste, die im selben Schema erstellt wurden, können nur über den <service-name>
kommunizieren. Dienste, die sich in derselben Datenbank, aber in unterschiedlichen Schemas befinden, müssen den Schemanamen angeben, z. B. <service-name>.<schema-name>
.
Snowflake erlaubt die Netzwerkkommunikation zwischen Diensten, die von der gleichen Rolle erstellt wurden, und blockiert die Netzwerkkommunikation zwischen Diensten, die von verschiedenen Rollen erstellt wurden. Wenn Sie verhindern möchten, dass Ihre Dienste miteinander kommunizieren (z. B. aus Sicherheitsgründen), verwenden Sie verschiedene Snowflake-Rollen, um diese Dienste zu erstellen.
DNS-Namen haben die folgenden Einschränkungen:
Ihre Datenbank-, Schema- oder Dienstnamen müssen gültige DNS-Bezeichnungen sein. (Siehe auch https://www.ietf.org/rfc/rfc1035.html#section-2.3.1). Andernfalls wird das Erstellen eines Dienstes fehlschlagen.
Snowflake ersetzt einen Unterstrich (_) in den Namen (Datenbank-, Schema- und Dienstname) im DNS-Namen durch einen Bindestrich (-).
Ändern Sie nach dem Erstellen eines Dienstes nicht die Datenbank oder den Schemanamen, da Snowflake den DNS-Namen des Dienstes nicht aktualisiert.
Ein DNS-Name dient nur der internen Kommunikation innerhalb von Snowflake zwischen Diensten, die in demselben Konto ausgeführt werden. Er ist nicht über das Internet zugänglich.
Aktualisieren des Codes für Ihren Dienst¶
Nachdem Sie einen Dienst erstellt haben, verwenden Sie ALTER SERVICE, um den Dienstcode zu aktualisieren. Sie laden zunächst den geänderten Anwendungscode in Ihr Image-Repository hoch und rufen dann ALTER SERVICE auf, wobei Sie die Dienstspezifikation entweder inline oder unter Angabe des Pfads zu einer Spezifikationsdatei in einem Snowflake-Stagingbereich bereitstellen. Beispiel:
Geben Sie die Spezifikation inline an (eine Teilspezifikation wird angezeigt).
ALTER SERVICE echo_service FROM SPECIFICATION $$ spec: … … $$;
Geben Sie den Dateipfad zur Snowflake-Stagingdatei an:
ALTER SERVICE echo_service FROM @tutorial_stage SPECIFICATION_FILE='echo_spec.yaml';
Nach Erhalt der Anforderung stellt Snowflake den Dienst mit dem neuen Code erneut bereit.
ALTER SERVICE verwendet immer die aktuellste Version des Images aus Ihrem Repository. Wenn Sie beispielsweise mehrere Versionen eines Bildes mit den Namen „echo_service:latest“ oder „echo_service:sometag“ hochladen, verwendet Snowflake die zuletzt hochgeladene Image-Version.
Sie können den DESCRIBE SERVICE-Befehl verwenden, um die Image-Version zu ermitteln, die der Dienst ausführt. Wenn Sie der Eigentümer des Dienstes sind, enthält die DESCRIBE SERVICE-Ausgabe die Dienstspezifikation, in der Sie den Image-Digest (SHA256 des Images) erhalten. Beispiel:
spec:
containers:
- name: "echo"
image: "orgname-acctname.registry-dev.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest"
sha256: "@sha256:8d912284f935ecf6c4753f42016777e09e3893eed61218b2960f782ef2b367af"
env:
SERVER_PORT: "8000"
CHARACTER_NAME: "Bob"
readinessProbe:
port: 8000
path: "/healthcheck"
endpoints:
- name: "echoendpoint"
port: 8000
public: true
Bemerkung
Wenn Sie einen Dienst anhalten und fortsetzen, stellt Snowflake dieselbe Image-Version bereit, es handelt sich nicht um eine Aktualisierungsoperation des Dienstes.
Berechtigungen¶
Berechtigung |
Verwendung |
Anmerkungen |
---|---|---|
USAGE |
Ermöglicht die Kommunikation mit einem Dienst. Erforderlich für das Erstellen einer Dienstfunktion, die Verwendung öffentlicher Endpunkte und die Verbindung von einem anderen Dienst aus. |
|
MONITOR |
Ermöglicht das Überwachen eines Dienstes und das Abrufen des Laufzeitstatus. |
|
OPERATE |
Ermöglicht das Anhalten oder Fortsetzen einer Aufgabe. |
|
OWNERSHIP |
Ermöglicht die volle Kontrolle über den Dienst. Diese Berechtigung kann für ein bestimmtes Objekt immer nur einer Rolle erteilt sein. |
|
ALL [ PRIVILEGES ] |
Ermöglicht das Erteilen aller Berechtigungen für den Dienst, außer OWNERSHIP. |