Connector Tablestore memungkinkan Anda menggunakan tabel Tablestore sebagai tabel sumber, tabel dimensi, dan tabel sink dalam pekerjaan Flink SQL yang berjalan dalam mode streaming.
Kemampuan connector
| Item | Deskripsi |
|---|---|
| Mode running | Streaming mode |
| Tipe API | SQL API |
| Tipe tabel | Tabel sumber, tabel dimensi, dan tabel sink |
| Format data | N/A |
| Metrik tabel sink | numBytesOut, numBytesOutPerSecond, numRecordsOut, numRecordsOutPerSecond, currentSendTime |
| Pembaruan atau penghapusan data di tabel sink | Didukung |
Untuk detail metrik sink, lihat Monitoring metrics.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
-
Instans Tablestore dan tabel Tablestore. Lihat Use Tablestore.
Batasan penggunaan
Akses lintas akun ke instans Tablestore didukung. Saat menggunakan endpoint VPC, instans Tablestore harus berada di wilayah yang sama dengan Flink. Atur accessId dan accessKey ke pasangan AccessKey dari akun pemilik instans Tablestore.
Sintaksis
Ketiga tipe tabel menggunakan 'connector'='ots' dalam klausa WITH, dengan opsi khusus tipe.
Tabel sink
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'
);
Tabel sink Tablestore memerlukan primary key. Setiap catatan output ditambahkan ke tabel untuk memperbarui data yang ada.
Tabel dimensi
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}'
);
Tabel sumber
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'
);
Metadata yang tersedia
Tabel sumber Tablestore mengekspos dua bidang metadata melalui kata kunci METADATA. Gunakan bidang ini untuk melacak tipe operasi dan waktu setiap event perubahan.
| Kunci metadata | Tipe data Flink | Deskripsi |
|---|---|---|
type |
STRING | Tipe operasi data (memetakan ke OtsRecordType). |
timestamp |
BIGINT | Waktu operasi data dalam mikrodetik (memetakan ke OtsRecordTimestamp). Diatur ke 0 untuk pembacaan data penuh. |
Untuk membaca bidang metadata, deklarasikan dengan sintaksis 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 (
...
);
Opsi connector
Opsi umum
Semua tipe tabel berbagi opsi berikut.
| Opsi | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
connector |
String | Ya | — | Diatur ke ots. |
instanceName |
String | Ya | — | Nama instans Tablestore. |
endPoint |
String | Ya | — | Endpoint instans Tablestore. Lihat Endpoints. |
tableName |
String | Ya | — | Nama tabel. |
accessId |
String | Ya | — | ID AccessKey dari Akun Alibaba Cloud Anda atau Pengguna Resource Access Management (RAM). Lihat How do I view the AccessKey ID and AccessKey secret? |
accessKey |
String | Ya | — | Rahasia AccessKey dari Akun Alibaba Cloud Anda atau pengguna RAM. |
connectTimeout |
Integer | Tidak | 30000 | Timeout koneksi dalam milidetik. |
socketTimeout |
Integer | Tidak | 30000 | Timeout socket dalam milidetik. |
ioThreadCount |
Integer | Tidak | 4 | Jumlah thread I/O. |
callbackThreadPoolSize |
Integer | Tidak | 4 | Ukuran kolam thread callback. |
Gunakan variabel untuk menyimpan pasangan AccessKey Anda alih-alih hardcoding.
Opsi tabel sumber
| Opsi | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
tunnelName |
String | Ya | — | Nama saluran data Tablestore. Buat saluran data di konsol Tablestore sebelum menggunakan opsi ini. Tipe saluran data yang didukung: Incremental, Full, dan Differential. Lihat bagian "Create a tunnel" di Quick start. |
ignoreDelete |
Boolean | Tidak | false | Apakah akan melewati operasi penghapusan. true: lewati; false: proses operasi penghapusan. |
skipInvalidData |
Boolean | Tidak | false | Apakah akan melewati data kotor. true: lewati data kotor; false: laporkan error. Memerlukan Ververica Runtime (VVR) 8.0.4 atau lebih baru. |
retryStrategy |
Enum | Tidak | TIME | Kebijakan retry. TIME: retry hingga retryTimeoutMs berakhir; COUNT: retry hingga mencapai retryCount. |
retryCount |
Integer | Tidak | 3 | Jumlah maksimum retry. Berlaku saat retryStrategy adalah COUNT. |
retryTimeoutMs |
Integer | Tidak | 180000 | Timeout retry dalam milidetik. Berlaku saat retryStrategy adalah TIME. |
streamOriginColumnMapping |
String | Tidak | — | Pemetaan dari nama kolom asli ke nama kolom aktual. Format: origin_col1:col1,origin_col2:col2. |
outputSpecificRowType |
Boolean | Tidak | false | Apakah akan meneruskan tipe baris spesifik. false: semua baris diperlakukan sebagai INSERT; true: baris dapat berupa INSERT, DELETE, atau UPDATE_AFTER. |
dataFetchTimeoutMs |
Integer | Tidak | 10000 | Waktu maksimum dalam milidetik untuk mengambil data dari satu partisi. Kurangi nilai ini untuk menurunkan latensi sinkronisasi secara keseluruhan saat menyinkronkan banyak partisi. Memerlukan VVR 8.0.10 atau lebih baru. |
enableRequestCompression |
Boolean | Tidak | false | Apakah akan mengaktifkan kompresi permintaan. Mengurangi penggunaan bandwidth dengan biaya beban CPU yang lebih tinggi. Memerlukan VVR 8.0.10 atau lebih baru. |
Opsi tabel sink
| Opsi | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
valueColumns |
String | Ya | — | Nama kolom yang akan ditulis. Pisahkan beberapa nama kolom dengan koma (,). |
retryIntervalMs |
Integer | Tidak | 1000 | Interval retry dalam milidetik. |
maxRetryTimes |
Integer | Tidak | 10 | Jumlah maksimum retry. |
bufferSize |
Integer | Tidak | 5000 | Jumlah maksimum catatan yang dibuffer sebelum penulisan dipicu. |
batchWriteTimeoutMs |
Integer | Tidak | 5000 | Timeout penulisan dalam milidetik. Jika catatan yang dibuffer tidak mencapai bufferSize dalam periode ini, semua catatan yang dibuffer akan ditulis. |
batchSize |
Integer | Tidak | 100 | Jumlah catatan yang ditulis per batch. Maksimum: 200. |
ignoreDelete |
Boolean | Tidak | false | Apakah akan melewati operasi penghapusan. |
autoIncrementKey |
String | Tidak | — | Nama kolom kunci utama auto-increment. Konfigurasikan hanya jika tabel sink memiliki kolom kunci utama auto-increment. Memerlukan VVR 8.0.4 atau lebih baru. |
overwriteMode |
Enum | Tidak | PUT | Mode penulisan. PUT: timpa dalam mode PUT; UPDATE: timpa dalam mode UPDATE. Mode kolom dinamis memerlukan UPDATE. |
defaultTimestampInMillisecond |
Long | Tidak | -1 | Timestamp default untuk penulisan. Jika tidak diatur, waktu sistem saat ini digunakan. |
dynamicColumnSink |
Boolean | Tidak | false | Apakah akan mengaktifkan mode kolom dinamis. Dalam mode ini, tidak ada kolom yang telah didefinisikan sebelumnya; kolom dimasukkan berdasarkan nilai runtime. N kolom pertama mendefinisikan kunci utama. Kolom kedua dari terakhir berisi nama kolom dan kolom terakhir berisi nilainya — keduanya harus bertipe STRING. Jika diaktifkan, overwriteMode harus diatur ke UPDATE dan kunci utama auto-increment tidak didukung. |
checkSinkTableMeta |
Boolean | Tidak | true | Apakah akan memverifikasi bahwa kunci utama tabel Tablestore sesuai dengan kunci utama yang dideklarasikan dalam pernyataan CREATE TABLE. |
enableRequestCompression |
Boolean | Tidak | false | Apakah akan mengaktifkan kompresi permintaan selama penulisan. |
maxColumnsCount |
Integer | Tidak | 128 | Jumlah maksimum kolom yang ditulis ke tabel sink. Jika diatur di atas 128, terjadi error The count of attribute columns exceeds the maximum. Memerlukan VVR 8.0.10 atau lebih baru. |
storageType |
String | Tidak | WIDE_COLUMN |
Tipe tabel sink. WIDE_COLUMN: tabel wide-column; TIMESERIES: tabel time series. |
Opsi tabel dimensi
Cara kerja cache
Cache tabel dimensi mengurangi pencarian berulang terhadap Tablestore. Pilih kebijakan cache berdasarkan ukuran tabel dan pola kueri Anda:
-
None: Tanpa caching. Setiap pencarian langsung mengakses Tablestore. Gunakan ketika data sering berubah dan freshness sangat penting.
-
LRU: Menyimpan jumlah tetap catatan yang baru saja diakses. Ketika pencarian tidak ditemukan di cache, connector melakukan kueri ke Tablestore dan memperbarui cache dengan hasilnya. Atur
cacheSizedancacheTTLMssaat menggunakan kebijakan ini. -
ALL (default): Memuat seluruh tabel dimensi ke dalam cache sebelum pekerjaan dimulai. Semua pencarian selanjutnya dilayani dari cache. Saat cache kedaluwarsa (
cacheTTLMs), connector memuat ulang semua data. Gunakan ALL ketika tabel kecil dan Anda mengharapkan banyak pencarian dengan kunci yang tidak ditemukan. Saat menggunakan ALL, tingkatkan memori node join — cache memerlukan ruang sekitar dua kali ukuran tabel remote.
| Opsi | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
retryIntervalMs |
Integer | Tidak | 1000 | Interval retry dalam milidetik. |
maxRetryTimes |
Integer | Tidak | 10 | Jumlah maksimum retry. |
cache |
String | Tidak | ALL | Kebijakan cache: None, LRU, atau ALL. |
cacheSize |
Integer | Tidak | — | Jumlah maksimum catatan yang dicache. Berlaku saat cache adalah LRU. |
cacheTTLMs |
Integer | Tidak | — | TTL cache dalam milidetik. Untuk LRU: timeout per entri. Untuk ALL: interval refresh cache penuh. Biarkan tidak diatur untuk menonaktifkan kedaluwarsa. |
cacheEmpty |
Boolean | Tidak | — | Apakah akan menyimpan hasil kosong (tidak cocok) di cache. true: simpan di cache; false: jangan simpan di cache. |
cacheReloadTimeBlackList |
String | Tidak | — | Jendela waktu saat cache ALL tidak direfresh. Format: 2017-10-24 14:00 -> 2017-10-24 15:00, 2017-11-10 23:30 -> 2017-11-11 08:00. Pisahkan beberapa jendela dengan koma; gunakan -> antara waktu mulai dan akhir. |
async |
Boolean | Tidak | false | Apakah akan mengaktifkan pencarian asinkron. true: pencarian asinkron (hasil tidak terurut); false: pencarian sinkron. |
Pemetaan tipe data
Tabel sumber
| Tipe Tablestore | Tipe Flink SQL |
|---|---|
| INTEGER | BIGINT |
| STRING | STRING |
| BOOLEAN | BOOLEAN |
| DOUBLE | DOUBLE |
| BINARY | BINARY |
Tabel sink
| Tipe Flink SQL | Tipe Tablestore |
|---|---|
| BINARY | BINARY |
| VARBINARY | BINARY |
| CHAR | STRING |
| VARCHAR | STRING |
| TINYINT | INTEGER |
| SMALLINT | INTEGER |
| INTEGER | INTEGER |
| BIGINT | INTEGER |
| FLOAT | DOUBLE |
| DOUBLE | DOUBLE |
| BOOLEAN | BOOLEAN |
Contoh
Baca dari Tablestore dan tulis ke Tablestore
Contoh ini membaca data pesanan dari tabel sumber Tablestore melalui Tunnel Service dan menulisnya ke tabel sink Tablestore. Tabel sink menggunakan kolom kunci utama auto-increment.
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;
Menyinkronkan tabel wide-column ke tabel time series
Contoh ini membaca dari tabel sumber wide-column dan menulis ke tabel sink time series. Kolom tags pada tabel sink menggunakan MAP<STRING, STRING> untuk menyimpan pasangan kunci-nilai tag, dan storageType diatur ke 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'
);
-- Bangun map tags dari kolom tag individual dan masukkan ke tabel sink time series
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;