代表的な面接トピック

システムデザイン面接:マルチテナント向けクォータおよび使用量従量課金サービスの設計

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

質問

SaaSテナント向けのクォータチェック、使用量計測、超過処理を行うサービスを設計してください。整合性、ホットテナント、重複イベント、クォータ変更、およびリカバリについて説明してください。

1. 質問と背景

SaaSプラットフォームは、多数のテナントに対してAPIリクエスト、並行ジョブ、ストレージを提供します。テナントにはプロジェクト単位、組織単位、リソース単位のクォータが存在する場合があり、分単位でリセットされるものもあれば、請求期間にわたって累積されるものもあります。ビジネス要件として、迅速な受付判定と、アラート、監査、請求のための信頼性の高い使用量データが求められています。ハードリミット、ソフトリミットのしきい値、超過ポリシー、マルチリージョン障害時の動作を含め、クォータチェックおよびメータリングサービスを設計してください。

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

  • 割り当て制限、レート制限、同時実行制限を区別し、それぞれのスコープとリセットセマンティクスを定義できているか。
  • 同期的な受付処理と、非同期の使用量イベント、請求集計、照合を分離できているか。
  • アトミックな予約、冪等性キー、重複または順序不同のイベント、ホットテナント、設定バージョンを適切に処理できるか。
  • リージョン間の一貫性、縮退動作、監査ログ、アラート、安全な手動変更について説明できるか。

3. 回答前に確認すべき明確化のための質問

  1. 制限対象はリクエストレート、同時実行ジョブ数、ストレージ容量、あるいは請求期間内の累積使用量のいずれですか?
  2. スコープは組織、テナント、プロジェクト、ユーザー、リソースインスタンスのどれであり、制限は階層構造の下位へ継承されますか?
  3. 上限に達した際、システムは拒否、キューイング、縮退、または請求のための超過許可のいずれを行う必要がありますか?
  4. マルチリージョン間での強い整合性が必要ですか?また、照合までに許容されるイベント遅延はどの程度ですか?

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

システムを、クォータカタログ、同期受付エンジン、予約台帳、非同期使用量イベントパイプライン、集計クエリ、監査アラートに分割します。リクエストには、テナント、プロジェクト、リソースタイプ、および冪等なリクエストIDが含まれます。受付エンジンは設定バージョンの下でレート、同時実行数、累積クォータをチェックし、必要に応じてアトミックに予約します。完了またはキャンセル時に予約を解放し、使用量イベントを発行します。イベントは一意のID、イベント時刻、ディメンションを保持し、コンシューマーは冪等に集計した上で、予約台帳および請求入力と期間の照合を行います。リソースごとに、リージョン間での信頼できる単一書き込み先(オーソリテイティブ)または許容範囲を定めたオーバーセルを選択し、障害時にもハードリミットを保護して適切にリトライ可能なシグナルを返します。

5. ステップごとの詳細な回答

ステップ 1: クォータモデルとスコープの定義

クォータカタログには、リソースタイプ、スコープ、単位、ウィンドウ、上限値、調整可能性、設定バージョンを保存します。レートクォータは時間枠内の消費量を制限し、同時実行クォータは同時に実行される処理数を制限し、割り当てクォータはすでに割り当てられているリソースを制限します。組織の制限を上限とすることができ、テナントやプロジェクトの予約は親の残容量内に収まる必要があるため、独立したチェックによって合計を超過することはありません。

ステップ 2: 同期チェックとアトミックな予約の設計

同期パスは、受付判定に影響を与える確定データ(現在のウィンドウのカウンター、アクティブな予約、設定バージョン)を保持します。ホットテナントに対しては、シャーディングされたホットキーまたはテナントごとにパーティション分割された強整合性ストレージを使用します。予約は残容量をチェックして予約量をアトミックに増分し、2つの同時リクエストが同じ残枠を使用することを防ぐ必要があります。長時間実行ジョブには予約IDが付与され、完了、キャンセル、期限切れの各処理は冪等に行われます。

text
checkAndReserve(tenant, dimensions, amount, requestId, configVersion)
  verify configVersion is active
  if requestId already committed: return previous decision
  atomically check remaining quota and add reservation
  persist reservation with expiry and requestId
  return reservationId and retryAfter

ステップ 3: 使用量イベントとメータリング集計の疎結合化

成功、失敗、キャンセル、期限切れの各契機でイベントを発行する必要があります。各イベントには、テナント、プロジェクト、リソース、数量、単位、イベント時刻、および一意のイベントIDが含まれます。少なくとも1回の配信(at-least-once)を前提とし、コンシューマーはイベントIDで重複を排除します。順序不同のイベントは、イベント時刻ウィンドウまたは再生可能な台帳を使用して処理します。集計データはクエリ、しきい値アラート、請求入力に利用されますが、同期予約台帳を上書きしてはなりません。

ステップ 4: 超過、クォータ変更、公平性の処理

ハードクォータに達した場合は拒否またはキューイングし、ソフトリミットのしきい値ではアラートをトリガーします。超過を許可するかどうかは、承認されたアクターと価格ルールを伴う明示的な製品設定である必要があります。クォータを引き下げる前に既存の予約を確認し、すでに受け入れられた作業が突然容量を失わないようにします。ホットテナントが共有シャードを占有しないよう、テナント単位の同時実行上限、トークンバケット、公平キューにより他のテナントを保護します。増枠申請は承認または自動化ルールに従い、監査のために過去のバージョンを保持します。

ステップ 5: マルチリージョン動作、リカバリ、および照合

ハードリミットをグローバルで厳密に保つ必要がある場合は、リソースを1つのオーソリティにルーティングするか、コンセンサスベースのストレージを使用します。可用性を優先する場合は、リージョンごとのバジェットを割り当て、最大オーバーセル量を明記します。リージョン間のネットワーク分断時には、安全に判断できないハードリミットの決定を拒否します。ソフトリミットは一時的にアラートのみへ縮退させることができます。復旧後は、イミュータブルなイベントと予約レコードを再生し、受付判定、集計値、請求結果を比較して、履歴を直接編集するのではなく補償イベントによって差異を修復します。

6. 質の高い回答例

私はクォータカタログ、同期受付エンジン、予約台帳、非同期メータリングパイプライン、監査クエリを分離して設計します。カタログは組織、テナント、プロジェクトのスコープと、レート、同時実行、割り当ての各制限を定義します。受付処理はテナントディメンションと冪等性IDを使用してアトミックなチェック・アンド・リザーブを実行し、長時間ジョブには予約IDを付与して完了、キャンセル、期限切れを冪等にします。成功および失敗イベントはat-least-onceパイプラインに投入され、コンシューマーはイベントIDで重複排除し、受付台帳を上書きすることなくアラートや請求のためにイベント時刻で集計します。リソースごとに、マルチリージョン動作はオーソリテイティブ方式または許容範囲付きオーバーセル方式のいずれかをとります。障害時にはハードクォータを保護し、復旧後は再生と照合を行い、すべての変更と補償を監査可能にします。

7. よくある間違い

  • 1つの共有カウンターを使用する → ホットテナントが他のすべての処理を遅延させる → テナントごとにシャード化し、公平な上限を強制する。
  • 非同期集計を受付判定に使用する → イベントの遅延によってオーバーセルが発生する → 受付の真実のソースとしてアトミックな予約台帳を保持する。
  • レート制限のみを議論する → 長時間ジョブやストレージが無制限のキャパシティを消費する → レート、同時実行、割り当て制限をモデル化する。
  • リクエストIDのみを重複排除する → リトライされたイベントが二重計上される → 予約と使用量イベントで別々の冪等性キーを使用する。
  • クォータ引き下げ時に残高を上書きする → 受け入れ済みの作業が突然拒否される → 設定をバージョニングし、既存の予約を確認する。

8. フォローアップ質問と回答

フォローアップ 1: なぜRedisカウンターだけに頼らないのですか?

カウンターは低レイテンシなウィンドウ統計には有用ですが、リソースをまたぐアトミックな予約、ジョブの期限切れ、設定バージョン管理、監査にはより完全な台帳が必要です。カウンターは、オーソリテイティブなレコードと再構築プロセスが存在する場合にのみ高速パスとして機能します。

フォローアップ 2: 重複した使用量イベントによる二重請求をどのように防ぎますか?

すべてのイベントに一意で安定したIDを付与します。コンシューマーは重複排除レコードと集計を単一トランザクションで書き込むか、同等のアトミック操作を使用します。集計は再計算可能な状態を維持し、請求処理は確定した集計バージョンを使用して補償イベントを保持します。

フォローアップ 3: マルチリージョンのネットワーク分断時にも処理を受け付け続けますか?

オーバーセルが許されないハードクォータについては、処理を一時停止するかオーソリティにルーティングします。許容されるオーバーセルバジェットを持つソフトクォータについては、リージョンの割り当てから受け付け、最大リスクを記録します。この選択は、ビジネス上の損失と整合性の目標に応じて決定します。

フォローアップ 4: クォータサービスをどのようにテストしますか?

ホットテナント、並行予約、重複および順序不同のイベント、設定のダウングレード、リージョン分断、コンシューマーの再生、期間のロールオーバーの負荷テストを実施します。ハードリミットが決して破られないこと、冪等な操作が安定していること、そして復旧後に台帳、集計、請求が収束することを検証します。

公開情報ソース

関連する質問

関連面接ツール

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

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

ツールを見る