回填會重新計算你選擇的時間範圍內特徵視圖的實體化值。 在校正或新增歷史來源資料後使用,讓離線與線上的具體化結果反映更新後的資料。
Materialization 會計算每次執行時最近的特徵值,不會回頭檢視已經寫入的值。 過去某個時間範圍的來源資料變更,只有在你補填該時間範圍後,才會反映到具體化值中。 在以下情境下使用回填:
- 上游資料品質問題影響了過去的時間範圍,你修正了來源列。
- 過去時間範圍的來源資料是在實體化處理完之後才到達的。
回填是一次性的工作,與預定的具體化同時進行。 這不會改變具體化的時間表。 請參見 Materialize 特徵視圖。
Requirements
-
databricks-feature-engineering0.18.2 及以上。 其他要求請參見 需求。 - 每個特徵檢視都是一個批次聚合功能,使用
DeltaTableSource和SlidingWindow或TumblingWindow。 不支援永久視窗。 - 每個 Feature View 都已具現化,且至少完成一次實體化運行。 回填會重新計算實體化已經寫入的數值,因此無法首次實體化特徵視圖。
- 你要以具現化 Feature Views 的相同使用者或服務主體身分,從這些 Feature Views 具現化所在的工作區開始回填。
權限
回填會以你的身分執行,它讀寫與你的實體化相同的資料表,因此使用與你的實體化相同的權限。 欲了解完整的 Unity 目錄權限描述,請參閱 Unity 目錄權限參考。
- 你所回填的每個功能檢視都必須有
MANAGE。 - 要檢查回填,你需要在回填中的每個特徵檢視上都有
READ FEATURE。 若要取消回填,你需要對回填中的每個 Feature View 執行MANAGE。
開始回填
要開始回填,請呼叫 backfill_features,並傳入要回填的特徵視圖(Feature Views)和一個或多個時間範圍:
FeatureEngineeringClient.backfill_features(
*, # Arguments are keyword-only
features: List[Union[str, Feature]], # Feature Views to backfill, as Feature objects or full names
backfill_ranges: List[BackfillRange], # Time ranges of source data to reprocess
request_id: Optional[str] = None, # Idempotency token, a UUID
tags: Optional[Dict[str, str]] = None, # Custom tags for cost attribution
budget_policy_id: Optional[str] = None, # Serverless usage policy for cost attribution
wait: bool = False, # Wait for the backfill to finish
) -> BackfillStatus:
同一呼叫中的所有特徵視圖都必須在相同的時間點產生數值。 它們的值之間必須具有相同的間隔(即 window_duration 的 slide_duration 或 TumblingWindow 的 SlidingWindow),以及相同的 offset。 否則,呼叫會失敗,並顯示錯誤訊息,要求依區間將特徵檢視分組,讓你可以為每個群組分別開始回填。
每個 BackfillRange 都有一個 start_time(為包含式),以及一個 end_time(為排他式)。 兩者都是 Python datetime 值。 沒有時區的 A datetime 會被視為 UTC。 每個 start_time 都必須早於其 end_time,且同一次呼叫中的範圍不能重疊。 關於回填如何解釋每個範圍,請參見 回填如何應用時間範圍。
以下範例為兩個 Feature View 回填一週的歷史:
from datetime import datetime, timezone
from databricks.feature_engineering import FeatureEngineeringClient
from databricks.feature_engineering.entities import BackfillRange
fe = FeatureEngineeringClient()
backfill = fe.backfill_features(
features=[
"main.feature_store.amount_sum_sliding_7d_1d",
"main.feature_store.transaction_count_sliding_7d_1d",
],
backfill_ranges=[
BackfillRange(
start_time=datetime(2026, 3, 1, tzinfo=timezone.utc),
end_time=datetime(2026, 3, 8, tzinfo=timezone.utc),
)
],
)
print(backfill.operation_name) # operations/<operation-id>
在開始回填前,backfill_features 會檢查以下事項。 若檢查失敗,呼叫即告失敗,錯誤訊息會指出受影響的 Feature Views。
該方法回傳描述回填物的 BackfillStatus。 其 operation_name 可識別回填,格式為 operations/<operation-id>。 請參閱監視或取消回填。
為了讓此呼叫可安全重試,請將 UUID 傳遞為 request_id。 用同樣的 request_id 重試會回傳原本的回填,而不是重新開始新的回填。
若要將回填成本歸因,請傳遞 tags、budget_policy_id 或兩者。 它們只適用於該回填資料。 請參見 具有標籤和無伺服器使用政策的屬性成本。
回填如何套用時間範圍
每個範圍選擇要重新處理的來源資料:來源列的時間戳記在 start_time 或之後,且在 end_time 之前。 回填對每個範圍的套用方式如下:
- 範圍與整數特徵值對齊。 回填會重新計算整個特徵的值,因此會將每個範圍向外擴展到特徵產生值時最近的時間點。 特徵
SlidingWindow會每個slide_duration產生一個值,而特徵TumblingWindow會每個window_duration產生一個值;若有設定,則會依視窗的offset位移。 例如,一個長度為 1 小時slide_duration的功能,從凌晨 1:30 到 2:30 的範圍會變成凌晨 1:00 到 3:00。 你不需要自己對齊範圍。 在對齊後重疊的範圍會合併為一個。 - 超出範圍的值可能會改變。 回填會重寫所有包含重新處理資料的時間窗特徵值。 視窗可以在
end_time之後結束,因此在end_time之後一個window_duration內的值都可能變更。 例如,對於具有 7 天window_duration的功能,在end_time之後最多 7 天內,數值可能會改變。 - 回填會停止在最近的實體化值。 回填只會重新計算實體化已經寫入的歷史。 如果某個區間超過最近具體化的值,回填會停止於此,並將較晚的時間範圍留給你排程的具體化作業。
- 未設定的界限延伸到可用資料範圍。 如果你省略
start_time了 ,範圍會從來源資料中最早的時間戳開始。 若省略end_time,範圍延伸至最近具體化的數值。
backfill_ranges 的 BackfillStatus 是對齊後的範圍。 回填不會將其縮小到最近具體化的數值,因此報告範圍可能超出回填重新計算的數值。 你不需要回填後面的數值,因為已排程的具體化作業會根據目前的來源資料計算這些數值。
離線與線上資料表
回填會更新功能檢視的離線表格,若功能檢視同時實體化到線上商店,也會更新其線上表格。 對於同時擁有兩者的功能檢視,回填會重新計算離線資料表,然後再從中重新發布線上資料表。 你不能只補其中一個。
線上表格中顯示每個實體的最新數值。 回填只有在改變實體最新值時才會改變線上值。
監視或取消 backfill
backfill_features 不必等待回填完成就會返回。 等待、略過 wait=True,或以回傳的狀態呼叫 wait_for_backfill:
backfill = fe.wait_for_backfill(backfill=backfill)
wait_for_backfill 會在回填成功時傳回最終的 BackfillStatus。 若回填失敗或被取消,則會引發 OperationFailed 錯誤,說明原因。 為了限制等待時間,將 timeout 作為 timedelta 傳遞。 如果回填尚未完成,則 wait_for_backfill 會引發 TimeoutError。 停止等待並不會取消回填。
若想在不等待的情況下檢查回填,或從另一個筆記本或作業中呼叫,請使用作業名稱呼叫 get_backfill:
backfill = fe.get_backfill(operation_name="operations/<operation-id>")
print(backfill.state) # For example, BackfillState.RUNNING
A BackfillStatus 具有以下欄位:
-
operation_name:這個名稱用來識別回填。 -
state:回填物的狀態,作為一個BackfillState值。 -
feature_full_names:回填中的特徵視圖全名。 -
backfill_ranges:對齊的時間範圍,以 UTC 為界的BackfillRange值。 -
error:回填失敗的原因。 此欄位僅在state為FAILED時設定。
回填狀態為以下數值之一:
| State | Description |
|---|---|
PENDING |
回填已獲接受,至今尚未開始運作。 |
RUNNING |
資料回填正在執行中。 |
SUCCEEDED |
回填已完成,並重新計算其範圍內的特徵值。 |
FAILED |
回填因錯誤而停止。 參見 從失敗的回填中恢復。 |
CANCELLED |
回填作業在完成前就被取消了。 |
如果沒有操作名稱,請在 list_materialized_features 欄位中找出由 latest_backfill_operation 傳回的實體化特徵最近一次回填,並將其傳給 get_backfill。
若要取消回填,請呼叫 cancel_backfill 並附上其狀態:
fe.cancel_backfill(backfill=backfill)
取消回填會請求停止回填。 即將完成的回填仍可能成功,因此請用 get_backfill來檢查其最終狀態。 取消已經完成的回填作業沒有效果。 取消的回填可能會讓部分特徵值重新計算,如從失敗的回填中復原所述。
Concurrency
回填會與預定的具體化同時進行。 不同功能視圖的回填也可以同時執行。
一次只能為一個 Feature View 執行一個回填。 如果你開始為已經有回填正在進行的功能檢視進行回填,請求會因 ALREADY_EXISTS 錯誤而失敗。 等上一次回填完成後再開始下一次。
從失敗的 backfill 復原
失敗或取消的回填可能會在完成前就停止。 回填在停止前重寫的每個值都會被完全重新計算。 它未達到的值會保留先前的值,因此某些功能檢視或時間範圍可能不會更新。
若要復原,請再次啟動相同的回填作業。 如果您已傳遞一個 request_id,請改為傳遞新的,因為使用原本的 request_id 重試時,會傳回失敗的 backfill 作業,而不是重新開始新的作業。 回填是安全的,可以重複執行。 如果來源資料沒有改變,重新計算已經成功的範圍會產生相同的數值。
Limitations
- 只有使用 a
DeltaTableSource和 aSlidingWindow或TumblingWindow的批次聚合功能才能被回填。 串流功能、ColumnSelection功能、帶有RollingWindow或SawtoothWindow的功能、具有永久期間視窗的功能,以及具有其他來源(例如RequestSource)的功能,皆無法回填。 - 產生不同區間或偏移量的特徵視圖無法共用一個回填。 為每個群組分別啟動回填。
- 回填更新功能檢視的離線表格,若功能檢視同時實體化到線上商店,也會更新其線上表格。 你不能只回填其中一個。
- 回填不會填滿最近實體化值之後的時間範圍。 你預定的具體化會填入其中。