支援高吞吐資料攝入、變更追蹤、高效分析的流批資料湖
基於LSM提升寫入速度並降低寫入消耗;基於有序的SortRun裁剪大部分資料以提升查詢效能;支援多種merge引擎實現高效能流表打寬
基於Flink&Paimon實現,提供資料一致性管理能力,解決流式數倉普遍存在的問題
paimon透過snapshot定義資料版本,即資料按snapshot對齊。
實現方案:提交階段查詢系統表中的血緣表設定起始消費位置;執行階段按照消費的snapshot粒度響應chkpt請求,chkpt coordinator將barrier放在兩個snapshot中間;chkpt成功後通知sink提交對應的表;提交完成後由CommitListener將血緣關係寫入系統表
問題:
缺少血緣管理(表血緣、資料血緣)
缺少統一的版本管理(多表關聯查詢時不一致)
資料訂正困難(複雜的資料修正過程、鏈路雙跑、業務邏輯修正)
特點
是 Flink SQL 的內建儲存
- Flink DDL 會真實建立或刪除物理表,不再只是一個外部物理表的對映
- 掩蓋和抽象底層技術細節,沒有煩人的選項如connector配置
支援亞秒級流寫入和消費
高吞吐量掃描能力
降低了認知門檻,儲存需要自動處理各種Insert/Update/Delete輸入和表定義
- 接收任何型別的變更日誌,接收任何型別的資料型別
- 表可以有主鍵或沒有主鍵
支援多種引擎
儲存
LogStore append延時很低,但有TTL限制,可用於流讀。FileStore確保可以查詢歷史資料:
- LogStore:儲存最新資料,支援秒級流式增量消費,預設使用Kafka實現
- 完全支援插入/更新/刪除
- 根據主鍵(若有)或整行(無主鍵)將記錄雜湊到不同的kafka分割槽
- FileStore:儲存最新資料+歷史資料,提供批次Ad-Hoc分析,使用LSM、parquet/orc實現
- 為了完全支援插入/更新/刪除和可選的主鍵定義,我們需要一個支援更新和自定義合併的靈活儲存結構,LSM 是一個不錯的選擇
- 為了支援高效能和多場景分析,應該支援多種列式檔案格式
- key若有主鍵則預設json格式,若無則空。value預設使用debezium-json格式
如果是流模式且開啟change-tracking,log與file同時生效,生成HybridSource讀,如果是流模式且未開啟change-tracking、批模式,生成FileStoreSource讀。
檔案結構
後設資料與資料儲存在表的同一級目錄下,包括 snapshot 目錄、manifest 目錄、schema 目錄、資料檔案。桶檔案是讀寫的最小儲存單元。
每個snapshot會有對應的一個base清單列表、一個delta清單列表檔案,base清單列表包含了本次操作之前的清單檔案,清單列表檔案會對應一個或多個清單,每個清單會對應一個或多個不同操作型別的資料檔案
- snapshot 目錄:記錄了每次提交產生的 snapshot 檔案,記錄了本次 commit 正在使用的schema檔案、新增了哪些 manifest 檔案、刪除了哪些 manifest 檔案
- snapshot-x 一次checkpoint生成一個或兩個snapshot(當有append、compact同時發生時出現會生成兩個),若檢查點間隔內未寫入資料,只會建立compact快照
- EARLIEST 最早的快照編號,一開始是-8
- LATEST 最新的快照編號
- manifest 目錄:記錄了每次經 checkpoint 觸發而提交的資料檔案變更,每個檔案記錄了產生了哪些 sst 檔案、刪除了哪些 sst 檔案,以及每個 sst 檔案所包含記錄的主鍵範圍、每個欄位的 min/max/null count 等統計資訊
- schema 目錄:表結構檔案
- 資料檔案:按分割槽、儲存桶分到對應目錄,每個桶目錄都包含一個LSM樹和變更日誌檔案,每個 sst 檔案則包含了按主鍵排好序的、列存格式的記錄。對於 Level 0 的檔案,會非同步地觸發 compact 合併執行緒來消除主鍵範圍重疊帶來的讀端 merge 開銷
- LSM樹將sst檔案組織成多個SortedRun,SortedRun與檔案是一對多的關係,對於主鍵表,不同的SortedRun可能具有重疊的主鍵範圍或相同的主鍵,查詢LSM樹時必須MOR,根據指定的合併引擎和每條記錄的時間戳來合併所有SortedRun
- 當write-buffer-size耗盡時會將資料flush生成檔案
Catalog
file
CREATE CATALOG my_catalog WITH ( 'type' = 'paimon', 'warehouse' = 'hdfs:///path/to/warehouse' ); USE CATALOG my_catalog;
hive
表
分類
- 管理表,paimon catalog下建的表,刪除會刪所有資料
- 外部表,非paimon catalog下建的表,屬性要有'connector'='paimon', 'path'='xxx',可以直接讀寫外部的paimon資料,刪除後只是show tables無,未刪後設資料、資料
- 臨時表,僅flink支援,在paimon catalog下建的外部表,會話級的,會話退出後自動失效。create tempoary table t1,with屬性與外部表一樣
- 系統表,表名$系統表名,如快照表$snapshots、schema表$schemas、選項表$options、審計日誌表$audit_log、檔案表$files
有主鍵表
如果定義具有主鍵的表,則可以在表中插入、更新或刪除記錄。
無主鍵表
1、append表
若無主鍵則預設是append表。流式傳輸只能向表中插入一條完整的記錄。這種型別的表適合不需要流式更新的用例。預設是zstd壓縮
CREATE TABLE my_table ( product_id BIGINT, price DOUBLE, sales BIGINT ) WITH ( 'file.compression' = 'zstd' );
流式讀取:
- 預設情況下,流式讀取在第一次啟動時會對錶生成最新的快照,並繼續讀取最新的增量記錄。
- 可以指定scan.mode、scan.snapshot-id、scan.timestamp-millis或scan.file-creation-time-millis僅流式讀取增量。
OLAP查詢
- 按順序跳過資料,Paimon 預設記錄清單檔案中每個欄位的最大值和最小值,在查詢的時候,根據WHERE查詢的條件,根據manifest中的統計資訊做檔案過濾
- 按檔案索引跳過資料
CREATE TABLE <PAIMON_TABLE> (<COLUMN> <COLUMN_TYPE> , ...) WITH ( 'file-index.bloom-filter.columns' = 'c1,c2', 'file-index.bloom-filter.c1.items' = '200' );
2、bucketed append表
必須指定bucket-key
CREATE TABLE my_table ( product_id BIGINT, price DOUBLE, sales BIGINT ) WITH ( 'bucket' = '8', 'bucket-key' = 'product_id' );
系統表
snapshots 快照表
manifests 清單表
audit_log 審計日誌表,包含表的變更統計
schemas 表結構
partitions 分割槽
files 檔案表
tags 標籤表
ro Read-optimized表,當需要非常高的讀效能且能接受較舊的資料,使用該表,讀時不需要MOR,對於有主鍵表只讀取最新的full compaction,對於無主鍵表,無變化
consumers 消費者表
aggregation_fields 查表的聚合欄位情況
全域性系統表
- sys.all_table_options
- sys.catalog_options
- sys.source_table_lineage
- sys.sink_table_lineage
生態
重要特性
Predicate
讀取時會filter過濾掉不需要讀的內容
- 讀取 manifest:根據檔案的 min/max、分割槽,執行分割槽和欄位的 predicate,淘汰多餘的檔案
- 讀取檔案 footer:根據 chunk 的 min/max,過濾不需要讀取的 chunk
- 讀取剩下的檔案以及其中的 chunks
寫入
Paimon Sink 首先在記憶體堆的 LSM 樹中緩衝新記錄,並在記憶體緩衝區滿時將它們重新整理到磁碟。注意,寫入的每個資料檔案都是一個SortedRun。此時,不會建立清單檔案和快照。就在 Flink 檢查點發生之前,Paimon Sink 將flush所有遺留的緩衝記錄,並向下遊傳送committable,該訊息在檢查點期間由Committer運算元讀取和提交。
在檢查點期間,Committer運算元將建立一個新的快照並將其與清單列表關聯,以便快照 包含有關表中所有資料檔案的資訊。
稍後可能會進行非同步Compaction,由 CompactManager 生成的committable包含以前檔案和合並檔案的資訊,以便Committer運算元可以構造相應的清單條目。此時Committer運算元可能在 Flink 檢查點期間生成兩個快照,一個用於寫入(Append 型別的快照) ,另一個用於壓縮(Compend 型別的快照)。如果在檢查點間隔期間沒有寫入任何資料檔案,則將只建立 Compact 型別的快照。Committer運算元將檢查快照過期情況,並對標記的資料檔案執行物理刪除。
批查
RESET 'execution.checkpointing.interval';
SET 'execution.runtime-mode'='batch';
TimeTraveling
-- read the snapshot with id 1L SELECT * FROM t /*+ OPTIONS('scan.snapshot-id' = '1') */; -- read the snapshot from specified timestamp in unix milliseconds SELECT * FROM t /*+ OPTIONS('scan.timestamp-millis' = '1678883047356') */; -- read tag 'my-tag' SELECT * FROM t /*+ OPTIONS('scan.tag-name' = 'my-tag') */; -- read the snapshot from watermark, will match the first snapshot after the watermark SELECT * FROM t /*+ OPTIONS('scan.watermark' = '1678883047356') */;
批增量查
讀快照a到b間的增量變更,不包含起始快照a本身
-- incremental between snapshot ids SELECT * FROM t /*+ OPTIONS('incremental-between' = '12,20') */; -- incremental between snapshot time mills SELECT * FROM t /*+ OPTIONS('incremental-between-timestamp' = '1692169000000,1692169900000') */; --批模式下,-D資料不會展示,如果想檢視-D資料,可以看審計系統表 SELECT * FROM t$audit_log /*+ OPTIONS('incremental-between' = '12,20') */;
流查
SET 'execution.checkpointing.interval'='30s';
SET 'execution.runtime-mode'='streaming';
TimeTraveling
-- read changes from snapshot id 1L 快照1之後的增量,且包含在快照1階段的變更 SELECT * FROM t /*+ OPTIONS('scan.snapshot-id' = '1') */; -- read changes from snapshot specified timestamp SELECT * FROM t /*+ OPTIONS('scan.timestamp-millis' = '1678883047356') */; -- read snapshot id 1L upon first startup, and continue to read the changes SELECT * FROM t /*+ OPTIONS('scan.mode'='from-snapshot-full','scan.snapshot-id' = '1') */;
consumer-id
- 類似於kafka消費者組,會自動記錄消費offset,重啟後會自動從上次消費點位開始,不需要手動指定savepoint。可指定'consumer.mode'='at-least-once',預設是exactly-once,
- 類似於JVM GC,判斷快照是否過期時會檢視該表的所有消費者,若還有消費者依賴該快照則不會因過期而刪除。指定consumer.expiration-time引數
--直接查出當前的全量資料,是全+I的 SELECT * FROM pk1 /*+ OPTIONS('consumer-id' = 'myid') */; insert into pk1 values (9,'f'); --只會顯示+I 9,因為是從上一次消費位點開始 SELECT * FROM pk1 /*+ OPTIONS('consumer-id' = 'myid') */;
流讀overwrite changelog
select * from pk_part2 /*+OPTIONS('streaming-read-overwrite'='true')*/;
查詢過濾最佳化
增強效能支援如下過濾
- =
- <
- <=
- >
- >=
- IN (...)
- LIKE 'abc%'
- IS NULL
過濾條件的欄位應該在主鍵字首範圍內,順序也應該一致,若有多個要用AND聯接
Lookup Join維表查詢
支援有主鍵的非分割槽表作為維表,維護一個本地的rocksdb cache並實時拉取最新的變更,且會下推謂詞
SELECT o.order_id, o.total, c.country, c.zip FROM Orders AS o JOIN customers /*+ OPTIONS('lookup.cache-rows'='20000') */ FOR SYSTEM_TIME AS OF o.proc_time AS c ON o.customer_id = c.id;
獨立的compaction作業
--呼叫procedure CALL sys.compact('default.t', '', '', '', 'sink.parallelism=4') --呼叫action <FLINK_HOME>/bin/flink run \ /path/to/paimon-flink-action-0.9-SNAPSHOT.jar \ compact \ --warehouse s3:///path/to/warehouse \ --database test_db \ --table test_table \ --partition dt=20221126,hh=08 \ --partition dt=20221127,hh=09 \ --table_conf sink.parallelism=10 \ --catalog_conf s3.endpoint=https://****.com \ --catalog_conf s3.access-key=***** \ --catalog_conf s3.secret-key=*****
過期快照
首先刪除所有標記的資料檔案,並記錄所有發生變更的桶。
然後刪除任何變更日誌檔案和相關的清單。
最後,它刪除快照本身並更新EARLIEST檔案。
縮放桶
一、不停任務
alter table t1 set ('bucket'='4'); --僅修改後設資料,不會自動重分佈資料
set 'execution.runtime-mode'='batch';
insert overwrite t1 partition (dt='2024-05-27') select ...; --重分佈資料,若直接insert into會報TableException
二、停任務
flink stop --savePointPath xxx $JOB_ID
alter table t1 set ('bucket'='4'); --僅修改後設資料,不會自動重分佈資料
set 'execution.runtime-mode'='batch';
insert overwrite t1 partition (dt='2024-05-27') select ...; --重分佈資料,若直接insert into會報TableException
--overwrite任務完成後,用流模式重啟任務
SET 'execution.runtime-mode' = 'streaming';
SET 'execution.savepoint.path' = ;
insert into t1 select ...;
CDC整合
支援模式演化,修改的列會實時同步到paimon表且不需要重啟作業。
- mysql一張或多張表->一個paimon表
- mysql整個資料庫->一個paimon庫
- DataSteram api表->一個paimon表
- kafka一個topic對應的一張或多張表->一個paimon表
- kafka整個資料庫->一個paimon庫
mysql同步單表或多表
多表的欄位會合併到一張paimon表,同名欄位不重複增加
--partition_keys pt 指定分割槽列
--primary_keys pt,uid 指定主鍵
--mysql_conf database-name='source_db.+' 多shards同步
--catalog_conf paimon的catalog配置
<FLINK_HOME>/bin/flink run \ /path/to/paimon-flink-action-0.9-SNAPSHOT.jar \ mysql_sync_table \ --warehouse hdfs:///path/to/warehouse \ --database test_db \ --table test_table \ --partition_keys pt \ --primary_keys pt,uid \ --computed_column '_year=year(age)' \ --mysql_conf hostname=127.0.0.1 \ --mysql_conf username=root \ --mysql_conf password=123456 \ --mysql_conf database-name='source_db' \ --mysql_conf table-name='source_table1|source_table2' \ --catalog_conf metastore=hive \ --catalog_conf uri=thrift://hive-metastore:9083 \ --table_conf bucket=4 \ --table_conf changelog-producer=input \ --table_conf sink.parallelism=4
mysql同步整庫
--including_tables test|paimon.*
--excluding_tables
--table_prefix
--table_suffix
--mode 預設是divided,每張表會生成單獨的sink,若同步新表需要重啟指定--fromSavepoint。可以指定combined,所有表共用一個sink,新表會自動同步無需重啟
<FLINK_HOME>/bin/flink run \ /path/to/paimon-flink-action-0.9-SNAPSHOT.jar \ mysql_sync_database \ --warehouse hdfs:///path/to/warehouse \ --database test_db \ --mysql_conf hostname=127.0.0.1 \ --mysql_conf username=root \ --mysql_conf password=123456 \ --mysql_conf database-name=source_db \ --catalog_conf metastore=hive \ --catalog_conf uri=thrift://hive-metastore:9083 \ --table_conf bucket=4 \ --table_conf changelog-producer=input \ --table_conf sink.parallelism=4
kafka一個topic對應的一張或多張表同步
支援canal-cdc、debezium-cdc、maxwell-cdc、ogg-cdc,schema從topic的cdc訊息中獲取
--computed_column 'part=date_format(create_time,yyyy-MM-dd)'
<FLINK_HOME>/bin/flink run \ /path/to/paimon-flink-action-0.9-SNAPSHOT.jar \ kafka_sync_table \ --warehouse hdfs:///path/to/warehouse \ --database test_db \ --table test_table \ --partition_keys pt \ --primary_keys pt,uid \ --computed_column '_year=year(age)' \ --kafka_conf properties.bootstrap.servers=127.0.0.1:9020 \ --kafka_conf topic=order \ --kafka_conf properties.group.id=123456 \ --kafka_conf value.format=canal-json \ --catalog_conf metastore=hive \ --catalog_conf uri=thrift://hive-metastore:9083 \ --table_conf bucket=4 \ --table_conf changelog-producer=input \ --table_conf sink.parallelism=4
kafka整庫同步:一個或多個topic同步到一個paimon庫
若一個topic中有不同的schema會自動拆分到多個表
<FLINK_HOME>/bin/flink run \ /path/to/paimon-flink-action-0.9-SNAPSHOT.jar \ kafka_sync_database \ --warehouse hdfs:///path/to/warehouse \ --database test_db \ --kafka_conf properties.bootstrap.servers=127.0.0.1:9020 \ --kafka_conf topic=order\;logistic_order\;user \ --kafka_conf properties.group.id=123456 \ --kafka_conf value.format=canal-json \ --catalog_conf metastore=hive \ --catalog_conf uri=thrift://hive-metastore:9083 \ --table_conf bucket=4 \ --table_conf changelog-producer=input \ --table_conf sink.parallelism=4
核心屬性
bucket
|
-1
|
-1是動態桶模式,大於0的數是固定桶數
|
|
bucket-key
|
資料根據桶key這些欄位的hash值進行分發,若有多個用逗號分隔,若不指定,有主鍵則預設用主鍵欄位,無主鍵則使用所有欄位
|
||
primary-key
|
|||
partition
|
分割槽鍵必須是主鍵的子集
|
分割槽
|
|
partition.expiration-time
|
Paimon定期檢查分割槽的狀態,並根據時間刪除過期的分割槽
|
||
partition.expiration-check-interval
|
1 h
|
檢查分割槽過期的間隔,比較分割槽時間與當前時間
|
|
partition.timestamp-formatter
|
|||
partition.timestamp-pattern
|
|||
file.format
|
|||
auto-create
|
false
|
若資料目錄不存在,是否自動建立
|
|
sequence.field
|
為主鍵表生成序列號的欄位,序列號確定哪些資料是最新的
|
||
snapshot.time-retained
|
1 h
|
已完成快照的最長時間保留,對於過期的snapshot,會無法做到其之後的增量讀取
|
|
snapshot.num-retained.min
|
10
|
要保留的已完成快照的最小數量
|
|
snapshot.num-retained.max
|
Integer.MAX_VALUE
|
要保留的已完成快照的最大數量
|
|
write-buffer-size
|
256 mb
|
在轉換為磁碟sst檔案前的記憶體使用量,增大可增加寫入效能
|
寫緩衝區
批次模式'execution.runtime-mode'='batch'也能提高寫入效能
|
write-buffer-spillable
|
是否寫緩衝區可溢位到磁碟,若使用物件儲存則預設開啟
|
||
write-buffer-spill.max-disk-size
|
infinite
|
寫緩衝區溢寫的最大磁碟佔用容量
|
|
sink.parallelism
|
writer並行度,為最佳化寫入效能應該最好等於bucket數
|
寫並行度
|
|
num-sorted-run.compaction-trigger
|
5
|
觸發compaction的sorted run數量,包括0級檔案(一個檔案一個sorted run)和高階runs(一個level一個sorted run)
|
合理透過SortedRun數量控制compact次數,權衡寫入、讀取效能和資源消耗
|
num-sorted-run.stop-trigger
|
觸發writer停止寫入的sorted run數量,會極大影響寫入效能,預設是'num-sorted-run.compaction-trigger'+3
|
||
write-only
|
false
|
若為true則在write階段忽略快照過期和compaction,與獨立的compact action結合使用
|
解耦write和compact
|
write-manifest-cache
|
0 bytes
|
減少重啟時與檔案系統的互動,提高manifest載入初始化速度
|
影響重啟時載入清單檔案的速度
|
scan.manifest.parallelism
|
掃描清單檔案的並行性,預設值為 CPU 處理器的大小。注意: 放大此引數將在掃描清單檔案時增加記憶體使用。當掃描時遇到記憶體不足異常時,我們可以考慮縮小它
|
||
scan.mode
|
default
|
|
|
read.batch-size
|
1024
|
對orc、parquet的批次讀大小,若有的行太大可適當減小
|
|
full-compaction.delta-commits
|
增量commit多少次後執行full compaction
注意對主鍵表、append-only表都有效
|
對於主鍵表,使用的是MOR來讀
若想查得足夠快但不需要多新的資料,指定本配置後,再配置scan.mode為compacted-full
|
|
compaction.max.file-num
|
50
|
對append-only無主鍵表,觸發compaction的最大小檔案數量
|
|
compaction.min.file-num
|
5
|
對append-only無主鍵表,若未達到此值則都不觸發compaction,防止對幾乎完整的檔案compact,防止過於頻繁的compact
|
|
deletion-vectors.enabled
|
開啟刪除向量特性可以在稍微影響寫入效能的情況下,不合並檔案即可獲取最新的資料,可有效提高讀取效能
|
||
continuous.discovery-interval
|
10 s
|
持續讀的發現間隔
|
|
streaming-read-overwrite
|
false
|
是否在流模式讀insert overwrite產生的變更,不能在changelog-producer為full-compaction或lookup使用
|
|
scan.split-enumerator.batch-size
|
10
|
在 StaticFileStoreSplitEnumerator 中,為了避免超過'akka.framesize'限制,應該為每個子任務一次分配多少個split
|
1、changelog-producer
- 'full-compaction', 對比兩次full compaction後的結果生成完整的changelog,頻率取決於full compaction的生成間隔,成本低
- 'changelog-producer.compaction-interval' = '' 在此時間區間內會至少執行一次full compaction,推薦3-10min時延
- lookup 在提交資料寫入前透過lookup LSM tree生成changelog檔案,推薦1-3min時延,成本高
- lookup.cache-file-retention
- lookup.cache-max-disk-size
- lookup.cache-max-memory-size
- 'input' 會在儲存層LSM檔案之外直接持久化cdc流成changelog檔案
- 'none' 增加一個normalize單並行度高消耗運算元,不會生成changelog檔案
2、merge-engine
(1)deduplicate 預設
去重且保留主鍵的最新資料
(2)partial-update支援部分更新
雙流join儲存所有state成本過高但結果準確、維表join成本低但無法應對維表更新的資料,透過在儲存層面支援Partial Update解決join問題
指定sequence.field無法解決多流部分更新的亂序問題,因為會互相影響,因此引入sequence-group機制,每個流都可以定義自己的sequence-group,且是真正的部分更新,指定的sequence-group欄位的值為空或更小,將不更新對應的欄位
'fields.g_1.sequence-group'='a,b' 若g_1為空或更小,則不更新a b兩個欄位
(3)aggregation
對除鍵外的所有列的資料的最近結果與新來的資料一一聚合,注意所有非主鍵列都要指定fields..aggregate-function表屬性
CREATE TABLE MyTable ( product_id BIGINT, price DOUBLE, sales BIGINT, PRIMARY KEY (product_id) NOT ENFORCED ) WITH ( 'merge-engine' = 'aggregation', 'fields.price.aggregate-function' = 'max', 'fields.sales.aggregate-function' = 'sum' );
(4)first-row
保留相同鍵的第一行資料,只會產生append cdc流。
7、Deletion vectors
設計是為了兼顧寫入、讀取的效率。該模式下,寫入時會引入額外的開銷(查詢LSM Tree並生成對應的Deletion File),但讀取時可以直接使用有刪除向量的資料找回資料,避免了不同檔案之間額外的merge開銷。總體來說,在這種模式下,我們可以在不損失太多寫入效能的情況下,獲得巨大的讀取效能提升。
'deletion-vectors.enabled' = 'true'
安裝
1、打包成fat包,拷到flink/lib目錄
mvn clean package -DskipTests
2、配置HADOOP_CLASSPATH或拷https://flink.apache.org/downloads.html裡的預編譯hadoop jar包到flink/lib
3、修改conf/config.yaml,numberOfTaskSlots: 8,比1大的值
執行
set 'execution.runtime-mode'='batch'; //批模式,跑得更快些 create catalog paimon1 with ('type'='paimon','warehouse'='file:///home/rick/data/paimon1'); use catalog paimon1; CREATE TABLE my_table ( product_id BIGINT, price DOUBLE, sales BIGINT ) WITH ( 'file.compression' = 'zstd' ); CREATE TABLE MyTable ( user_id BIGINT, item_id BIGINT, behavior STRING, dt STRING, PRIMARY KEY (dt, user_id) NOT ENFORCED ) PARTITIONED BY (dt) WITH ( 'bucket' = '4', 'file.format' = 'parquet' ); insert into MyTable values (1,2,'a','part1'); insert into MyTable partition (dt='part2') values (2,3,'a'); set 'execution.checkpointing.interval'='20s'; set 'execution.runtime-mode'='streaming'; --kafka CREATE TABLE t1 (id int,name string) WITH ( 'log.system' = 'kafka', 'kafka.bootstrap.servers' = 'localhost:9092', 'kafka.topic' = 'topic1' );