このアーキテクチャは、オンラインサービングとオフライントレーニングの問題を厳密に分離するデュアルストアパターンを採用しています。オンライン層は、各リージョン内にデプロイされたNVMeベースのインスタンス上のRedis Clusterを使用し、Envoy ProxyがローカルロードバランシングとTLS終了処理を行います。機能更新は、変更ログとして機能するApache Kafkaを経由して流れ、Debezium CDCコネクタが運用データベースからの変異をキャプチャして地域のRedis消費者にストリーミングします。
オフラインストレージでは、過去の機能がS3上のApache Icebergテーブルに圧縮され、時間旅行クエリを可能にし、Apache Sparkを介して効率的なバッチ処理を実現します。バックフィル中の一貫性は、ベクトルクロックのバージョン管理を通じて達成されます:各機能値には論理的なタイムスタンプが付与され、Redis Luaスクリプトが原子比較と置換操作を実行して順序違いの書き込みを拒否し、サービングパスが部分的なバックフィル状態を決して観察しないようにします。
ドリフト検出は、Prometheusヒストグラムを利用して行われ、Apache Flinkジョブが機能分布に対するリアルタイムの統計解析を実行します。KLダイバージェンスまたは人口安定性指数がしきい値を超えると、FlinkがArgo Workflowsをトリガーし、クロスリージョンのモデル再訓練とカナリアデプロイメントを調整します。
ある多国籍フィンテック企業は、AWS、Azure、およびオンプレミスデータセンター全体でリアルタイムの詐欺検出機能を必要としていました。重要な課題は、ユーザーの取引速度のようなロールアップ集計機能を、サブ5msのレイテンシーで推論エンドポイントに提供することでした。既存のPostgreSQLレプリカは、ピーク負荷中に200msを超える複製遅延に悩まされており、詐欺スコアリングモデルが古いデータで操作され、協調攻撃を見逃すことになっていました。
解決策1:グローバルアクティブ-アクティブデータベース CockroachDBまたはGoogle Spannerをデプロイすることで、直列隔離と自動グローバル複製を約束しました。このアプローチは一貫性の問題を排除しましたが、Paxosコンセンサスのオーバーヘッドにより、クロスリージョンの書き込みレイテンシーが100msを超えるという問題を引き起こしました。新しいトランザクションを即座に可視化することが求められる高バイタリティ機能にとって、このレイテンシーは受け入れられないものでした。さらに、運用コストは読み取りスループットに応じて二次的に増加し、ミリ秒レベルのサービング要件には経済的に実現不可能でした。
解決策2:地域キャッシュによる最終的一貫性 地域ごとの独立したRedisクラスターを実装し、Kafka MirrorMakerを介した非同期複製により、優れた読み取り性能と線形スケーラビリティを提供しました。しかし、これによりデータサイエンティストがデータ品質の問題を修正するために履歴機能を再計算するバックフィル操作中に重要な一貫性脆弱性が生じました。厳密なバージョン保証がない状態では、システムが新しい集計値と古い集計値の両方を提供し、モデル推論の歪みと合法的な取引を誤ってフラグするリスクスコアを引き起こしました。
解決策3:ベクトルクロックを伴う階層的キャッシュ(選択) 私たちは、Redisをホット層として、Kafkaを不変の真実のソースとして使用する階層的システムを設計しました。各機能値には、取り込みパイプラインから派生したベクトルクロックのタイムスタンプが付与されました。バックフィル中に、SparkジョブはS3に書き込みながら、バージョン化されたイベントをKafkaに発信しました。地域の消費者は、サーバーサイドのベクトルクロック比較を行うRedis Luaスクリプトを使用して更新を適用し、順序違いの書き込みを原子的に拒否し、新しいバージョンを受け入れました。ドリフト検出のために、Prometheusヒストグラムを介して機能分布を計測し、Flinkにフィードしてトレーニングの基準に対するリアルタイムの統計的比較を行いました。
その結果、グローバルにP99サービングレイテンシーが1.2msに削減され、バックフィル中の一貫性違反が排除され、94%のモデル劣化のインシデントが自動ドリフトトリガー再訓練パイプラインを通じて削減されました。
オンラインサービングレイヤーを維持したまま、大量の履歴機能バックフィル中にキャッシュの汚染を防ぐにはどうしますか?
多くの候補者は、バックフィル中にサービングを単に一時停止するか、キャッシュとデータベースにまたがる分散トランザクションを使用することを提案します。正しいアプローチは、論理的なタイムスタンプとシャドウキー空間を実装します。バックフィルデータは、単調に増加するバージョンIDを持つ別のKafkaトピックを経由します。オンラインサービングクラスターは、"current"と"staging"の2つのRedisキー空間を保持します。バックフィルはstagingを満たしながらcurrentから読み取ります。完了すると、原子のRedis RENAME操作がマイクロ秒でキー空間を交換するか、代わりにアプリケーション層が両方のキー空間に問い合わせて高いバージョンの値を選択します。これにより、ゼロダウンタイムが保証され、複雑な調整プロトコルなしに部分的なバックフィル状態のサービングが防止されます。
オンラインとオフラインの機能ストア間の関係を支配するべき一貫性モデルは何ですか? なぜ強い一貫性はスケーラビリティで失敗しますか?
候補者はしばしば、2段階コミットプロトコルを使用してRedisとS3をまたがるACIDトランザクションを推奨します。オフラインストアはスループットとバッチ不変性を最適化し、オンラインストアは低レイテンシーのポイント読み取りを最適化します。強い一貫性は、サービングパスに受け入れがたいレイテンシーをもたらすコンセンサスオーバーヘッドを必要とします。代わりに、限定されたステールネス保証を持つ最終的一貫性を採用します。Kafkaログ圧縮と保持ベースの再調整ウィンドウを使用して、オンラインストアがオフラインストアの状態に定義された時間境界内で収束することを保証します。より厳格な保証を必要とする機能には、オンラインの書き込み確認がKafkaコミットの確認を待つ書き込み通過キャッシュを実装し、重要な機能に対してやや高いレイテンシーを受け入れつつ、他の機能に対して非同期複製を通じて高いスループットを維持します。
同じ生データの異なる変換を必要とするモデルのA/Bテスト中に機能のバージョン管理をどのように処理しますか?
一般的な誤りは、機能スキーマの進化を無視しながらモデルアーティファクトのみをバージョン管理することです。解決策は、DataHubまたはApache Atlasを使用して機能の名前空間と系譜追跡を実装します。各機能変換にはセマンティックバージョンが付与されます。機能ストアは、プレフィックスキーを使用してRedis内で複数のバージョンを同時に保持します。モデルサービング構成は、Consulまたはetcdを介して必要な機能バージョンを指定します。シャドウから本番にモデルを昇格させる際、オーケストレーション層はトラフィックがシフトする前にKafkaからの履歴再生を使用して新しい機能バージョンのキャッシュを事前にウォームアップします。これにより、データ漏洩やコールドスタートのレイテンシーのスパイクなしで、互換性のない機能計算を使用する同時のA/Bテストが可能になります。