代表的な面接トピック

システムデザイン面接:機能フラグのパーセンテージバケットの安定性を維持する

システム設計難しい
Offer.cc 編集チーム公開日 更新日

質問

同一ユーザーが複数のリージョンやサービスインスタンスにアクセスします。機能フラグ設定の伝播には数秒かかります。パーセンテージロールアウトの安定性を維持し、ユーザーがバリアント間で行き来するのを防ぐにはどうすればよいですか?

設問と背景

この設問では、機能フラグ評価のホットパスを切り離して考えます。管理、承認、および広範なプラットフォームは別の設計課題に属します。設定は非同期に伝播し、呼び出し側は複数の言語のSDKを使用しますが、ユーザーは説明可能で再現性のあるバリアントを受け取る必要があります。属性ルールとパーセンテージロールアウトを備えたサーバーサイドのインプロセス評価を前提とします。

面接官が評価するポイント

  • 設定の最終的な収束と、単一の識別子に対する安定したバケッティングの分離。
  • SDK間で統一された1つのtargetingKey、正規化規約、およびハッシュアルゴリズムの定義。
  • 部分的な更新を公開する代わりに、イミュータブルで単調増加するバージョンスナップショットの切り替え。
  • コンテキストの欠落、型エラー、不明なフラグ、および古い設定に対して安全なデフォルト値を返すこと。
  • ゴールデンベクター、シャドウ評価、および分布メトリクスによる一貫性の証明。

回答前の明確化事項

安定性がデバイス、リージョン、SDK言語をまたいで維持される必要があるか、匿名識別子がどのように永続化されるか、および10%ロールアウト内にすでに含まれているユーザーがロールアウト拡大時にも維持される必要があるかを確認します。また、機密情報となるターゲット属性、許容される伝播時間、緊急停止スイッチが通常のロールアウト規則を上書きするかどうかも確認します。

30秒の回答フレームワーク

ルールをイミュータブルでバージョニングされたスナップショットにコンパイルし、各SDK内で評価します。パーセンテージ割り当てでは、targetingKeyflagKey、およびシードを長さプレフィックス付きの正規化タプルとしてエンコードし、固定範囲にハッシュします。通常の変更では、非アクティブなスナップショットを配布し、すべてのサービングリージョンが準備完了を報告するのを待ってから、コントロールプレーンの割り当てジェネレーションを1つ進めます。各セッションまたは永続的な識別子がそのジェネレーションを保持し、サービングインスタンスは限定的な重複期間中両方のスナップショットを保持するため、ローカルクロックのズレによってユーザーがルールバージョン間を移動することはありません。コンテキストの欠落、無効なルールタイプ、または古い設定の場合は、理由コードとともに呼び出し側のデフォルト値を返します。クロス言語のゴールデンベクターとシャドウ評価により、同一の決定を検証します。

ステップバイステップの詳細解説

入力規約から始めます。サーバーサイドのすべての評価には、空でないtargetingKeyが必要です。匿名トラフィックは永続化されたランダム識別子を使用できますが、リクエストごとの新しい値は使用できません。文字列エンコーディング、大文字小文字、空白、数値、およびタイムスタンプの正規化を指定します。単純な連結や区切り文字のみのフレーミングではなく、バージョニングされた長さプレフィックス付きUTF-8タプルをハッシュします。そうしないと、SDK間でフィールド境界や区切り文字が曖昧になります。

バケット関数はbucket = hash(encodeTuple(v, seed, flagKey, targetingKey)) mod 100000とすることができます。各バリアントは重複しない連続した範囲を持ちます。10%から20%への拡大はターゲット範囲を拡大し、元のユーザーを維持します。flagKeyを含めることで、無関係なフラグが完全に相関したサンプルを選択するのを防ぎます。シードの変更は意図的にユーザーを再シャッフルするため、監査されたリリースが必要です。

ルールマッチングとバケッティングは、1つのイミュータブルなスナップショットを参照する必要があります。ディストリビューターは、チェックサムと単調増加バージョンを持つ完全な非アクティブスナップショットをすべてのサービングリージョンに送信します。すべてのリージョンが検証し準備完了を確認した後、コントロールプレーンが信頼できる割り当てジェネレーションを1つ進めます。セッション識別子や永続識別子のレコードがそのジェネレーションを保持し、すべてのリージョンが参照された正確なスナップショットを評価し、割り当ての有効期限が切れるまで前のスナップショットを保持します。参照されたバージョンがないインスタンスは、その割り当てのサービングを停止します。このプロトコルは、同期されたクロックではなくバージョンの伝達に依存します。緊急キルスイッチは安全のためにスティッキネスを明示的にオーバーライドできますが、記録されたバージョニングされたルールとして残ります。

OpenFeatureの評価規約により、呼び出し側はデフォルト値を指定でき、評価失敗時にエラー理由が関連付けられます。フラグの欠落、型の不一致、ターゲティングキーの不在、プロバイダーの準備未完了を区別します。メトリクスは低カーディナリティに保ち、メールアドレス、デバイス識別子、完全な評価コンテキストを通常のログに記録しないでください。

検証には3つのレイヤーがあります。すべてのSDKで、空の値、区切り文字、Unicode、フィールド境界の衝突ケースを含む同じゴールデン入力と期待されるバリアントを実行します。エバリュエーターを置き換える前に、本番相当のスナップショットに対して両方のエンジンをシャドウ実行し、リージョンが準備完了を逃すケースをリハーサルします。本番環境では、バリアント比率、デフォルト値率、スナップショットの経過時間、リージョン別のバージョン分布を監視します。分布の異常はシグナルであり、個々の決定はスナップショットバージョン、ルールID、およびバケットから再現可能でなければなりません。

優れた回答例

各SDKは検証済みのスナップショットのみを評価します。リクエストは安定したtargetingKeyを提供します。SDKはseedflagKey、およびtargetingKeyのバージョニングされた長さフレーム化タプルを100,000個の固定バケットの1つにハッシュします。エクスポージャーの増加は範囲を広げるだけなので、既存のメンバーが外れることはありません。

通常の変更は、コントロールプレーンが割り当てジェネレーションを進める前にすべてのリージョンに到達します。その後、セッションまたは永続識別子がそのジェネレーションを保持し、各リージョンは割り当ての有効期間中、参照されたスナップショットを保持します。したがって、リージョンをまたぐリクエストでも、同期されたクロックに依存することなく1つのルールバージョンが評価されます。そのスナップショットがないインスタンスは、割り当てのサービングを停止します。SDKはリグレッションを拒否し、古い設定や無効なコンテキストに対して呼び出し側のデフォルト値を返します。緊急シャットダウンは通常のスティッキネスを明示的にオーバーライドし、最優先で収束します。

よくある間違い

  • 評価ごとにリモートのフラグサービスを呼び出し、リクエストの可用性をそれに結合させてしまうこと。
  • 言語ランタイム組み込みのハッシュを使用すること(プロセス間やSDK間で異なる可能性があります)。
  • ユーザーIDのみをハッシュし、すべてのフラグ間で相関したサンプルを作成してしまうこと。
  • 設定をフィールドごとに更新し、混在したルールと重みのバージョンを公開してしまうこと。
  • targetingKeyが欠落している場合にリクエストをランダムに割り当てること。
  • 完全な評価コンテキストをログに記録し、機密属性を漏洩させること。

フォローアップの質問

異なる設定バージョンをグローバルに一貫させることはできますか?

非同期配信だけでは、幅ゼロのグローバル一貫性ウィンドウを保証することはできません。通常の変更は、まずすべてのサービングリージョンで準備完了を通過します。次にコントロールプレーンが割り当てジェネレーションを1つ進め、セッションまたは永続識別子がリクエストごとにそれを伝達します。リージョンはその割り当ての有効期限が切れるまで参照されたスナップショットを保持し、スナップショットを欠くインスタンスはサービングパスから外れます。緊急停止スイッチはスティッキネスをオーバーライドし、高速な収束を優先し、遅延しているインスタンスを監視できます。

匿名ユーザーは何で識別すべきですか?

クライアントに永続化されたランダムな匿名IDを使用し、ストレージのクリアやデバイスの変更によって再割り当てが発生することを文書化します。IPアドレスは共有され、不安定であり、プライバシーに関するさらなる懸念を引き起こします。

ハッシュアルゴリズムを安全に変更するにはどうすればよいですか?

スナップショット内でアルゴリズムとシードをバージョニングし、古いバケットと新しいバケットをシャドウ計算して変動を測定します。スティッキネスが必要な場合は、移行マッピングを通じて割り当てを維持します。再シャッフルが許容される場合でも、ロールバックスナップショットを用意して明示的にリリースします。

不具合のあるSDK実装をどのように検出しますか?

すべてのSDKで同一のゴールデンベクターを実行し、低カーディナリティのアルゴリズムバージョン、スナップショットバージョン、および集計されたバリアント数を報告します。乖離のあるSDKの設定アップグレードを凍結し、その最後の有効なスナップショットを保持し、正規化またはハッシュを修正してから再開します。

公開情報ソース

関連する質問

関連面接ツール

システム設計の回答には「回答する」を使用

まず要件を明確にし、スケール、アーキテクチャ、コンポーネント選定、トレードオフの順に進めます。

ツールを見る