阿里面試:Paimon 只保留兩天的快照,如何關聯昨天的數據?
在數據處理和管理中,Paimon作為一種流批統一的數據湖存儲格式,結合Flink可以構建流批處理的實時湖倉一體架構,具有實時更新的能力,其主鍵表支持大規模更新寫入,具有非常高的更新性能,同時也支持定義合并引擎,按照自定義的方式更新記錄。然而,Paimon的快照只保存兩天,這給關聯昨天的數據帶來了一定的挑戰。下面將詳細介紹如何關聯Paimon快照中昨天的數據。
一、Paimon快照概述
1. 快照的定義
快照(Snapshot)是在某個時間點上捕捉表狀態的方式。在Paimon中,每當進行數據更改或提交操作時,會生成一個新的快照來記錄當前表的狀態。用戶可以通過最新的快照訪問表的最新數據,也可以通過較早的快照訪問表的先前狀態。例如,在Flink Checkpoint時Paimon會產生1 - 2個Snapshot,這取決于Paimon在這個過程中是否有進行過Compaction,但至少會產生一個Snapshot來作為新的數據版本,通過定義Checkpoint Interval來控制Snapshot的生成。
2. 快照的保留期限
Paimon的快照數據默認具有保留期限,具體取決于Paimon的配置選項 snapshot.time - retained,通常默認是1小時。在超過這個保留時間后,舊快照會被清理以釋放存儲空間。因此,一旦這些快照被刪除或回收,就無法再使用time travel功能訪問這些已刪除快照對應的歷史數據。如果需要延長快照保留時間以支持更長時間的time travel,可以調整 snapshot.time - retained 配置參數。例如,將配置設置為 snapshot.time - retained = 24h,這會將快照的保留時間設置為24小時,允許在更長時間內進行數據回溯。但由于Paimon快照只保存兩天,我們需要在這個時間范圍內想辦法關聯昨天的數據。
二、關聯昨天數據的方法
1. 利用Tag功能
Paimon的Tag功能允許用戶基于快照創建標簽,以保留歷史數據。由于Paimon表會根據配置自動過期舊的快照,導致歷史數據無法查詢。通過Tag功能,用戶可以為特定的快照創建標簽,從而保留該快照對應的數據文件和元數據,以便后續查詢歷史數據。Tag功能特別適用于需要按天或按小時保留歷史數據的場景。
(1) 創建Tag
用戶可以為指定的快照創建Tag。Tag會保留該快照的所有數據文件和元數據,確保歷史數據可查詢。語法示例如下:
CALL sys.create_tag('default.T','my_tag',10,'1 d')
參數說明:
- identifier(標識符):目標表的標識符,不能為空。形如 dbName.tableName 格式。
- tagName(標簽名):新建tag的名稱。
- snapshotId(長整型):新建標簽所基于的快照的ID(標識號)。null 代表從最新快照創建。
- time_retained(保留時間):為新創建標簽保留的最長時間。
(2) 關聯昨天的數據
如果昨天的快照還未過期,我們可以為昨天對應的快照創建Tag。首先,需要確定昨天快照的ID。可以通過系統表或者日志信息來查找。假設我們已經確定了昨天快照的ID為 yesterday_snapshot_id,則可以使用以下語句創建Tag:
CALL sys.create_tag('your_database.your_table','yesterday_tag', yesterday_snapshot_id,'1 d')
這樣,我們就為昨天的快照創建了一個名為 yesterday_tag 的標簽,后續可以通過這個標簽來查詢昨天的數據。
2. 利用時間旅行功能
Paimon支持時間旅行(Time Travel)功能,允許用戶查詢歷史快照或Tag對應的數據。
(1) 批查詢
在批作業開發模式下,可以使用以下方法查詢指定快照的數據:
查詢最新快照數據:按照經典的 Select 語句從表中讀取數據,不指定Tag和快照ID等信息,就是默認從最新快照查詢。
SELECT*FROM t;
批查詢Time Travel:可以指定一個快照或者一個標簽,并讀取相應的數據。
-- 讀取ID為1的快照
SELECT*FROM t /*+ OPTIONS('scan.snapshot - id' = '1') */;
-- 從指定的Unix毫秒時間戳讀取快照
SELECT*FROM t /*+ OPTIONS('scan.timestamp - millis' = '1678883047356') */;
-- 從指定的時間戳字符串讀取快照,會自動轉換為Unix毫秒時間戳
-- 支持的格式包括:yyyy - MM - dd, yyyy - MM - dd HH:mm:ss, yyyy - MM - dd HH:mm:ss.SSS,使用默認本地時區
SELECT*FROM t /*+ OPTIONS('scan.timestamp' = '2023 - 12 - 09 23:09:12') */;
-- 從watermark讀取快照,將匹配watermark之后的第一個快照
SELECT*FROM t /*+ OPTIONS('scan.watermark' = '1678883047356') */;
-- 從某一個Tag讀取數據
SELECT*FROM t /*+ OPTIONS('scan.tag - name' = 'my - tag') */;
如果我們已經為昨天的快照創建了Tag,假設Tag名為 yesterday_tag,則可以使用以下語句查詢昨天的數據:
SELECT*FROM your_table /*+ OPTIONS('scan.tag - name' = 'yesterday_tag') */;
查詢兩個Tag之間的增量數據:可以讀取起始快照(不包括)和結束快照之間的增量變化。
-- 快照ID之間的增量變化
SELECT*FROM t /*+ OPTIONS('incremental - between' = 'tag1,tag3') */;
-- 快照時間戳(毫秒)之間的增量變化
SELECT*FROM t /*+ OPTIONS('incremental - between - timestamp' = '1692169000000,1692169900000') */;
(2) 流式查詢
在流作業開發模式下,也可以進行時間旅行查詢。如果當前Paimon表是一個分區表,如果只想處理今天及以后的數據,可以使用分區過濾器。如果不是一個分區表,或者無法按分區過濾,可以使用時間旅行的流式讀取。例如:
-- 從快照ID 1L讀取更改
SELECT*FROM your_table WHERE.../* 結合時間條件 */
三、注意事項
1. 快照過期問題
雖然Paimon快照只保存兩天,但如果在某些情況下,由于系統資源緊張或者配置不合理,可能會導致昨天的快照提前過期。因此,在關聯昨天的數據之前,最好先檢查快照的狀態,確保昨天的快照仍然可用。可以通過查看系統表或者日志信息來確認。
2. 性能問題
利用Tag功能和時間旅行功能進行數據查詢時,可能會對系統性能產生一定的影響。尤其是在查詢大量歷史數據時,可能會導致查詢時間過長。因此,在實際應用中,需要根據具體情況進行性能優化,例如合理設置Tag的保留時間,避免保留過多不必要的歷史數據。
3. 數據一致性問題
在多用戶并發寫入操作的情況下,可能會出現數據一致性問題。Paimon使用兩階段提交協議來實現對數據的原子提交,每次提交會在提交時生成一個新的快照,最多生成兩個快照。對于任意兩個同時修改表的writer,只要他們不修改同一個存儲桶,他們的提交都是可序列化的。如果他們修改了同一個存儲桶,則僅保證快照隔離性。也就是說,最終的表狀態可能是兩次提交的混合,但不會丟失任何更改。在關聯昨天的數據時,需要考慮這些因素,確保查詢到的數據是準確和一致的。
綜上所述,要關聯Paimon快照中昨天的數據,可以利用Paimon的Tag功能和時間旅行功能。在實際應用中,需要根據具體情況選擇合適的方法,并注意快照過期、性能和數據一致性等問題。