このトピックでは、住宅用電力網の端末データを使用して、Realtime Compute for Apache Flink コンソールでユーザー定義集計関数 (UDAF) を使用してデータをマージおよびソートする方法を説明します。
サンプルデータ
electric_info テーブルには、住宅用電力網の端末データが含まれています。このテーブルには、イベント ID (event_id)、ユーザー ID (user_id)、イベント時間 (event_time)、および端末ステータス (status) が含まれます。各ユーザーの status 値を集計し、event_time でソートします。
-
electric_info
event_id
user_id
event_time
status
1
1222
2023-06-30 11:14:00
LD
2
1333
2023-06-30 11:12:00
LD
3
1222
2023-06-30 11:11:00
TD
4
1333
2023-06-30 11:12:00
LD
5
1222
2023-06-30 11:15:00
TD
6
1333
2023-06-30 11:18:00
LD
7
1222
2023-06-30 11:19:00
TD
8
1333
2023-06-30 11:10:00
TD
9
1555
2023-06-30 11:16:00
TD
10
1555
2023-06-30 11:17:00
LD
-
期待される結果
user_id
status
1222
TD,LD,TD,TD
1333
TD,LD,LD,LD
1555
TD,LD
ステップ1:データソースの準備
この例では、データソースとして ApsaraDB RDS を使用します。
-
ApsaraDB RDS for MySQL インスタンスを作成します。
説明ApsaraDB RDS for MySQL インスタンスは、Realtime Compute for Apache Flink ワークスペースと同じ VPC にある必要があります。異なる VPC にある場合は、「ネットワーク接続」をご参照ください。
-
electric という名前のデータベースと、このデータベースに対する読み取りおよび書き込み権限を持つアカウントを作成します。
-
Data Management (DMS) を使用して ApsaraDB RDS for MySQL インスタンスにログインし、
electricデータベースにelectric_infoテーブルとelectric_info_SortListAggテーブルを作成して、データを挿入します。CREATE TABLE `electric_info` ( event_id bigint NOT NULL PRIMARY KEY COMMENT 'イベント ID', user_id bigint NOT NULL COMMENT 'ユーザー ID', event_time timestamp NOT NULL COMMENT 'イベント時間', status varchar(10) NOT NULL COMMENT 'ユーザー端末のステータス' ); CREATE TABLE `electric_info_SortListAgg` ( user_id bigint NOT NULL PRIMARY KEY COMMENT 'ユーザー ID', status_sort varchar(50) NULL COMMENT 'イベント時間で昇順にソートされたユーザー端末のステータス' ); -- データを準備 INSERT INTO electric_info VALUES (1,1222,'2023-06-30 11:14','LD'), (2,1333,'2023-06-30 11:12','LD'), (3,1222,'2023-06-30 11:11','TD'), (4,1333,'2023-06-30 11:12','LD'), (5,1222,'2023-06-30 11:15','TD'), (6,1333,'2023-06-30 11:18','LD'), (7,1222,'2023-06-30 11:19','TD'), (8,1333,'2023-06-30 11:10','TD'), (9,1555,'2023-06-30 11:16','TD'), (10,1555,'2023-06-30 11:17','LD');
ステップ2:UDAF の登録
-
ASI_UDX-1.0-SNAPSHOT.jar パッケージをダウンロードします。
pom.xml ファイルは、Flink バージョン 1.17.1 のこのカスタム関数に必要な最小限の依存関係で設定されています。カスタム関数の詳細については、「カスタム関数」をご参照ください。
-
サンプルコード
ASI_UDAFは、複数の行を 1 つの行にマージし、指定された列でデータをソートします。ビジネスニーズに合わせてコードを変更できます。package ASI_UDAF; import org.apache.commons.lang3.StringUtils; import org.apache.flink.table.functions.AggregateFunction; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; public class ASI_UDAF{ /**アキュムレータクラス*/ public static class AcList { public List<String> list; } /**集計関数クラス*/ public static class SortListAgg extends AggregateFunction<String,AcList> { public String getValue(AcList asc) { /**特定のルールに基づいてリスト内のデータをソートします*/ asc.list.sort(new Comparator<String>() { @Override public int compare(String o1, String o2) { return Integer.parseInt(o1.split("#")[1]) - Integer.parseInt(o2.split("#")[1]); } }); /**ソートされたリストを走査し、必要なフィールドを抽出して文字列に結合します*/ List<String> ret = new ArrayList<String>(); Iterator<String> strlist = asc.list.iterator(); while (strlist.hasNext()) { ret.add(strlist.next().split("#")[0]); } String str = StringUtils.join(ret, ','); return str; } /**アキュムレータを作成するメソッド*/ public AcList createAccumulator() { AcList ac = new AcList(); List<String> list = new ArrayList<String>(); ac.list = list; return ac; } /**アキュムレーションメソッド:入力データをアキュムレータに追加します*/ public void accumulate(AcList acc, String tuple1) { acc.list.add(tuple1); } /**リトラクションメソッド*/ public void retract(AcList acc, String num) { } } } -
UDAF を登録します。
UDAF を登録すると、そのコードを他のジョブで再利用できます。Java UDAF の場合、JAR を依存関係ファイルとしてアップロードすることもできます。詳細については、「ユーザー定義集計関数 (UDAF)」をご参照ください。
-
目的のワークスペースを見つけ、[アクション] 列の [コンソール] をクリックします。
-
左側のナビゲーションペインで、 を選択します。
-
[機能] タブで、[UDF の登録] をクリックします。
-
[ファイルを選択] セクションで、ステップ 1 の JAR ファイルをアップロードし、[OK] をクリックします。
ダイアログボックスには、[Upload File] と [External URL] の 2 つの登録方法があります。[UDF Name] を指定する必要があり、任意で [dependency file] をアップロードできます。
説明-
UDF の JAR ファイルは、ワークスペースに関連付けられている OSS バケットの sql-artifacts ディレクトリにアップロードされます。
-
Realtime Compute for Apache Flink コンソールは UDF JAR ファイルを解析し、Flink UDF、UDAF、UDTF インターフェイスを使用するクラスを検出します。クラス名を自動的に抽出し、[Function Name] フィールドに設定します。
-
-
[関数の管理] ダイアログボックスで、[関数を作成] をクリックします。
登録された UDF は、SQL エディターページの左側にある[関数] リストに表示されます。
ステップ3:Flink ジョブの作成
-
ページで、[新規作成] をクリックします。
-
[空白のストリームドラフト] をクリックします。
-
[次へ] をクリックします。
-
[新規ドラフト] ダイアログボックスで、ジョブ設定を設定します。
パラメーター
説明
[ファイル名]
ジョブの一意の名前。
説明ジョブ名は現在のプロジェクト内で一意である必要があります。
[保存場所]
ジョブの保存場所。
既存のフォルダーの横にある
アイコンをクリックして、サブフォルダーを作成することもできます。[エンジンバージョン]
ジョブの Flink エンジンバージョン。これは、
pom.xmlファイルで指定されたバージョンと一致する必要があります。エンジンバージョン、バージョンのマッピング、ライフサイクル情報の詳細については、「エンジンバージョン」をご参照ください。
-
DDL および DML ステートメントを記述します。
-- 一時テーブル electric_info を作成します。 CREATE TEMPORARY TABLE electric_info ( event_id bigint not null, `user_id` bigint not null, event_time timestamp(6) not null, status string not null, primary key(event_id) not enforced ) WITH ( 'connector' = 'mysql', 'hostname' = 'rm-bp1s1xgll21******.mysql.rds.aliyuncs.com', 'port' = '3306', 'username' = 'your_username', 'password' = '${secret_values.mysql_pw}', 'database-name' = 'electric', 'table-name' = 'electric_info' ); CREATE TEMPORARY TABLE electric_info_sortlistagg ( `user_id` bigint not null, status_sort varchar(50) not null, primary key(user_id) not enforced ) WITH ( 'connector' = 'mysql', 'hostname' = 'rm-bp1s1xgll21******.mysql.rds.aliyuncs.com', 'port' = '3306', 'username' = 'your_username', 'password' = '${secret_values.mysql_pw}', 'database-name' = 'electric', 'table-name' = 'electric_info_sortlistagg' ); -- electric_info テーブルからデータを集計し、electric_info_sortlistagg テーブルに挿入します。 -- 登録されたカスタム関数 ASI_UDAF$SortListAgg のパラメーターとして、status と event_time を連結した文字列を渡します。 INSERT INTO electric_info_sortlistagg SELECT `user_id`, `ASI_UDAF$SortListAgg`(CONCAT(status,'#',CAST(UNIX_TIMESTAMP(event_time) as STRING))) FROM electric_info GROUP BY user_id;次の表でパラメーターについて説明します。実際のニーズに基づいて変更してください。MySQL コネクタのパラメーターの詳細については、「MySQL コネクタ」をご参照ください。
パラメーター
説明
注意
connector
コネクタのタイプ。
この例では、値は
mysqlに固定されています。hostname
MySQL データベースの IP アドレスまたはホスト名。
この例では、ApsaraDB RDS for MySQL インスタンスの内部エンドポイントを使用します。
username
MySQL データベースサービスのユーザー名。
なし。
password
MySQL データベースサービスのパスワード。
この例では、セキュリティリスクを回避するために、パスワードには変数の
mysql_pwを使用します。詳細については、「変数」をご参照ください。database-name
MySQL データベースの名前。
この例では、「ステップ1:データソースの準備」で作成したデータベース
electricを使用します。table-name
MySQL テーブルの名前。
この例では、
electric_infoまたはelectric_info_sortlistaggに設定します。port
MySQL データベースサービスのポート番号。
なし。
-
(任意) 右上隅で、[検証] と [デバッグ] をクリックします。これらの機能の詳細については、「ジョブ開発の概要」をご参照ください。
-
[デプロイ] をクリックし、次に [確認] をクリックします。
-
ページで、対象のジョブを見つけ、[操作] 列の [開始] をクリックし、[初期モード] を選択します。
ステップ4:結果のクエリ
ApsaraDB RDS で、次のステートメントを実行して、集計およびソートされた結果を表示します。
SELECT * FROM `electric_info_sortlistagg`;
出力は、各ユーザーのステータスが正しく集計およびソートされたことを示しています:user_id=1222 は status_sort=TD,LD,TD,TD に対応し、user_id=1333 は status_sort=TD,LD,LD,LD に対応し、user_id=1555 は status_sort=TD,LD に対応します。
関連ドキュメント
-
Flink がサポートする組み込み関数の詳細については、「組み込み関数」をご参照ください。
-
ジョブの実行パラメーターを変更するには、「ジョブデプロイの設定」をご参照ください。一部のパラメーターは動的に更新できるため、ジョブの停止と再起動によるダウンタイムを削減できます。詳細については、「動的スケーリングとパラメーターの更新」をご参照ください。
-
SQL ジョブでの Python カスタム関数の使用方法については、「カスタム関数」をご参照ください。