ユーザー定義スカラー関数 (UDSF) は、0 個、1 個、または複数のスカラー値を 1 つのスカラー値にマッピングします。各入力行は、必ず 1 つの出力値を生成します。
このトピックでは、Realtime Compute for Apache Flink で Python UDSF を作成、登録、使用する方法について説明します。
制限事項
Realtime Compute for Apache Flink で Python ユーザー定義関数 (UDF) を開発する場合、次の制約があります。
| 制約 | 要件 |
|---|---|
| Apache Flink バージョン | 1.12 以降 |
| Python バージョン | 各ワークスペースにプリインストールされています。VVR 8.0.11 未満:Python 3.7.9。VVR 8.0.11 以降:Python 3.9.21。 |
| JDK バージョン | JDK 8 および JDK 11。サードパーティの JAR パッケージは JDK 8 または JDK 11 と互換性がある必要があります。 |
| Scala バージョン | オープンソースの Scala 2.11 のみ。サードパーティの JAR パッケージは Scala 2.11 と互換性がある必要があります。 |
VVR 8.0.11 以降にアップグレードした後は、互換性を確認するために、既存の PyFlink ドラフトを再度テスト、デプロイ、および実行してください。
UDSF の作成
次の手順では、例として Windows 環境を使用します。Flink は、UDSF、ユーザー定義集計関数 (UDAF)、ユーザー定義テーブル値関数 (UDTF) の実装を含むサンプルリポジトリを提供しています。
-
python_demo-master をローカルマシンにダウンロードして解凍します。
これはサードパーティの GitHub リポジトリです。アクセスが遅い、または断続的に利用できない場合があります。
-
PyCharm で、[ファイル] > [開く] を選択し、解凍した
python_demo-masterディレクトリを開きます。 -
\python_demo-master\udxパスにあるudfs.pyを開き、UDSF を定義します。from pyflink.table import DataTypes from pyflink.table.udf import udf @udf(result_type=DataTypes.STRING()) def sub_string(s: str, begin: int, end: int): return s[begin:end]sub_stringの例では、入力文字列内の位置beginから位置endまでの文字を抽出します。 -
\python_demo-masterディレクトリで、次のコマンドを実行してudxディレクトリをパッケージ化します:zip -r python_demo.zip udx\python_demo-master\にpython_demo.zipが生成されたら、パッケージの準備は完了です。
UDSF の登録
パッケージを作成した後、Realtime Compute for Apache Flink コンソールで UDSF を登録します。登録手順については、「ユーザー定義関数 (UDF) の管理」をご参照ください。
UDSF の使用
UDSF を登録した後、Flink SQL ジョブで使用します。
-
Flink SQL を使用してドラフトを作成します。詳細については、「ジョブ開発の概要」をご参照ください。次の例では、
ASI_UDSF(UDSF の登録名) を呼び出して、ソーステーブルのaフィールドの位置 2 から 4 の直前までの文字を抽出します:CREATE TEMPORARY TABLE ASI_UDSF_Source ( a VARCHAR, b INT, c INT ) WITH ( 'connector' = 'datagen' ); CREATE TEMPORARY TABLE ASI_UDSF_Sink ( a VARCHAR ) WITH ( 'connector' = 'blackhole' ); INSERT INTO ASI_UDSF_Sink SELECT ASI_UDSF(a, 2, 4) FROM ASI_UDSF_Source; -
開発コンソールの左側のナビゲーションペインで、[O&M] > [デプロイ] を選択します。対象のデプロイを見つけ、[アクション] 列で [開始] をクリックします。デプロイが開始されると、
ASI_UDSF_Sourceのaフィールドの 2–4 番目の文字がASI_UDSF_Sinkに書き込まれます。
非同期ユーザー定義関数
外部データベースへのアクセスや HTTP リクエストなど、I/O 集中型の処理を実行する UDF には、非同期ユーザー定義関数を使用します。単一の非同期 UDF は複数の I/O リクエストを同時に処理できるため、待機時間をリクエスト間で分散し、ジョブのスループットを向上させます。
制限事項
-
VVR 11.7 以降でのみサポートされます。VVR PyFlink 11.7 以降が必要です。詳細については、「ververica-flink」をご参照ください。
pip3 install "ververica-flink>=11.7" -
非同期ユーザー定義スカラー関数 (UDSF) のみがサポートされます。
-
Python プロセスモードのみがサポートされます。つまり、
python.execution-mode=processです。 -
Pandas の非同期ユーザー定義関数は、現時点ではサポートされていません。
使用方法
非同期ユーザー定義関数は、Python の async 関数として実装するか、非同期関数クラスのサブクラスとして実装できます。サンプルコードを次に示します。
import asyncio
from pyflink.table import DataTypes
from pyflink.table.udf import AsyncScalarFunction, udf
# 方法1:Python の async 関数を使用します
@udf(result_type=DataTypes.STRING())
async def async_api_call(product_id: str) -> str:
await asyncio.sleep(0.05)
return f"product_{product_id}"
# 方法2:非同期関数クラスをサブクラス化します
class AsyncUserLookup(AsyncScalarFunction):
def open(self, function_context):
self.cache = {}
async def eval(self, user_id: str) -> str:
if user_id in self.cache:
return self.cache[user_id]
await asyncio.sleep(0.05)
result = f"user_{user_id}"
self.cache[user_id] = result
return result
def close(self):
self.cache.clear()
async_user_lookup = udf(
AsyncUserLookup(),
input_types=[DataTypes.STRING()],
result_type=DataTypes.STRING()
)
非同期ユーザー定義関数は、同期関数と同じ方法で登録して使用します。
設定パラメーター
以下のパラメーターは、非同期ユーザー定義関数の実行時の動作を制御します。
|
パラメーター |
デフォルト値 |
説明 |
|
table.exec.async-scalar.max-concurrent-operations |
10 |
オペレーターインスタンスごとの非同期呼び出しの最大同時実行数。デフォルト値: 10。 |
|
table.exec.async-scalar.timeout |
3 min |
1回の非同期呼び出しのタイムアウト。 |
|
table.exec.async-scalar.retry-strategy |
FIXED_DELAY |
非同期呼び出しが失敗した後の再試行戦略。サポートされる値:
|
|
table.exec.async-scalar.retry-delay |
100 ms |
固定遅延で再試行する場合の待機時間。 説明
|
|
table.exec.async-scalar.max-attempts |
3 |
非同期呼び出しが失敗と見なされるまでの最大試行回数。 説明
|