バックフィル機能のビュー

バックフィルは、選択した時間範囲にわたってフィーチャービューの実体化された値を再計算します。 履歴ソース データを修正または追加した後に使用し、オフラインおよびオンラインの実体化が更新されたデータを反映するようにしてください。

実体化は、各実行時に最新の特徴量の値をコンピューティングし、すでに書き込んだ値には再度アクセスしません。 過去の時間範囲のソースデータの変更は、その時間帯をバックフィルするまでマテリアライズド値には反映されません。 バックフィルは、以下のような状況で使用します。

  • アップストリームのデータ品質の問題が過去の期間に影響を及ぼしましたが、ソース行を修正しました。
  • 過去の時間範囲のソースデータは、マテリアライゼーションがすでにそれを処理した後に届いた。

バックフィルは、予定されたマテリゼーションと並行して行われる一度きりの作業です。 マテリアライゼーションスケジュールは変わりません。 「 フィーチャ ビューを具体化する」を参照してください。

Requirements

  • databricks-feature-engineering 0.18.2以上。 その他の要件については「要件」を参照してください。
  • 各フィーチャービューは、 DeltaTableSource と SlidingWindow または TumblingWindowを使ったバッチ集約機能です。 有効期限なしのウィンドウはサポートされていません。
  • 各フィーチャービューはマテリアル化されており、少なくとも1回のマテリアライズランを完了しています。 バックフィルはマテリアル化がすでに書き込んだ値を再計算するため、初めてフィーチャービューをマテリアル化することはできません。
  • フィーチャー ビューを実体化したのと同じユーザーまたはサービス プリンシパルとして、そのフィーチャー ビューが実体化されているワークスペースから、バックフィルを開始します。

Permissions

バックフィルはユーザーとして実行され、実体化と同じテーブルを読み書きするため、実体化と同じ権限を使用します。 Unity Catalogの特権に関する詳細な説明については、 Unity Catalog Privileges referenceを参照してください。

  • バックフィルする各フィーチャービューに必ず MANAGE が必要です。
  • バックフィルを確認するには、そのバックフィルに含まれるすべてのフィーチャー ビューで READ FEATURE が必要です。 バックフィルをキャンセルするには、そのバックフィルに含まれるすべてのフィーチャー ビューで MANAGE が必要です。

バックフィルを開始する

バックフィルを開始するには、バックフィルする Feature Views と 1 つ以上の時間範囲を指定して backfill_features を呼び出してください:

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:

1回の呼び出し内のすべてのフィーチャービューは同じ時刻の値を生成しなければなりません。 それらは、値間の間隔 (SlidingWindow の slide_duration や TumblingWindow の window_duration) および offset が同じである必要があります。 これに該当しない場合、呼び出しはエラーで失敗し、フィーチャービューが区間ごとにグループ化されるため、グループごとに個別のバックフィルを開始できるようになります。

各 BackfillRange には、包含的な start_time と、排他的な end_time があります。 どちらも Python datetime の値です。 タイムゾーンのない datetime はUTCとして解釈されます。 各 start_time は end_time より前でなければならず、1回の呼び出し内の範囲は重複してはなりません。 バックフィルが各範囲をどのように解釈するかについては、「 バックフィルが時間範囲を適用する方法」を参照してください。

以下の例は、2つのフィーチャービューの1週間の履歴を埋め戻しています:

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 は次の点を確認します。 チェックに失敗した場合、影響を受けたフィーチャー ビューの名前が記載されたエラー メッセージが表示され、呼び出しは失敗します。

  • 各フィーチャー ビューは、実体化の実行が完了していることを含め、要件を満たしています。
  • 各フィーチャービューをマテリアライズしました。
  • 必要な権限を持っています。

メソッドはバックフィルを説明する BackfillStatus を返します。 その operation_name は、operations/<operation-id> という形式でバックフィルを識別します。 バックフィルを監視またはキャンセルするを参照してください。

再試行を安全にするために、 request_idとしてUUIDをパスしてください。 同じ request_id で再試すと、新しいバックフィルを始めるのではなく元のバックフィルが戻ってきます。

バックフィルのコストを割り当てるには、tags、budget_policy_id、またはその両方を指定してください。 それらはその埋め戻しにのみ適用されます。 詳細は、タグ付き属性コストとサーバーレス利用ポリシーを参照してください。

時間範囲がバックフィルにどのように適用されるか

各範囲は、再処理の対象となるソースデータ (タイムスタンプが start_time 以降かつ end_time 以前のソース行) を選択します。 バックフィルは各範囲ごとに次のように適用されます。

  • 範囲は、フィーチャ値の整数値に合わせて調整されます。 バックフィルは特徴値全体を再計算するため、各範囲を外側に広げて、特徴が値を生成する最も近い時刻まで拡張します。 SlidingWindow特徴はslide_durationごとに値を生成し、TumblingWindow特徴はoffsetごとに値を生成し、設定した場合はウィンドウのwindow_durationだけシフトされます。 たとえば、slide_duration が 1 時間のフィーチャーの場合、午前 1 時 30 分から午前 2 時 30 分までの範囲は、午前 1 時から午前 3 時までとなります。 自分でレンジを合わせる必要はありません。 アライメント後に重なり合う範囲は一つにまとめられます。
  • 範囲以降の値は変わることがあります。 バックフィルは、再処理データを含む時間ウィンドウを持つすべての特徴値を書き換えます。 ウィンドウはend_timeで終了することがあるため、window_durationの後の1end_timeまで値は変わることがあります。 例えば、7日間の window_duration を持つ機能の場合、end_time後、最大7日間は値が変わる可能性があります。
  • 埋め戻しは最新の実体化値で停止します。 バックフィルは、マテリアライゼーションがすでに書き込んだ履歴のみを再計算します。 もし範囲が最新のマテリアライズド値を超えて広がると、バックフィルはそこで止まり、後の時間範囲は予定されたマテリアライズに任せます。
  • 未設定の境界は利用可能なデータの範囲まで広がります。 start_timeを省略すると、範囲はソースデータの最も早いタイムスタンプから始まります。 end_timeを省略すると、範囲は最新の物質化された値まで拡張されます。

BackfillStatus の backfill_ranges は、アライメント後の範囲です。 バックフィルは最新の物質化された値に絞り込むわけではないので、報告範囲はバックフィルが再計算した値を超えて広がることがあります。 後続の値はバックフィルする必要はありません。なぜなら、スケジュールされたマテライゼーションは現在のソースデータからそれらを計算するからです。

オフラインおよびオンラインテーブル

バックフィルはフィーチャービューのオフラインテーブルを更新し、フィーチャービューがオンラインストアにも具現化されている場合は、そのオンラインテーブルを更新します。 両方を持つフィーチャービューの場合、バックフィルはオフラインテーブルを再計算し、そこからオンラインテーブルを再公開します。 一方だけをバックフィルすることはできません。

オンライン表には各事業体の最新の数値が記載されています。 バックフィルは、エンティティの最新の値を変更する場合にのみオンライン値を変更します。

埋め戻しを監視またはキャンセルする

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

BackfillStatusは以下のフィールドを持ちます:

  • operation_name:埋め戻し地を識別する名前です。
  • state:埋め戻しの状態を BackfillState 値として示します。
  • feature_full_names: バックフィルに含まれるフィーチャー ビューの正式名称。
  • backfill_ranges: 整列された時間範囲は、UTC を基準とする BackfillRange 値として表されます。
  • error埋め戻しが失敗した理由です。 このフィールドは state が FAILED の場合のみ設定されます。

バックフィル状態は以下のいずれかの値です:

状態 Description
PENDING バックフィルは承認され、まだ稼働は始まっていません。
RUNNING バックフィルが実行中です。
SUCCEEDED バックフィルが完了し、その範囲内のフィーチャ値が再計算されました。
FAILED 埋め戻しはエラーが発生したため停止しました。 失敗したバックフィルから回復するを参照してください。
CANCELLED バックフィル作業は完了する前に中止されました。

操作名がない場合は、latest_backfill_operationが返すlist_materialized_featuresフィールド内のマテリアライズド フィーチャの最新のバックフィルを見つけて、get_backfillに渡してください。

バックフィルをキャンセルするには、そのステータスを伝えて cancel_backfill に電話してください:

fe.cancel_backfill(backfill=backfill)

バックフィルをキャンセルすると、処理の停止を要求します。 完了間近のバックフィルでも成功することがあるので、get_backfill で最終状態を必ず確認してください。 すでに完了したバックフィルをキャンセルしても効果はありません。 キャンセルされたバックフィルは、失敗したバックフィルからの復旧で説明されているように、一部の特徴値が再計算されたままになることがあります。

Concurrency

バックフィルは、予定されている実体化と並行して実行されます。 異なるフィーチャービューのバックフィルも同時に実行可能です。

フィーチャービューで一度に1つのバックフィルしか実行できません。 すでにバックフィルが進行中のフィーチャービューのバックフィルを開始すると、リクエストは ALREADY_EXISTS エラーで失敗します。 前のバックフィルが終わるまで待ってから次のバックフィルを始めましょう。

バックフィルの失敗から回復

失敗した、またはキャンセルされたバックフィルは、完了する前に停止することもあります。 バックフィルが停止する前に書き換えた各値は完全に再計算されます。 到達しなかった箇所の値は以前の値を保持するため、一部のフィーチャービューや時間帯が更新されないことがあります。

復旧するには、同じバックフィル作業を再度開始します。 request_idを渡した場合は、新しいものを渡してください。元のrequest_idで再試行すると、新しいバックフィルを開始するのではなく、失敗したバックフィルが返されます。 埋め戻しは繰り返しても安全です。 元のデータが変わっていなければ、すでに成功した範囲を再計算しても同じ値が得られます。

Limitations

  • DeltaTableSource および SlidingWindow または TumblingWindow を使用するバッチ集計機能のみ、バックフィルが可能です。 ストリーミング フィーチャー、ColumnSelection フィーチャー、RollingWindow または SawtoothWindow を持つフィーチャー、ライフタイム ウィンドウを持つフィーチャー、および RequestSource などの他のソースを持つフィーチャーは、バックフィルできません。
  • 異なる区間やオフセットで値を生成するフィーチャービューは、同じバックフィルを共有することはできません。 各グループごとに別々のバックフィルを開始します。
  • バックフィルはフィーチャービューのオフラインテーブルを更新し、フィーチャービューがオンラインストアにも具現化されている場合は、そのオンラインテーブルを更新します。 一方だけをバックフィルすることはできません。
  • バックフィルは、最新の実体化値以降の時間範囲を埋めることはありません。 予定された実体化がそれらを満たします。