回填 Feature Views

回填會重新計算你選擇的時間範圍內特徵視圖的實體化值。 在校正或新增歷史來源資料後使用,讓離線與線上的具體化結果反映更新後的資料。

Materialization 會計算每次執行時最近的特徵值,不會回頭檢視已經寫入的值。 過去某個時間範圍的來源資料變更,只有在你補填該時間範圍後,才會反映到具體化值中。 在以下情境下使用回填:

  • 上游資料品質問題影響了過去的時間範圍,你修正了來源列。
  • 過去時間範圍的來源資料是在實體化處理完之後才到達的。

回填是一次性的工作,與預定的具體化同時進行。 這不會改變具體化的時間表。 請參見 Materialize 特徵視圖。

Requirements

  • databricks-feature-engineering 0.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。

  • 每個特徵檢視都符合 需求,包括完成的具體化執行。
  • 你把每個 Feature View 都實體化了。
  • 你擁有 所需的權限。

該方法回傳描述回填物的 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 和 a SlidingWindow 或 TumblingWindow 的批次聚合功能才能被回填。 串流功能、ColumnSelection 功能、帶有 RollingWindow 或 SawtoothWindow 的功能、具有永久期間視窗的功能,以及具有其他來源(例如 RequestSource)的功能,皆無法回填。
  • 產生不同區間或偏移量的特徵視圖無法共用一個回填。 為每個群組分別啟動回填。
  • 回填更新功能檢視的離線表格,若功能檢視同時實體化到線上商店,也會更新其線上表格。 你不能只回填其中一個。
  • 回填不會填滿最近實體化值之後的時間範圍。 你預定的具體化會填入其中。