阿里面試:Paimon 只保留兩天的快照,如何關(guān)聯(lián)昨天的數(shù)據(jù)?
在數(shù)據(jù)處理和管理中,Paimon作為一種流批統(tǒng)一的數(shù)據(jù)湖存儲(chǔ)格式,結(jié)合Flink可以構(gòu)建流批處理的實(shí)時(shí)湖倉(cāng)一體架構(gòu),具有實(shí)時(shí)更新的能力,其主鍵表支持大規(guī)模更新寫(xiě)入,具有非常高的更新性能,同時(shí)也支持定義合并引擎,按照自定義的方式更新記錄。然而,Paimon的快照只保存兩天,這給關(guān)聯(lián)昨天的數(shù)據(jù)帶來(lái)了一定的挑戰(zhàn)。下面將詳細(xì)介紹如何關(guān)聯(lián)Paimon快照中昨天的數(shù)據(jù)。

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





























