代表的な面接トピック

バックエンド面接:完全性チェックを備えた再開可能なマルチパートアップロードAPIの設計

バックエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

再開可能な大容量ファイルアップロード用APIを設計してください。クライアントは接続が切断されたり、同じパートを2回アップロードしたり、リクエストを並行して送信したりする可能性があります。システムは完全性を検証し、孤立パートの発生を防ぎ、完了後に安定したオブジェクトバージョンを返さなければなりません。

プロンプトとコンテキスト

クライアントは、不安定なネットワーク経由で数ギガバイトのファイルをアップロードする必要があります。モバイルクライアントは、同じパートを再試行したり並行して送信したりすることがあります。サービスは進捗状況を公開し、欠落したパートの再試行を可能にし、ファイナライズ前後のコンテンツの完全性を証明する必要があります。面接では、プロトコル状態、冪等性、チェックサム、ライフサイクル、オブジェクトの可視性に焦点を当てます。

面接官がテストしていること

面接官は、大きなリクエストが復旧可能なセッションに分解されているかを確認したいと考えています。Google Cloudは再開可能なアップロードを、通信障害後に続行できる複数のリクエストとして定義しています。Amazon S3のマルチパートアップロードでは、オブジェクトを組み立てる前にパートの送信と明示的な完了呼び出しが必要であり、未完了のアップロードに対するライフサイクルクリーンアップを推奨しています。優れた回答では、認可、レート制限、重複した完了セマンティクスについてもカバーします。

最初に確認すべき明確化のための質問

オブジェクトサイズ、パートサイズ、並行処理の制限、クライアントがセッションURLを保持できるかどうか、オブジェクトの上書きまたはバージョニングの可否、クライアントがファイル全体のダイジェストを提供するかサービス側が計算するか、そしてセッションの保持、キャンセル、不正利用防止、テナントクォータポリシーを明確にします。事前署名付きURL(presigned URL)は、ビジネス認可を自動的に伴うものではありません。

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

次のように答えます:「セッション作成、パートアップロード、ステータス取得、完了、キャンセルの各操作を公開します。セッションは、テナント、オブジェクトキー、サイズ、パートのルール、有効期限、チェックサムポリシーをバインドします。各パートは (uploadId, partNumber, checksum) によって冪等になります。完了処理では連続するパートとオブジェクト全体のダイジェストを検証し、その後オブジェクトバージョンをアトミックに公開します。ワーカーが期限切れセッションをクリーンアップし、認可、クォータ、レート制限は作成時およびパートリクエストごとにチェックされます。」

ステップバイステップの詳細分析

1. アップロードセッションの作成と認可

POST /uploads はテナントのクォータ、オブジェクトサイズ、コンテンツタイプ、宛先の権限をチェックし、ランダムな uploadId、パートサイズ、有効期限、スコープ付きアップロード認証情報を返します。セッションには予想サイズ、オブジェクトキー、バージョニングポリシー、チェックサムアルゴリズムが記録され、クライアントが任意のストレージパスを選択することはできません。

2. 冪等なパートとステータスの設計

PUT /uploads/{id}/parts/{n} はパート長とチェックサムを保持します。サービスは uploadId + partNumber の最新の有効なメタデータを保存します。同じダイジェストを持つ重複リクエストには成功を返し、異なるダイジェストの場合は競合を返してクライアントにステータスの更新を求めます。GET /uploads/{id} は、他のテナントのデータを公開することなく、確認済みパート、サイズ、次のアクションを返します。

3. データの完全性の検証

アップロードごとに長さとパートチェックサムを検証し、完了時に連続するパート番号、合計長、オブジェクト全体のダイジェストを検証します。Amazon S3はパートまたは複合チェックサムをドキュメント化しており、不一致がある場合は公開を防ぐ必要があります。クライアントとサービスがダイジェストを異なる方法で解釈しないよう、アルゴリズムとエンコーディングをセッションに保存します。

4. 完了処理と可視性の制御

POST /uploads/{id}/complete は、順序付けられたパートリストとオプションのファイル全体ダイジェストを保持します。完了処理は冪等です。同じリストには同じオブジェクトバージョンを返し、競合するリストは拒否されます。ストレージがオブジェクトを組み立てて検証した後にのみ、データベースレコードが UPLOADING から READY に移行します。読み取りによって不完全なオブジェクトが公開されることは決してありません。

5. キャンセル、期限切れ、孤立パートのクリーンアップ

クライアントは明示的にキャンセルできます。ワーカーが期限切れセッションをスキャンし、ストレージの中止操作を呼び出して、アップロードされたパートを削除します。クリーンアップ自体も冪等かつ再試行可能であり、最後のエラーとコストのメトリクスが記録されます。S3では不完全なパートにもストレージ料金が発生すると記載されているため、ライフサイクルルールは最後のセーフティネットであり、アプリケーション状態の代替ではありません。

6. セキュリティ、クォータ、可観測性の追加

すべての操作でテナント、オブジェクト権限、セッション状態、パート範囲をチェックします。認証情報は現在のセッションにスコープが絞られ、短時間で期限切れになります。テナントごとにアクティブセッション数、合計バイト数、パートサイズを制限します。セッションの成功、再試行、チェックサム失敗、クリーンアップ遅延、孤立バイトを、テナントごとに分離されたアラートとともに監視します。

高品質なサンプル回答

POST /uploads を使用してセッションを作成し、テナントクォータとオブジェクトサイズを検証した上で、ランダムな uploadId、固定パートサイズ、チェックサムアルゴリズム、24時間の有効期限を発行します。すべてのパートはその番号、長さ、ダイジェストを保持し、(uploadId, partNumber) が冪等性キーとなります。同じダイジェストの重複には既存の結果を返し、異なるダイジェストは拒否されます。クライアントはステータスエンドポイントを使用して欠落しているパートを確認します。完了処理では順序付けられたリストとファイル全体のダイジェストが提供され、サービスは番号付け、合計長、パートチェックサムを検証した後に、オブジェクトストアの完了操作を呼び出します。組み立てが成功した後にのみ、オブジェクトを READY とマークします。重複した完了呼び出しには同じバージョンを返し、競合するリストは何の変更も行いません。キャンセルおよび期限切れワーカーは、孤立ストレージの課金を避けるために未完了のアップロードを再試行付きで中止します。認証情報はテナントおよびセッションスコープであり、作成、パート、完了の各パスでクォータ、認可、レート制限、監査が適用されます。」

よくある間違いと改善策

  • アップロードを1つの長いリクエストにする: セッションとパートを使用し、ネットワーク障害の影響が欠落したデータのみに及ぶようにします。
  • アップロードされたバイト数のみを追跡する: パート番号、ダイジェスト、バージョンを追跡し、重複や順序不同の置き換えを防ぎます。
  • 完了前に成功とマークする: まずストレージ側で組み立てと検証を行い、その後に READY なオブジェクトを公開します。
  • 期限切れパートのコストを無視する: キャンセル、バックグラウンドでの中止、ストレージライフサイクルクリーンアップを組み合わせて提供します。

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

クライアントが同じパートを並行してアップロードした場合はどうなりますか?

セッションとパート番号ごとにメタデータの更新をシリアライズするか、条件付き書き込みを使用します。同じダイジェストの重複は冪等な成功を返し、異なるダイジェストは競合を返し、クライアントは再試行前にステータスを更新します。

ストレージ側で実際に完了した後に、完了処理がタイムアウトした場合はどうなりますか?

完了の冪等性キーとターゲットバージョンを永続化します。再試行時には、まずストレージとローカル状態を照会します。リストが完了したバージョンと一致する場合はそのバージョンを返します。不明確な場合は COMPLETING を維持し、やみくもに組み立てるのではなくワーカーに調整させます。

悪意のあるクライアントがストレージを埋め尽くすのをどのように防ぎますか?

セッション作成時にクォータを確保し、テナントごとにアクティブセッション数、合計パートバイト数、並行数、有効期限を制限します。パートの認証情報をセッションと範囲にバインドし、期限切れセッションを速やかに中止し、異常な再試行率に対してアラートを発報します。

同じキーのオブジェクトは上書き可能にすべきですか?

デフォルトでは新しいバージョンまたは条件付き書き込みにします。上書きが必要な場合は、ターゲットバージョンまたは If-Match 条件を受け入れ、完了後に参照をアトミックに更新することで、低速なアップロードによって新しいオブジェクトが上書きされないようにします。

公開情報ソース

関連する質問