外部ネットワークアクセスのベストプラクティス

このトピックでは、ユーザー定義関数およびプロシージャから外部ネットワークロケーションにアクセスするためのベストプラクティスを提供します。

該当する外部関数のベストプラクティスに従う

以下を含む、 外部関数 について記載されたベストプラクティスに従ってください。

外部関数とは異なり、再試行の実行、ベクトル化された UDFs からのバッチリクエストの送信、例外の管理は、ハンドラーコードで行う必要があることに注意してください。

ベクトル化された UDF または UDTF で外部アクセスを使用する場合は、一度に1行を処理します。

ベクトル化された UDF または UDTF ハンドラーコードが外部ネットワークにリクエストする場合は、非決定論的な結果を避けるために、各行を独立して処理する必要があります。

ネットワークのオーバーヘッドを最小限に抑えるために、Snowflakeは通常、行をバッチ処理してリモートサービスに送信します。バッチの数と各バッチのサイズは異なる場合があります。

さらに、バッチの順序、およびバッチ内の行の順序は異なる場合があります。クエリに ORDER BY 句が含まれている場合でも、通常、 ORDER BY は外部ネットワークロケーションへのリクエストの後に適用されます。

バッチサイズと行の順序は保証されないため、このバッチまたは以前のバッチの他の行に依存する行の値を返すハンドラーコードを作成すると、非決定論的な結果が生成される可能性があります。

Snowflakeでは、コードで各行を個別に処理することを強く推奨します。

各入力行の戻り値は、他の入力行ではなく、その入力行のみに依存する必要があります。(現在、外部ネットワークアクセスを行うハンドラーは、 ウィンドウ関数 などに対応していません)。

また、バッチサイズは保証されていないため、バッチのカウントは意味がありません。

可能であれば TCP 接続を再利用する

Snowflakeは UDF から行うことができる接続の総数を制限しています。この制限に達すると、次のようなエラーメッセージが表示されることがあります。

Cannot assign requested address
Copy

リソースの枯渇の問題を避けるために、接続はできるだけ再利用するようにしてください。これは、 TCP クライアントまたはセッションを UDF 初期化中に一度だけ作成し、 UDF ハンドラーで残りのクエリに使用することで達成できます。例えば、Pythonで記述されたコードでは、 Session オブジェクト(Pythonの requests ライブラリから利用可能)を複数の HTTP 呼び出しに再利用することができます。

詳細と例については、 関数またはプロシージャでの外部アクセス統合の使用 をご参照ください。

コードの一時的なエラーを予期し、対処する

リモートサービスを複数回呼び出すようなクエリを長時間実行すると、そのうちの1回が一時的なエラーで失敗する可能性があります。クエリの失敗を回避するために、コードは再試行を行い、失敗が発生することを前提に失敗を処理する必要があります。