外部関数の概念¶
このトピックでは、外部関数がどのように機能するかについての概要を説明します。
このトピックの内容:
外部関数のしくみ¶
概要¶
Snowflakeはリモートサービスを直接呼び出しません。代わりに、Snowflakeは、クラウドプロバイダーのネイティブ HTTPS プロキシサービス(たとえば、AWS 上の API Gateway)を介してリモートサービスを呼び出します。
外部関数を呼び出す主なステップは次のとおりです。
ユーザーのクライアントプログラムは、Snowflakeに外部関数を呼び出す SQL ステートメントを渡します。
クエリ実行の一部として外部関数を評価するとき、Snowflakeは、プロキシサービスの URL とそのプロキシサービスの認証情報を含む API 統合の名前を含む外部関数定義を読み取ります。
Snowflakeは API 統合から情報を読み取り、次を含む HTTP POST リクエストを作成します。
HTTP ヘッダー情報。(詳細は、 CREATE EXTERNAL FUNCTION に記載。)
処理するデータ。このデータは JSON 形式です。
使用するプロキシサービスの「リソース」。リソースには、そのサービスの場所など、リモートサービスに関する情報が含まれています。
そのプロキシサービスリソースの認証情報。
POST リクエストがプロキシサービスに送信されます。
プロキシサービスは POST を受信し、リクエストを処理して実際のリモートサービスに転送します。プロキシサービスとリソースは、リモートサービスを呼び出す「リレー機能」と大まかに考えることができます。
リモートサービスはデータを処理し、結果を返します。その結果は、チェーンを介して元のSQLステートメントに渡されます。
リモートサービスがHTTPコードで応答して 非同期 処理を通知する場合、Snowflakeは1つ以上のHTTP GETリクエストを送信して、リモートサービスから結果を取得します。Snowflakeは、リクエストを継続するための応答コードを受信する限り、または外部関数がタイムアウトするかエラーを返すまで、 GET リクエストを送信し続けます。
この図は、上記で説明した基本的ステップを示しています。非同期処理の詳細は示されていません。
同期リモートサービス¶
ユーザーが外部関数を呼び出す前に、開発者とSnowflakeアカウント管理者は、プロキシサービスにアクセスするためにSnowflakeを構成する必要があります。通常、ステップはおおよそ以下の順序で実行されます(上の図の右側から開始して、Snowflakeに向かって左側に移動)。
開発者はリモートサービスを記述し、 HTTPS プロキシサービスを介してそのリモートサービスを公開する必要があります。たとえば、リモートサービスは、 AWS Lambdaで実行され、Amazon API Gatewayのリソースを介して公開されるPython関数である場合があります。
Snowflakeでは、 ACCOUNTADMIN または CREATE INTEGRATION 権限を持つロールにより、Snowflakeがプロキシサービスと通信できるようにする認証情報を含む「API 統合」オブジェクトを作成する必要があります。API 統合は、 SQL コマンド CREATE API INTEGRATION で作成されます。
Snowflakeユーザーは、 SQL コマンド CREATE EXTERNAL FUNCTION を実行する必要があります。ユーザーは、 API 統合に対する USAGE 権限と、関数を作成するための十分な権限を持つロールを使用する必要があります。
注釈
CREATE EXTERNAL FUNCTION コマンドは、「Snowflakeの外部で実行される」コードをロードするという意味で、実際には外部関数を作成しません。代わりに、 CREATE EXTERNAL FUNCTION コマンドは、Snowflakeの外部で実行されるコードを 間接的に参照する データベースオブジェクトを作成します。より正確には、 CREATE EXTERNAL FUNCTION コマンドは以下を含むオブジェクトを作成します。
リレー機能として機能する HTTPS プロキシサービスのリソースの URL。
プロキシサービスへの認証に使用する API 統合の名前。
事実上リモートサービスのエイリアスである名前。このエイリアスは、たとえば
SELECT MyAliasForRemoteServiceXYZ(col1) ...;
といった SQL コマンドで使用されます。
Snowflakeのエイリアス、 HTTPS プロキシサービスリソースの名前、およびリモートサービスの名前はすべて異なる場合があります。(ただし、3つすべてに同じ名前を使用すると、管理の簡略化が可能。)
上記のステップは外部関数を実行する最も一般的な方法ですが、いくつかのバリエーションが許可されています。例:
リモートサービスは、チェーンの最後のステップではない可能性があります。リモートサービスは、作業の一部を実行するためにさらに別のリモートサービスを呼び出す場合があります。
リモートサービスが JSON 形式のデータを受け入れずに返す場合、 HTTPS プロキシサービスのリソース(リレー関数)は、データを JSON 形式から別の形式に変換します(そして、返されたデータを JSON に変換)。
Snowflakeでは、リモートサービスの動作として、副作用がなく状態情報を保持しない真の関数(つまり、0以上の入力パラメーターを受け入れて出力を返すコード)とすることを推奨していますが、これは厳密な必須事項ではありません。リモートサービスは他のタスクを実行できます。たとえば、値(データの温度の読み取り値など)が危険なほど高い場合にアラートを送信します。まれに、リモートサービスが、発行されたアラートの総数などの状態情報を保持する場合があります。
非同期リモートサービス¶
非同期 リモートサービスは、リモートサービスがプロキシサービスなどのコンポーネントに組み込まれているタイムアウトを超えた場合に役立ちます。
非同期リモートサービスには、上記で説明したものと同じコンポーネント(クライアント、Snowflake、プロキシサービス、およびリモートサービス)、および同じ一般的な手順が含まれます。ただし、 HTTP リクエストとレスポンスの詳細は異なります。
トピック 非同期リモートサービスの概要 では、非同期リモートサービスの実装に使用される HTTP リクエストとレスポンスについて説明します。
スケーラビリティ¶
リモートサービス、プロキシサービス、およびSnowflakeとリモートサービスの間の他のステップは、それらに送信されるピークワークロードを処理できる必要があります。
一部のクラウドプラットフォームプロバイダーには、プロキシサービスとリモートサービスのデフォルトの使用制限またはその他のクォータあり、外部関数呼び出しのスループットを制限する可能性があります。
Snowflake ウェアハウスのサイズ が大きくなるほど、リクエスト送信の同時実行が多くなり、プロキシサービスのクォータを超える可能性があります。
ユーザーは、クエリプロファイルの Retries due to transient errors の値を確認することで、Snowflakeがクエリのリクエストバッチの送信を(スロットリングまたはその他のエラーが原因で)再試行する必要があった回数を確認できます。
リモートサービスのスケーラビリティ¶
リモートサービスを作成する開発者は、以下を検討する必要があります。
リモートサービスが呼び出される頻度。
呼び出しごとに送信される行数。
各行の処理に必要なリソース。
呼び出しの時間分布(ピーク対平均)。
発信者が、少数の開発者とテスターから組織全体に変わるにつれて、時間の経過とともに容量を増やす必要が生じる可能性があります。リモートサービスが複数の組織で使用されている場合は、組織の数が増えるにつれて容量を増やす必要が生じる場合があります。さらに、組織の数と多様性が増加するにつれて、ワークロードのサイズとタイミングを予測することがより困難になる可能性があります。
リモートサービスプロバイダーは、ピークのワークロードを処理するために十分な容量を提供する責任があります。さまざまな手法を使用してサービスをスケーリングできます。リモートサービスがリモートサービスの作成者によって管理されている場合、作成者は、ピークを処理するのに十分な容量を持つサービスを明示的にプロビジョニングする必要がある場合があります。あるいは、作成者は AWS Lambdaといった、ホストされた自動スケーリング/弾性サービスの使用を決定する場合があります。
リモートサービスは、過負荷時に HTTP 応答コード429を返す必要があります。Snowflakeが429の HTTP を検出した場合、Snowflakeは行を送信する速度を低減し、正常に処理されなかった行のバッチの送信を再試行します。
スケーラビリティの問題に関するトラブルシューティングの詳細については、 スケーラビリティ をご参照ください。
システムが一般的に過負荷になっているためではなく、個々の呼び出しに時間がかかるためにリモートサービスの呼び出しがタイムアウトする場合は、 非同期リモートサービス の作成方法の説明をご覧ください。
プロキシサービスのスケーラビリティ¶
プロキシサービスもスケーラブルでなければなりません。幸い、主要なクラウドプロバイダーが提供するプロキシサービスは、一般にスケーラブルです。
ただし、Amazon API GatewayやAzure API Managementなどの一部のプロキシサービスには、デフォルトの使用制限があります。リクエストレートが制限を超えると、これらのプロキシサービスはリクエストをスロットルします。必要に応じて、プロキシサービスのクォータを増やすように AWS またはAzureに依頼する必要が生じる場合があります。
外部関数を開発または管理するユーザーは、次のプラットフォーム固有の情報を念頭に置く必要があります。
- Amazon API Gateway
Amazon API Gateway自体がマネージド AWS サービスであり、ユーザーのワークロードに合わせて自動スケーリングされます。ユーザーは、 API Gatewayの制限 に精通している必要があります。
Amazon API Gatewayは、リモートサービスのスケーリングに役立つように構成できます。具体的には、必要に応じてリモートサービスの負荷を軽減するため、リクエストのキャッシュやスロットリングを有効化するように API Gatewayを構成できます。
スロットルはタイムアウトと再試行に影響を与える可能性があるため、Snowflakeがタイムアウトと再試行を処理する方法に関する情報を確認する必要がある場合があります。
- Azure API Managementサービス
Azure API 管理の場合、制限はサービスに選択された SKU によって異なります。制限は、 Azureサブスクリプションサービスの制限 の API Management制限セクションに記載されています。
スロットルはタイムアウトと再試行に影響を与える可能性があるため、Snowflakeがタイムアウトと再試行を処理する方法に関する情報を確認する必要がある場合があります。
同時実行¶
リソース要件は、行が複数の呼び出しに分散される方法に依存します(各行が数行ある多数の並列呼び出しに対し、同じ行数の1つの呼び出し)。大容量をサポートするシステムが、必ずしも高い同時実行性をサポートするわけではなく、その逆も同様です。同時実行で必要となるピークと、妥当と思われる各最大ワークロードを見積もり、両方のタイプのピークを処理するために十分なリソースを提供する必要があります。
さらに、同時実行の見積もりでは、Snowflakeが外部関数呼び出しを並列化できることを考慮に入れる必要があります。単一のユーザーからの単一のクエリにより、リモートサービスへの複数の呼び出しが並行して発生する場合があります。Snowflakeからプロキシサービスまたはリモートサービスへの同時呼び出しの数には、次のようないくつかの要因が影響します。
外部関数でクエリを実行している同時ユーザーの数。
各ユーザーのクエリのサイズ。
仮想ウェアハウス内のサーバーの数(つまり、 ウェアハウスサイズ)。
ウェアハウスクラスター の数。
外部関数に 副作用 がある場合は、同時実行を適切に処理することが特に複雑になる可能性があります。結果は、ユーザーの行が処理される順序によって異なります。(Snowflakeでは、副作用のあるリモートサービスの作成や使用を避けることを推奨。)
信頼性¶
リモートサービスが実行されている場所に応じて、次のことを考慮する必要があります。
信頼性。
エラー処理。
デバッグ。
アップグレード(リモートサービスにより新機能が追加されるか、バグ修正が必要な場合)。
リモートサービスがステートレスでない場合は、障害後の回復も検討する必要があります。(Snowflakeでは、リモートサービスをステートレスにすることを強く推奨。)
タイムアウトと再試行の詳細については、 タイムアウトエラーの説明 および リモートサービスが各行に1回だけ渡されると思い込まない をご参照ください。