Tablestore コネクタを使用すると、ストリーミングモードで実行される Flink SQL ジョブで、Tablestore テーブルをソーステーブル、ディメンションテーブル、シンクテーブルとして使用できます。
コネクタの機能
| 項目 | 説明 |
|---|---|
| 実行モード | ストリーミングモード |
| API タイプ | SQL API |
| テーブルタイプ | ソーステーブル、ディメンションテーブル、シンクテーブル |
| データ形式 | N/A |
| シンクテーブルのメトリクス | numBytesOut、numBytesOutPerSecond、numRecordsOut、numRecordsOutPerSecond、currentSendTime |
| シンクテーブルでのデータの更新または削除 | サポート済み |
シンクのメトリクスの詳細については、「メトリクスのモニタリング」をご参照ください。
前提条件
開始する前に、以下の準備が整っていることを確認してください。
-
Tablestore インスタンスと Tablestore テーブル。「Tablestore の使用」をご参照ください。
使用制限
Tablestore インスタンスへのクロスアカウントアクセスをサポートしています。VPC エンドポイントを使用する場合、Tablestore インスタンスは Flink と同じリージョンにある必要があります。accessId と accessKey には、Tablestore インスタンスを所有するアカウントの AccessKey ペアを設定します。
構文
3 種類のテーブルはいずれも、WITH 句で 'connector'='ots' を使用し、タイプ固有のオプションを指定します。
シンクテーブル
CREATE TABLE ots_sink (
name VARCHAR,
age BIGINT,
birthday BIGINT,
PRIMARY KEY (name, age) NOT ENFORCED
) WITH (
'connector'='ots',
'instanceName'='<yourInstanceName>',
'tableName'='<yourTableName>',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'endPoint'='<yourEndpoint>',
'valueColumns'='birthday'
);
Tablestore シンクテーブルにはプライマリキーが必要です。各出力レコードは、テーブルに対して Upsert (存在しない場合は挿入、存在する場合は更新) されます。
ディメンションテーブル
CREATE TABLE ots_dim (
id INT,
len INT,
content STRING
) WITH (
'connector'='ots',
'endPoint'='<yourEndpoint>',
'instanceName'='<yourInstanceName>',
'tableName'='<yourTableName>',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}'
);
ソーステーブル
CREATE TABLE tablestore_stream (
`order` VARCHAR,
orderid VARCHAR,
customerid VARCHAR,
customername VARCHAR
) WITH (
'connector'='ots',
'endPoint'='<yourEndpoint>',
'instanceName'='flink-source',
'tableName'='flink_source_table',
'tunnelName'='flinksourcestream',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'ignoreDelete'='false'
);
利用可能なメタデータ
Tablestore ソーステーブルは、METADATA キーワードを使用して 2 つのメタデータフィールドを公開します。これらのフィールドを使用して、各変更イベントの操作タイプとタイミングを追跡します。
| メタデータキー | Flink データ型 | 説明 |
|---|---|---|
type |
STRING | データ操作タイプ (OtsRecordType に対応)。 |
timestamp |
BIGINT | マイクロ秒単位のデータ操作時間 (OtsRecordTimestamp に対応)。フルデータ読み取りの場合は 0 になります。 |
メタデータフィールドを読み取るには、METADATA FROM 構文で宣言します。
CREATE TABLE tablestore_stream (
`order` VARCHAR,
orderid VARCHAR,
customerid VARCHAR,
customername VARCHAR,
record_type STRING METADATA FROM 'type',
record_timestamp BIGINT METADATA FROM 'timestamp'
) WITH (
...
);
コネクタオプション
共通オプション
以下のオプションは、すべてのテーブルタイプで共通です。
| オプション | タイプ | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
connector |
String | はい | — | ots に設定します。 |
instanceName |
String | はい | — | Tablestore インスタンスの名前。 |
endPoint |
String | はい | — | Tablestore インスタンスのエンドポイント。「エンドポイント」をご参照ください。 |
tableName |
String | はい | — | テーブルの名前。 |
accessId |
String | はい | — | Alibaba Cloud アカウントまたは Resource Access Management (RAM) ユーザーの AccessKey ID。 詳細については、「AccessKey ID と AccessKey シークレットの表示方法」をご参照ください。 |
accessKey |
String | はい | — | Alibaba Cloud アカウントまたは RAM ユーザーの AccessKey シークレット。 |
connectTimeout |
Integer | いいえ | 30000 | ミリ秒単位の接続タイムアウト。 |
socketTimeout |
Integer | いいえ | 30000 | ミリ秒単位のソケットタイムアウト。 |
ioThreadCount |
Integer | いいえ | 4 | I/O スレッドの数。 |
callbackThreadPoolSize |
Integer | いいえ | 4 | コールバックスレッドプールのサイズ。 |
AccessKey ペアをハードコーディングするのではなく、変数を使用して保存してください。
ソーステーブルのオプション
| オプション | タイプ | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
tunnelName |
String | はい | — | Tablestore トンネルの名前。このオプションを使用する前に、Tablestore コンソールでトンネルを作成してください。サポートされているトンネルタイプ:増分、完全、差分。「クイックスタート」の「トンネルの作成」セクションをご参照ください。 |
ignoreDelete |
Boolean | いいえ | false | 削除操作をスキップするかどうか。true:スキップします。false:削除操作を処理します。 |
skipInvalidData |
Boolean | いいえ | false | ダーティデータをスキップするかどうか。true:ダーティデータをスキップします。false:エラーを報告します。Ververica Runtime (VVR) 8.0.4 以降が必要です。 |
retryStrategy |
Enum | いいえ | TIME | リトライポリシー。TIME:retryTimeoutMs が経過するまでリトライします。COUNT:retryCount に達するまでリトライします。 |
retryCount |
Integer | いいえ | 3 | 最大リトライ回数。retryStrategy が COUNT の場合に適用されます。 |
retryTimeoutMs |
Integer | いいえ | 180000 | ミリ秒単位のリトライタイムアウト。retryStrategy が TIME の場合に適用されます。 |
streamOriginColumnMapping |
String | いいえ | — | 元の列名から実際の列名へのマッピング。形式:origin_col1:col1,origin_col2:col2。 |
outputSpecificRowType |
Boolean | いいえ | false | 特定の行タイプをパススルーするかどうか。false:すべての行を INSERT として扱います。true:行は INSERT、DELETE、または UPDATE_AFTER になります。 |
dataFetchTimeoutMs |
Integer | いいえ | 10000 | 単一のパーティションからデータをフェッチする最大時間 (ミリ秒単位)。多くのパーティションを同期する場合、この値を小さくすると、全体の同期レイテンシーが低下します。VVR 8.0.10 以降が必要です。 |
enableRequestCompression |
Boolean | いいえ | false | リクエスト圧縮を有効にするかどうか。CPU 負荷が高くなる代わりに、帯域幅の使用量を削減できます。VVR 8.0.10 以降が必要です。 |
シンクテーブルのオプション
| オプション | タイプ | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
valueColumns |
String | はい | — | 書き込む列の名前。複数の列名はカンマ (,) で区切ります。 |
retryIntervalMs |
Integer | いいえ | 1000 | ミリ秒単位のリトライ間隔。 |
maxRetryTimes |
Integer | いいえ | 10 | 最大リトライ回数。 |
bufferSize |
Integer | いいえ | 5000 | 書き込みがトリガーされる前にバッファリングされるレコードの最大数。 |
batchWriteTimeoutMs |
Integer | いいえ | 5000 | ミリ秒単位の書き込みタイムアウト。この期間内にバッファリングされたレコードが bufferSize に達しない場合、バッファリングされたすべてのレコードを書き込みます。 |
batchSize |
Integer | いいえ | 100 | バッチごとに書き込むレコード数。最大:200。 |
ignoreDelete |
Boolean | いいえ | false | 削除操作をスキップするかどうか。 |
autoIncrementKey |
String | いいえ | — | 自動インクリメントプライマリキー列の名前。シンクテーブルに自動インクリメントプライマリキー列がある場合にのみ設定します。VVR 8.0.4 以降が必要です。 |
overwriteMode |
Enum | いいえ | PUT | 書き込みモード。PUT:PUT モードで上書きします。UPDATE:UPDATE モードで上書きします。動的列モードでは UPDATE が必要です。 |
defaultTimestampInMillisecond |
Long | いいえ | -1 | 書き込みのデフォルトのタイムスタンプ。設定されていない場合、現在のシステム時刻を使用します。 |
dynamicColumnSink |
Boolean | いいえ | false | 動的列モードを有効にするかどうか。このモードでは、列を事前定義せず、ランタイム値に基づいて挿入します。最初の N 個の列がプライマリキーを定義します。最後から 2 番目の列に列名を、最後の列にその値を保持します (両方とも STRING である必要があります)。有効にした場合、overwriteMode は UPDATE である必要があり、自動インクリメントプライマリキーはサポートしていません。 |
checkSinkTableMeta |
Boolean | いいえ | true | Tablestore テーブルのプライマリキーが CREATE TABLE ステートメントで宣言されたプライマリキーと一致するかどうかを検証します。 |
enableRequestCompression |
Boolean | いいえ | false | 書き込み中にリクエスト圧縮を有効にするかどうか。 |
maxColumnsCount |
Integer | いいえ | 128 | シンクテーブルに書き込まれる列の最大数。128 を超えて設定すると、"The count of attribute columns exceeds the maximum" というエラーが発生します。VVR 8.0.10 以降が必要です。 |
storageType |
String | いいえ | WIDE_COLUMN |
シンクテーブルのタイプ。WIDE_COLUMN:ワイドカラムテーブル。TIMESERIES:時系列テーブル。 |
ディメンションテーブルのオプション
キャッシュの仕組み
ディメンションテーブルのキャッシュは、Tablestore への繰り返しルックアップを減らします。テーブルのサイズとクエリパターンに基づいてキャッシュポリシーを選択します。
-
None:キャッシングなし。すべてのルックアップは Tablestore に直接アクセスします。データが頻繁に変更され、鮮度が重要な場合に使用します。
-
LRU:最近アクセスされた一定数のレコードをキャッシュします。ルックアップしたデータがキャッシュに存在しない場合、コネクタは Tablestore にクエリを実行し、その結果でキャッシュを更新します。このポリシーを使用する場合は、
cacheSizeとcacheTTLMsを設定します。 -
ALL (デフォルト):ジョブが開始される前に、ディメンションテーブル全体をキャッシュにロードします。以降のすべてのルックアップはキャッシュからデータを取得します。キャッシュの有効期限が切れると (
cacheTTLMs)、コネクタはすべてのデータをリロードします。テーブルが小さく、キーが見つからないルックアップが多いと予想される場合に ALL を使用します。ALL を使用する場合、結合ノードのメモリを増やしてください。キャッシュには、リモートテーブルの約 2 倍のサイズが必要です。
| オプション | タイプ | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
retryIntervalMs |
Integer | いいえ | 1000 | ミリ秒単位のリトライ間隔。 |
maxRetryTimes |
Integer | いいえ | 10 | 最大リトライ回数。 |
cache |
String | いいえ | ALL | キャッシュポリシー:None、LRU、または ALL。 |
cacheSize |
Integer | いいえ | — | キャッシュされるレコードの最大数。cache が LRU の場合に適用されます。 |
cacheTTLMs |
Integer | いいえ | — | ミリ秒単位のキャッシュ TTL。LRU の場合:エントリごとのタイムアウト。ALL の場合:フルキャッシュのリフレッシュ間隔。有効期限を無効にするには、このオプションを設定しません。 |
cacheEmpty |
Boolean | いいえ | — | 空 (一致なし) の結果をキャッシュするかどうか。true:キャッシュします。false:キャッシュしません。 |
cacheReloadTimeBlackList |
String | いいえ | — | ALL キャッシュをリフレッシュしない時間帯。形式:2017-10-24 14:00 -> 2017-10-24 15:00, 2017-11-10 23:30 -> 2017-11-11 08:00。複数の時間帯はカンマで区切り、開始時刻と終了時刻の間には -> を使用します。 |
async |
Boolean | いいえ | false | 非同期ルックアップを有効にするかどうか。true:非同期ルックアップ (結果の順序は保証されません)。false:同期ルックアップ。 |
データ型マッピング
ソーステーブル
| Tablestore のタイプ | Flink SQL のタイプ |
|---|---|
| INTEGER | BIGINT |
| STRING | STRING |
| BOOLEAN | BOOLEAN |
| DOUBLE | DOUBLE |
| BINARY | BINARY |
シンクテーブル
| Flink SQL のタイプ | Tablestore のタイプ |
|---|---|
| BINARY | BINARY |
| VARBINARY | BINARY |
| CHAR | STRING |
| VARCHAR | STRING |
| TINYINT | INTEGER |
| SMALLINT | INTEGER |
| INTEGER | INTEGER |
| BIGINT | INTEGER |
| FLOAT | DOUBLE |
| DOUBLE | DOUBLE |
| BOOLEAN | BOOLEAN |
例
Tablestore からの読み取りと Tablestore への書き込み
この例では、Tunnel Service を使用して Tablestore ソーステーブルから注文データを読み取り、Tablestore シンクテーブルに書き込みます。シンクテーブルは、自動インクリメントプライマリキー列を使用します。
CREATE TEMPORARY TABLE tablestore_stream (
`order` VARCHAR,
orderid VARCHAR,
customerid VARCHAR,
customername VARCHAR
) WITH (
'connector'='ots',
'endPoint'='<yourEndpoint>',
'instanceName'='flink-source',
'tableName'='flink_source_table',
'tunnelName'='flinksourcestream',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'ignoreDelete'='false',
'skipInvalidData'='false'
);
CREATE TEMPORARY TABLE ots_sink (
`order` VARCHAR,
orderid VARCHAR,
customerid VARCHAR,
customername VARCHAR,
PRIMARY KEY (`order`, orderid) NOT ENFORCED
) WITH (
'connector'='ots',
'endPoint'='<yourEndpoint>',
'instanceName'='flink-sink',
'tableName'='flink_sink_table',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'valueColumns'='customerid,customername',
'autoIncrementKey'='${auto_increment_primary_key_name}'
);
INSERT INTO ots_sink
SELECT `order`, orderid, customerid, customername FROM tablestore_stream;
ワイドカラムテーブルから時系列テーブルへの同期
この例では、ワイドカラムソーステーブルから読み取り、時系列シンクテーブルに書き込みます。シンクテーブルの tags 列は MAP<STRING, STRING> を使用してタグのキーと値のペアを保持し、storageType を TIMESERIES に設定します。
CREATE TEMPORARY TABLE timeseries_source (
measurement STRING,
datasource STRING,
tag_a STRING,
`time` BIGINT,
binary_value BINARY,
bool_value BOOLEAN,
double_value DOUBLE,
long_value BIGINT,
string_value STRING,
tag_b STRING,
tag_c STRING,
tag_d STRING,
tag_e STRING,
tag_f STRING
) WITH (
'connector'='ots',
'endPoint'='https://iotstore-test.cn-hangzhou.vpc.tablestore.aliyuncs.com',
'instanceName'='iotstore-test',
'tableName'='test_ots_timeseries_2',
'tunnelName'='timeseries_source_tunnel_2',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'ignoreDelete'='true'
);
CREATE TEMPORARY TABLE timeseries_sink (
measurement STRING,
datasource STRING,
tags MAP<STRING, STRING>,
`time` BIGINT,
binary_value BINARY,
bool_value BOOLEAN,
double_value DOUBLE,
long_value BIGINT,
string_value STRING,
tag_b STRING,
tag_c STRING,
tag_d STRING,
tag_e STRING,
tag_f STRING,
PRIMARY KEY (measurement, datasource, tags, `time`) NOT ENFORCED
) WITH (
'connector'='ots',
'endPoint'='https://iotstore-test.cn-hangzhou.vpc.tablestore.aliyuncs.com',
'instanceName'='iotstore-test',
'tableName'='test_timeseries_sink_table_2',
'accessId'='${ak_id}',
'accessKey'='${ak_secret}',
'storageType'='TIMESERIES'
);
-- 個々のタグ列からタグマップを構築し、時系列シンクテーブルに挿入します
INSERT INTO timeseries_sink
SELECT
measurement,
datasource,
MAP['tag_a', tag_a, 'tag_b', tag_b, 'tag_c', tag_c, 'tag_d', tag_d, 'tag_e', tag_e, 'tag_f', tag_f] AS tags,
`time`,
binary_value,
bool_value,
double_value,
long_value,
string_value,
tag_b,
tag_c,
tag_d,
tag_e,
tag_f
FROM timeseries_source;