Plattformunabhängige Informationen zum Erstellen externer Funktionen

Ein Großteil der Informationen zur Entwicklung eines Proxydienstes und eines Remotedienstes sind plattformabhängig. Es gibt jedoch viele zusätzliche Details, die plattformunabhängig sind. Dieses Thema konzentriert sich auf Details, die plattformunabhängig sind. Es sind jedoch einige plattformspezifische Informationen enthalten.

Unter diesem Thema:

Remotedienst

Dateiformat

Snowflake ruft eine Ressource in einem Proxydienst auf, indem eine HTTP-POST-Anforderung ausgeführt wird. Die POST-Anforderung enthält Daten in einem bestimmten Format sowie bestimmte Header.

Die vom Remotedienst zurückgegebenen Daten müssen ebenfalls einem bestimmten Format entsprechen.

Nachfolgend wird sowohl das Format, das von Snowflake gesendet wird, als auch das Format, das an Snowflake zurückgesendet wird, beschrieben.

Beachten Sie auch die Bedeutung der Verwendung kompatibler Datentypen sowohl beim Sender als auch beim Empfänger von POST. Weitere Details dazu finden Sie unter Sicherstellen, dass Argumente der externen Funktion den Argumenten des Remotedienstes entsprechen.

Von Snowflake gesendetes Datenformat

Jede HTTP-Anforderung von Snowflake ist ein POST oder ein GET.

Eine POST-Anforderung enthält Header und einen Anforderungstext. Der Anforderungstext enthält einen Batch von Zeilen.

Ein GET enthält nur Header und wird nur für das Abrufen verwendet, wenn der Remotedienst Ergebnisse asynchron zurückgibt.

Die Header-Informationen stehen dem Remotedienst in der Regel als ein Satz von Schlüssel/Wert-Paaren zur Verfügung. Zu diesen Header-Informationen gehören:

  • Es gibt folgende HTTP-Header:

    • Header, die beschreiben, wie Daten im Body der Anforderung serialisiert sind:

      • „sf-external-function-format“: Dies ist derzeit immer auf „json“ eingestellt.

      • „sf-external-function-format-version“: Dies ist derzeit immer auf „1.0“ eingestellt.

    • „sf-external-function-current-query-id“: Enthält die Abfrage-ID der Abfrage, die diese externe Funktion aufgerufen hat. Sie können diesen Header verwenden, um Snowflake-Abfragen mit Aufrufen des Remotedienstes zu korrelieren, um beispielsweise Probleme zu beheben.

    • „sf-external-function-query-batch-id“: Die Batch-ID ermöglicht die eindeutige Identifizierung des spezifischen Batches von Zeilen, die mit dieser Anforderung verarbeitet werden. Der Remotedienst kann diese ID verwenden, um den Status eines in Bearbeitung befindlichen Batches zu verfolgen. Die ID kann auch als Idempotenztoken verwendet werden, wenn Anforderungen aufgrund eines Fehlers erneut gesendet werden. Die ID kann auch für die Protokollierung/Ablaufverfolgung von Anforderungen durch den Remotedienst verwendet werden.

      Die Batch-ID in einem GET ist die gleiche wie die Batch-ID in dem zugehörigen POST.

      Die Batch-ID ist ein nicht transparenter Wert, der von Snowflake generiert wird. Das Format kann sich in zukünftigen Versionen ändern, sodass sich die Remotedienste nicht auf ein bestimmtes Format verlassen oder versuchen sollten, den Wert zu interpretieren.

    • Header, die die Signatur (Name und Argumenttypen) und den Rückgabetyp der externen Funktion beschreiben, die in der SQL-Abfrage aufgerufen wurde. Diese Werte können Zeichen enthalten, die keine Standardzeichen für Snowflake-Bezeichner sind. Daher sind Base64-Versionen der Informationen enthalten, und Nicht-Standardzeichen werden in den Nicht-Base64-Versionen durch ein Leerzeichen ersetzt. Die spezifischen Header sind:

      • sf-external-function-name

      • sf-external-function-name-base64

      • sf-external-function-signature

      • sf-external-function-signature-base64

      • sf-external-function-return-type

      • sf-external-function-return-type-base64

      Die für die Funktion ext_func(n integer)  returns varchar gesendeten Header sind zum Beispiel:

      • sf-external-function-name: ext_func

      • sf-external-function-name-base64: <Base64-Wert>

      • sf-external-function-signature: (N NUMBER)

      • sf-external-function-signature-base64: <Base64-Wert>

      • sf-external-function-return-type: VARCHAR(16777216)

      • sf-external-function-return-type-base64: <Base64-Wert>

      Beachten Sie, dass das vom Typ INTEGER deklarierte SQL-Argument als Typ NUMBER beschrieben wird, da SQL INTEGER-Werte wie SQL NUMBER-Wert behandelt werden.

  • Zusätzliche optionale Metadaten, die in den Eigenschaften „headers“ und „context_headers“ von CREATE EXTERNAL FUNCTION beschrieben sind.

Um beispielsweise den Header „sf-external-function-signature“ aus dem Inneren einer AWS Lambda-Funktion zu extrahieren, die in Python geschrieben ist und die die Header als Python-Wörterbuch empfängt, führen Sie Folgendes aus:

def handler(event, context):

    request_headers = event["headers"]
    signature = request_headers["sf-external-function-signature"]

Die Details werden sich für andere Sprachen und andere Cloudplattformen unterscheiden.

(Für Remotedienste, die auf AWS entwickelt wurden, finden Sie weitere Informationen zu Header und Lambda-Proxyintegration in der API Gateway-Dokumentation.)

Der Textköper der POST-Anforderung enthält die Daten, die im JSON-Format serialisiert sind. Das Schema für JSON lautet:

  • Die oberste Ebene ist ein JSON-Objekt (eine Menge von Name/Wert-Paaren, auch „Wörterbuch“ oder „Dictionary“ genannt).

  • Derzeit gibt es genau einen Eintrag im Wörterbuch. Der Schlüssel für dieses Element heißt „data“.

  • Der Wert dieses „data“-Elements ist ein JSON-Array, in dem jedes Array-Element eine Datenzeile ist.

  • Jede Datenzeile ist ein JSON-Array aus einer oder mehreren Spalten.

  • Die erste Spalte ist immer die Zeilennummer (d. h. der 0-basierte Index der Zeile innerhalb des Batches).

  • Die verbleibenden Spalten enthalten die Argumente für die Funktion.

  • Datentypen werden wie folgt serialisiert:

    • Nummern werden als JSON-Nummern serialisiert.

    • Boolesche Werte werden als Boolesche JSON-Werte serialisiert.

    • Zeichenfolgen werden als JSON-Zeichenfolgen serialisiert.

    • Variant-Werte werden als JSON-Objekte serialisiert.

    • Alle anderen unterstützten Datentypen werden als JSON-Zeichenfolgen serialisiert.

    • NULL wird als JSON-Null serialisiert.

Hier ist ein Beispiel für eine serialisierte Anforderung für eine externe Funktion mit der Signatur f(integer, varchar, timestamp). Beachten Sie, dass die erste Spalte die Zeilennummer innerhalb des Batches ist und die nächsten drei Werte die Argumente für die externe Funktion sind.

{
    "data": [
                [0, 10, "Alex", "Wed, 01 Jan 2014 16:00:00 -0800"],
                [1, 20, "Steve", "Wed, 01 Jan 2015 16:00:00 -0800"],
                [2, 30, "Alice", "Wed, 01 Jan 2016 16:00:00 -0800"],
                [3, 40, "Adrian", "Wed, 01 Jan 2017 16:00:00 -0800"]
            ]
}

Beispiele für das Extrahieren von Daten finden Sie in der Dokumentation zum Erstellen eines Remotedienstes auf der jeweiligen Plattform:

Optional können JSON-Daten für die Übertragung über das Netzwerk komprimiert werden. Die Komprimierung ist in CREATE EXTERNAL FUNCTION dokumentiert.

Snowflake sendet diese Daten an den Proxydienst und nicht direkt an den Remotedienst. Daher muss der Proxydienst Daten in einem Snowflake-kompatiblen Format empfangen (und zurückgeben). Obwohl der Proxydienst normalerweise Daten unverändert weiterleitet, kann der Proxy zu sendende und zu empfangende Daten neu formatieren, um die Anforderungen sowohl des Remotedienstes als auch von Snowflake zu erfüllen.

Der Einfachheit halber und zur Veranschaulichung der Formate, die Snowflake voraussichtlich senden und empfangen wird, wird in den meisten Beispielen in diesem Abschnitt davon ausgegangen, dass der Remotedienst Daten im gleichen Format liest und schreibt, das Snowflake erwartet, und dass der Proxydienst Daten unverändert in beide Richtungen weiterleitet.

Von Snowflake empfangenes Datenformat

Wenn der Remotedienst die Verarbeitung eines Batches abgeschlossen hat, sollte der Remotedienst Daten in einem Format an Snowflake senden, das dem Format der von Snowflake gesendeten Daten ähnelt. Der zurückgegebene Wert hat das JSON-Format. Hier ist ein Beispiel für den Datenteil einer solchen Antwort:

{
    "data":
        [
            [ 0, 1995 ],
            [ 1, 1974 ],
            [ 2, 1983 ],
            [ 3, 2001 ]
        ]
}

Die an Snowflake zurückgegebene JSON-Antwort sollte eine Zeile für jede von Snowflake gesendete Zeile enthalten. Jede zurückgegebene Zeile enthält zwei Werte:

  • Die Zeilennummer (d. h. der 0-basierte Index der Zeile innerhalb des Batches).

  • Der von der Funktion für diese Zeile zurückgegebene Wert. Der Wert kann ein zusammengesetzter Wert sein (z. B. ein VARIANT), muss jedoch genau ein Wert sein, da alle skalaren Snowflake-Funktionen (extern oder anderweitig) einen einzelnen Wert zurückgeben.

Die Zeilennummern in den zurückgegebenen Daten müssen den Zeilennummern in den von Snowflake gesendeten Daten entsprechen und in derselben Reihenfolge zurückgegeben werden, in der sie empfangen wurden.

Die Antwort enthält außerdem einen HTTP-Statuscode. Snowflake erkennt die folgenden HTTP-Statuscodes:

Code

Beschreibung

200

Batch erfolgreich verarbeitet.

202

Batch erhalten und noch in Bearbeitung.

Andere Werte werden als Fehler behandelt.

Diese Liste der Statuscodes wird im Laufe der Zeit möglicherweise erweitert.

Die Antwort kann auch die folgenden optionalen HTTP-Header enthalten:

  • Content-MD5: Snowflake verwendet den optionalen Content-MD5-Header, um die Integrität der Antwort zu prüfen. Wenn dieser Header in der Antwort enthalten ist, berechnet Snowflake eine MD5-Prüfsumme für den Textkörper der Antwort, um sicherzustellen, dass er mit der entsprechenden Prüfsumme im zurückgegebenen Header übereinstimmt. Wenn die Werte nicht übereinstimmen, schlägt die SQL-Abfrage fehl. Die Prüfsumme sollte in einer Base64-Darstellung kodiert werden, bevor sie im Header zurückgegeben wird. Betrachten Sie dazu den Beispielcode unten.

Optional können JSON-Daten für die Übertragung über das Netzwerk komprimiert werden. Die Komprimierung ist in CREATE EXTERNAL FUNCTION dokumentiert.

Weitere Informationen zu Timeouts und Wiederholungsversuchen finden Sie unter Konto für Timeout-Fehler und Berücksichtigen, dass Remotedienst mehr als eine Zeile übergeben kann.

Der folgende Python-Beispielcode gibt eine korrekte Antwort zurück, einschließlich HTTP-Antwortcode, verarbeitete Daten und MD5-Header (der optional ist). (Dies wurde mit Python 3.8 geschrieben.)

Dieses Beispiel basiert auf einer AWS Lambda-Funktion. Einige Codes müssen möglicherweise für andere Plattformen angepasst werden.

import json
import hashlib
import base64

def handler(event, context):

    # The return value should contain an array of arrays (one inner array per input row for a scalar function).
    array_of_rows_to_return = [ ]

    ...

    json_compatible_string_to_return = json.dumps({"data" : array_of_rows_to_return})

    # Calculate MD5 checksum for the response
    md5digest = hashlib.md5(json_compatible_string_to_return.encode('utf-8')).digest()
    response_headers = {
        'Content-MD5' : base64.b64encode(md5digest)
    }

    # Return the HTTP status code, the processed data, and the headers (including the Content-MD5 header).
    return {
        'statusCode': 200,
        'body': json_compatible_string_to_return,
        'headers': response_headers
    }

Best Practices

Die folgenden bewährten Methoden gelten für die meisten externen Funktionen, insbesondere für den Remotedienst-Teil.

Weitere Best Practices finden Sie in den folgenden Dokumenten:

Verwenden Sie, falls verfügbar, die Batch-API des Remotedienstes

Einige Remotedienste bieten sowohl den Batchmodus als auch den Einzelmodus an. Wenn erwartet wird, dass Abfragen, die eine externe Funktion verwenden, mehrere Zeilen senden, dann empfiehlt Snowflake die Verwendung des Batchmodus des Remotedienstes, um die Leistung zu verbessern.

Diese Regel gilt nicht unbedingt in folgenden Situationen:

  • Jede Zeile ist sehr groß (z. B. Hunderte von Kilobytes oder mehr).

  • Der Remotedienst verarbeitet Zeilen anders, wenn sie im Batch empfangen werden, als wenn sie einzeln empfangen werden. (Weitere Details dazu finden Sie unter Eine Zeile nach der anderen verarbeiten.)

Eine Zeile nach der anderen verarbeiten

Um den Netzwerkaufwand zu minimieren, fasst Snowflake normalerweise Zeilen in Batches zusammen, um sie an Remotedienste zu senden. Die Anzahl der Batches und die Größe jedes Batches können variieren.

Darüber hinaus kann die Reihenfolge der Batches variieren, und die Reihenfolge der Zeilen innerhalb eines Batches kann variieren. Selbst wenn die Abfrage eine ORDER BY-Klausel enthält, wird ORDER BY normalerweise angewendet, nachdem die externen Funktionen aufgerufen wurden.

Da die Stapelgröße und die Zeilenreihenfolge nicht garantiert werden können, kann das Schreiben einer Funktion, die einen Wert für eine Zeile zurückgibt, der von einer anderen Zeile in diesem Batch oder früheren Batches abhängt, zu nicht deterministischen Ergebnissen führen.

Snowflake empfiehlt dringend, dass der Remotedienst jede Zeile unabhängig verarbeitet. Der Rückgabewert für jede Eingabezeile sollte nur von dieser Eingabezeile abhängen, nicht von anderen Eingabezeilen. (Derzeit unterstützen externe Funktionen beispielsweise keine Fensterfunktionen.)

Beachten Sie außerdem, dass das Zählen von Batches nicht sinnvoll ist, da die Batchgröße nicht garantiert ist.

Siehe auch Nur zustandslose externe Funktionen verwenden.

Berücksichtigen, dass Remotedienst mehr als eine Zeile übergeben kann

Wenn Snowflake einen Remotedienst anruft, und der Remotedienst die Anforderung empfängt und ein Ergebnis zurückgibt, Snowflake aber das Ergebnis aufgrund eines vorübergehenden Netzwerkproblems nicht empfängt, wiederholt Snowflake möglicherweise die Anforderung. Wenn Snowflake es erneut versucht, sieht der Remotedienst möglicherweise zweimal (oder mehrmals) dieselbe Zeile.

Dies kann zu unerwarteten Effekten führen. Da der Remotedienst beispielsweise für denselben Wert möglicherweise mehrmals aufgerufen wird, weist ein Remotedienst, der eindeutige IDs zuweist, möglicherweise Lücken in der Sequenz dieser IDs auf. In einigen Fällen können solche Effekte reduziert werden, indem die Batch-ID im Feld sf-external-function-query-batch-id des Anforderungskopfs verfolgt wird, um festzustellen, ob ein bestimmter Batch von Zeilen bereits früher verarbeitet wurde. Wenn Snowflake eine Anforderung für einen bestimmten Batch erneut sendet, verwendet Snowflake die gleiche Batch-ID, die zuvor für denselben Batch verwendet wurde.

Bei Rückgabe der folgenden Fehler sendet Snowflake die Anforderung erneut:

  • Alle vorübergehenden Netzwerktransportfehler.

  • Alle Anforderungen, die mit Statuscode 429 fehlschlagen.

  • Alle Anforderungen, die mit Statuscode 5XX fehlschlagen.

Anforderungen werden wiederholt, bis ein Gesamt-Timeout für Wiederholungen erreicht ist. Das Gesamt-Timeout für Wiederholungen kann vom Benutzer nicht konfiguriert werden. Snowflake kann dieses Limit möglicherweise in Zukunft anpassen.

Wenn das Gesamt-Timeout für Wiederholungen ohne erfolgreiche Wiederholung erreicht ist, schlägt die Abfrage fehl.

Wenn der Aufruf Ihrer externen Funktion mit Timeout fehlschlägt, der Remotedienst aber funktioniert, und alle Elemente zwischen Snowflake und dem Remotedienst zu funktionieren scheinen, können Sie eine geringere Batchgröße probieren, um festzustellen, ob dies die Anzahl der Timeout-Fehler verringert.

Eine Anleitung zum Festlegen der maximalen Batchgröße finden Sie unter CREATE EXTERNAL FUNCTION.

Nur zustandslose externe Funktionen verwenden

Im Allgemeinen sollte eine externe Funktion (einschließlich des Remotedienstes) das Speichern von Statusinformationen vermeiden. Dies gilt für:

  • Interner Status (Status, den der Remotedienst intern speichert).

  • Externer Status (Status, der außerhalb des Remotedienstes gespeichert ist, z. B. Statusinformationen, die an einen anderen Remotedienst gesendet und/oder von diesem gelesen werden, der selbst den Status beibehält).

Wenn der Remotedienst Statusinformationen ändert und diese Informationen dann verwendet, um zukünftige Ausgaben zu beeinflussen, gibt die Funktion möglicherweise andere Werte als erwartet zurück.

Stellen Sie sich beispielsweise einen einfachen Remotedienst vor, der einen internen Zähler enthält und die Anzahl der Zeilen zurückgibt, die seit dem ersten Start des Remotedienstes empfangen wurden. Wenn ein vorübergehendes Netzwerkproblem vorliegt und Snowflake eine Anforderung mit denselben Daten wiederholt, zählt der Remotedienst die erneut gesendeten Zeilen zweimal (oder mehrmals).

Ein Beispiel für einen externen Status finden Sie unter Nebeneffekte vermeiden.

In den seltenen Fällen, in denen eine Funktion nicht zustandslos ist, sollte in der Dokumentation deutlich hervorgehoben werden, dass die Funktion nicht zustandslos ist, und die Funktion sollte als „flüchtig“ gekennzeichnet werden.

Wenn ein Remotedienst Anforderungen asynchron verarbeitet, muss der Autor des Remotedienstes den Remotedienst so schreiben, dass ein Status vorübergehend gespeichert und verwaltet werden kann. Der Remotedienst muss z. B. die Batch-ID der HTTP-POST-Anforderung speichern, damit der Remotedienst, wenn ein HTTP-GET mit demselben Batch-ID empfangen wird, den HTTP-Code 202 zurückgeben kann, während der angegebene Batch noch verarbeitet wird.

Beachten Sie, dass eine Abfrage aus verschiedenen Gründen abgebrochen werden kann, was bedeutet, dass es keine Garantie dafür gibt, dass ein abschließender GET eintrifft, nachdem der Remotedienst die Generierung eines Ergebnisses abgeschlossen hat. Remotedienste, die den Status für asynchrone Anforderungen speichern, sollten irgendwann ein Timeout durchführen und diesen internen Status bereinigen. Das optimale Timeout könnte sich in Zukunft ändern, aber derzeit empfiehlt Snowflake, Informationen über asynchrone Anforderungen mindestens 10 Minuten und vorzugsweise 12 Stunden aufzubewahren, bevor sie gelöscht werden.

Nebeneffekte vermeiden

Eine externe Funktion (einschließlich des Remotedienstes) sollte Nebeneffekte wie das Ändern des externen Status (außerhalb des Remotedienstes gespeicherte Informationen) vermeiden.

Wenn der Remotedienst beispielsweise Werte außerhalb des Bereichs an eine Regierungsbehörde meldet, ist dies ein Nebeneffekt.

Nebeneffekte können nützlich sein, aber die Nebeneffekte des Aufrufs einer externen Funktion sind nicht immer vorhersehbar. Angenommen, Sie rufen einen Remotedienst auf, der eine anonymisierte Patientenakte analysiert und eine Diagnose zurückgibt. Angenommen, die Diagnose lautet, dass der Patient eine ansteckende Krankheit hat, dann wird die Diagnose einer Behörde gemeldet, die die Anzahl der Fälle dieser Krankheit zählt. Dies ist ein sinnvoller Nebeneffekt. Er ist jedoch anfällig für folgende Probleme:

  • Befindet sich ein externer Funktionsaufruf in einer Transaktion, die zurückgesetzt wird, werden die Nebenwirkungen nicht zurückgesetzt.

  • Wenn der Remotedienst mehrmals mit derselben Zeile aufgerufen wird (z. B. aufgrund vorübergehender Netzwerkfehler und erneuter Versuche), kann der Nebeneffekt mehrmals auftreten. Im Beispiel wird dann ein infizierter Patient in der Statistik mehrfach gezählt.

Es gibt auch Situationen, in denen eher zu wenige als zu viele Zeilen gezählt werden können.

In den sehr seltenen Fällen, in denen eine Funktion Nebeneffekte hat, sollte in der Dokumentation deutlich benannt werden, welche Nebeneffekte dies sind, und die Funktion sollte als „flüchtig“ gekennzeichnet werden.

Funktion als „Flüchtig“ oder „Unveränderlich“ kategorisieren

Funktionen können als flüchtig oder unveränderlich eingestuft werden. (Mit der Anweisung CREATE EXTERNAL FUNCTION kann der Benutzer angeben, ob die Funktion flüchtig oder unveränderlich ist.)

Damit eine externe Funktion als unveränderlich angesehen werden kann, sollte sie die folgenden Kriterien erfüllen:

  • Bei gleichem Eingabewert gibt die Funktion denselben Ausgabewert zurück. (Während beispielsweise die Funktion SQRT für dieselben Eingabewerte immer dieselben Ausgabewerte zurückgibt, ist dies bei der Funktion CURRENT_TIMESTAMP nicht notwendigerweise so.)

  • Die Funktion hat keine Nebeneffekte.

Wenn eine Funktion diese beiden Kriterien erfüllt, kann Snowflake bestimmte Arten von Optimierungen vornehmen, um die Anzahl der an den Remotedienst gesendeten Zeilen oder Batches zu verringern. (Diese Optimierungen werden im Laufe der Zeit möglicherweise weiterentwickelt und werden hier nicht im Detail beschrieben.)

Snowflake kann Unveränderlichkeit oder Faktoren, die die Unveränderlichkeit beeinflussen (z. B. Nebeneffekte), weder erkennen noch erzwingen. Der Ersteller eines Remotedienstes sollte dokumentieren, ob der Remotedienst die Kriterien für „Unveränderlichkeit“ erfüllt. Wenn ein Remotedienst Nebeneffekte hat, sollte die externe Funktion, die diesen Remotedienst aufruft, als flüchtig gekennzeichnet werden, auch wenn der Funktionsaufruf denselben Ausgabewert für denselben Eingabewert zurückgibt. Wenn Sie nicht sicher sind, ob ein Remotedienst unveränderlich ist, sollte jede externe Funktion, die diesen Remotedienst aufruft, als flüchtig gekennzeichnet werden.

Konto für Timeout-Fehler

Der Aufruf einer externen Funktion hat Auswirkungen auf Snowflake, einen Remotedienst, einen Proxydienst und möglicherweise andere Elemente in der Verarbeitungsabfolge. Keines dieser Elemente weiß, wie lange ein bestimmter Funktionsaufruf dauern soll, daher weiß keines genau, wann das Warten beendet und ein Timeout-Fehler zurückgegeben werden muss. Jeder Schritt kann einen eigenen, unabhängigen Timeoutwert haben. Weitere Informationen zu Timeouts und Wiederholungsversuchen finden Sie unter Konto für Timeout-Fehler und Wiederholungsversuche.

Latenz minimieren

Um die Latenz zu minimieren und die Verarbeitungsleistung externer Funktionen zu verbessern, empfiehlt Snowflake ggf. folgende Maßnahmen:

  • Verwenden Sie das API Gateway auf derselben Cloudplattform derselben Region wie die Snowflake-Instanzen, die es am häufigsten (oder mit der größten Datenmenge) aufrufen.

  • Wenn Sie den Remotedienst selbst geschrieben haben (anstatt einen vorhandenen Dienst zu verwenden), stellen Sie diesen Remotedienst auf derselben Cloudplattform derselben Region bereit, von der aus er aufgerufen wird.

  • Senden Sie so wenige Daten wie möglich. Wenn der Remotedienst beispielsweise Eingabewerte untersucht und nur eine Teilmenge davon verarbeitet, ist es normalerweise effizienter, in SQL zu filtern und nur die relevanten Zeilen an den Remotedienst zu senden, anstatt alle Zeilen an den Remotedienst zu senden und von diesem filtern zu lassen.

    Wenn Sie als weiteres Beispiel eine Spalte verarbeiten, die große semistrukturierte Datenwerte enthält und der Remotedienst nur einen kleinen Teil dieser Datenwerte verarbeitet, ist es normalerweise effizienter, vor der Verarbeitung den relevanten Teil mit Snowflake-SQL zu extrahieren und nur diesen Teil zu senden, anstatt die gesamte Spalte zu senden und das Extrahieren des kleinen Teils vom Remotedienst vornehmen zu lassen.

Externe Funktionen Schritt für Schritt entwickeln und testen

Snowflake empfiehlt, dass Sie vor dem Testen mit Snowflake erst ohne Snowflake testen.

Verwenden Sie in den frühen Phasen der Entwicklung einer externen Funktion die Proxydienst-Konsole der Cloudplattform (z. B. die Amazon API Gateway-Konsole) und die Remotedienst-Entwicklungskonsole (z. B. die AWS Lambda-Konsole), um den Proxydienst und den Remotedienst zu entwickeln und zu testen.

Wenn Sie beispielsweise eine Lambda-Funktion entwickelt haben, sollten Sie diese erst ausführlich über die Lambda-Konsole testen, bevor Sie sie über Snowflake aufrufen.

Das Testen über Proxydienst-Konsole und Remotedienst-Konsole bietet normalerweise die folgenden Vorteile:

  • Die Diagnose von Problemen wird erleichtert, da weniger potenzielle Quellen als Ursache des Problems in Frage kommen und untersucht werden müssen.

  • Das Anzeigen der Datennutzlast bietet möglicherweise hilfreiche Informationen für das Debugging. Snowflake zeigt in Fehlermeldungen keine Ausschnitte der Datennutzlast an. Dies erhöht zwar die Sicherheit, kann jedoch das Debuggen verlangsamen.

  • Snowflake wiederholt HTTP-5xx-Fehler automatisch, was das Debuggen in einigen Situationen langsamer oder schwieriger machen kann.

  • Das Testen über Snowflake verbraucht zusätzlich zu den Credits für die Cloudplattform auch Snowflake-Credits.

Nachdem Sie Remotedienst und Proxydienst so häufig wie möglich ohne Snowflake getestet haben, sollten Sie die Dienste natürlich auch mit Snowflake testen. Die Testen mit Snowflake bietet folgende Vorteile:

  • Sie testen alle Schritte der externen Funktion.

  • Die Verwendung einer Snowflake-Tabelle als Datenquelle erleichtert das Testen mit großen Datenmengen, um eine realistische Schätzung der Leistung der externen Funktion zu erhalten.

Betrachten Sie die folgenden Testfälle:

  • NULL-Werte

  • „Leere“ Werte (z. B. leere Zeichenfolgen, leere semistrukturierte Datentypen).

  • Gegebenenfalls sehr große VARCHAR- und BINARY-Werte.

Zu asynchronem Remotedienst wechseln

Wenn Sie einen Remotedienst schreiben und dieser möglicherweise nicht innerhalb des erwarteten Timeouts Ergebnisse zurückgibt, sollten Sie erwägen, Ihren Remotedienst asynchron auszuführen. Weitere Details dazu finden Sie unter Asynchrone externe Funktionen erstellen.

Sicherstellen, dass Argumente der externen Funktion den Argumenten des Remotedienstes entsprechen

Achten Sie beim Übergeben von Argumenten an oder von einer externen Funktion darauf, dass die passenden Datentypen verwendet werden. Wenn der gesendete Wert nicht zum Datentyp des Empfängers passt, wird der Wert möglicherweise abgeschnitten oder beschädigt, oder der Remotedienstaufruf schlägt fehl.

Da z. B. einige numerische Datentypen von Snowflake SQL größere Werte speichern können als häufig verwendete JavaScript-Datentypen, ist die Deserialisierung großer Zahlen von JSON in JavaScript besonders empfindlich.

Wenn Sie Ihren eigenen Remotedienst schreiben und die Anzahl, die Datentypen oder die Reihenfolge der Argumente für den Remotedienst ändern, müssen Sie die entsprechenden Änderungen auch an der externen Funktion vornehmen. Derzeit verfügt der Befehl ALTER EXTERNAL FUNCTION nicht über eine Option zum Ändern von Parametern. Sie müssen daher die externe Funktion löschen und neu erstellen, um die Argumente zu ändern.

Proxydienst

Proxydienst-Endpunkt sichern

Snowflake empfiehlt dringend die Sicherung Ihrer Proxydienst-Endpunkte.

Snowflake verwendet API-Integrationsobjekte ohne Anmeldeinformationen, um sich beim Proxydienst-Endpunkt zu authentifizieren. API-Integrationen ohne Anmeldeinformationen sorgen dafür, dass Verantwortlichkeiten zwischen Administratoren und Benutzern aufgeteilt werden. Durch eine API-Integration kann ein Administrator mithilfe des nativen Authentifizierungs- und Autorisierungsmechanismus des Cloudanbieters eine Vertrauensrichtlinie zwischen Snowflake und dem Cloudanbieter erstellen. Wenn Snowflake eine Verbindung zum Cloudanbieter herstellt, authentifiziert und autorisiert der Cloudanbieter den Zugriff über diese Vertrauensrichtlinie. Mithilfe einer speziellen API-Integration kann der Administrator auch einschränken, welche Proxydienste und Ressourcen Snowflake verwenden kann, sodass der Administrator Organisationsrichtlinien für den Datenausgang und -eingang durchsetzen kann.

Detaillierte Anleitungen zum Sichern bestimmter Proxydienst-Endpunkte, z. B. eines Amazon API Gateways, finden Sie in den plattformspezifischen Anweisungen.