マルチパートのエクスポートと大規模なアップロード
1)「大きな」輸出が必要とされ、何が重要であるか
シナリオ:財務レポート、ユーザー活動のアップロード、監査/レギュレータ、BIアップロード、パートナーディレクトリ、バックアップ。主な要件:- データの整合性(スナップショット/ポイント・イン・タイム)。
- ボリュームの通過性(並列書き込み/読み取り、ストリーミングシリアル化)。
- 再生可能および部分的な配達。
- 完全性(チェックサム)と検証可能性(マニフェスト)。
- セキュリティ/PII(マスキング、暗号化、アクセス制御)。
- コスト管理(圧縮、タイムアウト、CDN、 TTL)。
2)データ形式: 長所/短所
CSV-コンパクトで、書き込み/読み取りが高速です。cons:シールド、タイプが失われました。表形式のレポートに適しています。
JSONライン(JSONL)-ストリーミングや部分サンプリングに便利なオブジェクトごとに行で;cons:ボリューム。
寄木細工/Avro-列/回路フォーマット、圧縮、プッシュダウンの予測。分析やビッグデータに最適です。
混合:APIダウンロードのためのJSONL→Parquetへのオフライン変換。
圧縮:'gzip'/'zstd'(より良い)。非常に大容量の場合-スプリットアーカイブ(部品あたり~ 128-512 MB)。
3)一貫性: 「スナップショット」を取得する方法"
DB: REPEATABLE READ/SNAPSHOTトランザクション分離;スレッド、論理レプリケーション・スロットまたはウォーターマーク(max。 'updated_at '/version)。
イベントソーシング:オフセットログによるエクスポート。
スライス:"full' export+"deltas"('透かし'以降の変更の後のアップロード)。
4) Multipart/chunking
4.1種類の「マルチパート」
アップロード(私たちに):multipart/form-data(小さなファイル)、S3 MPU (Multipart Upload )/GCS Resumable (large)。
ダウンロード(私たちから):HTTP Range ('bytes=start-end')、' multipart/byteranges '(1つの応答で複数の範囲)、「partsのzip」、オブジェクトスタック内のディレクトリ。
4.2分割戦略
サイズ別(部品あたり256MBなど)。
キー/日付('tenant_id'、 'YYYY/MM/DD'で共有)。
テーブル/エンティティ(タイプごとに個々のファイル)。
バランス:64-512 MBの部品は、並列にうまくダウンロードし、メモリを過熱しません。
5)エクスポートAPIアーキテクチャ(非同期モデル)
ステップ:1.'POST/exports'→job in queue(メタデータ:format、 filters、 encryption、 lifetime)。
2.ワーカーはスナップショットを作成し、データをストリーミングし、部品をオブジェクトストレージに書き込みます。
3.部品、サイズ、チェックサム、スキーマバージョンのリストでマニフェスト(JSON)を生成します。
4.'GET/exports/{ id}' は/pre-signed URLの一部にステータスとリンクを返します。
5。 'GET/exports/{ id }/manifest。json'-検証/再ロードのための真実マシン。
例マニフェスト:json
{
"export_id": "exp_2025_10_31_001",
"created_at": "2025-10-31T14:23:00Z",
"schema": "orders_v3",
"format": "parquet+zstd",
"parts": [
{"name":"part-00000. parquet. zst","size":268435456,"sha256":"...","url":"...","range":"bytes=0-268435455"},
{"name":"part-00001. parquet. zst","size":241172480,"sha256":"...","url":"..."}
],
"total_bytes": 509607936,
"encryption": {"type":"AES-256-GCM","key_id":"kms/keys/exp"},
"watermark": {"type":"updated_at","value":"2025-10-31T00:00:00Z"}
}
6)再開可能
HTTP Range:クライアントはファイルの「尾」をロードします:'Range: bytes=241172480-'。
複数の範囲:'Range: bytes=0-999,2000-2999'→'Content-Type: multipart/byteranges'応答。
クライアント戦略:部品の並列「労働者」、各々の「sha256」の検証、指数関数的なバックオフを持つレトライ。
CDN:範囲サポート、大規模な応答バッファリングを無効にします。
7)私たちへの大規模なダウンロード(再開可能なアップロード)
S3マルチパートアップロード:クライアントは部品をダウンロード(5-5000)、サーバーは'CompleteMultipartUpload'を収集します。
GCS Resumable-1セッション、オフセット-クライアントは'Content-Range'を続行できます。
TUS(プロトコル)は、HTTP上の独立した再生可能なアップロードです。
Pattern B2B:プレサインされたURLをストアに直接、メタデータをAPIに送信します。
8)圧縮、暗号化、完全性
圧縮:'zstd'が好ましい(より良い比率/速度)。各部品を個別に圧縮します(更新/キャッシュする方が便利です)。
暗号化:- ワイヤーの上:TLS 1。2+.
- 残りの部分:サーバー側KMS (SSE-KMS)またはクライアント側(AES-256-GCM)キーをラッピングします。
- 「raw」キーをマニフェストに入れないでください。
- チェックサム:部品あたりの最小SHA-256+セット全体に共通。ackの前にクライアントをチェックしてください。
9)周囲の統合: NGINX/CDN
NGINX (Range+long timeouts+disable buffering):nginx server {
listen 443 ssl http2;
server_name downloads. example. com;
location /exports/ {
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 3600s;
add_header Accept-Ranges bytes;
proxy_pass http://export-backend;
}
}
レスポンスヘッダー:
- 'Content-Disposition:添付ファイル;filename="export_2025-10-31_part-00000。寄木細工だ。zst"'
- 'ETag'/'If-Range'は正しい読み込みのためです。
- パーソナルアップロードの'Cache-Control'(例えば、'private、 max-age=3600')。
10)安全性とコンプライアンス
認証/承認:オーナー/ロールにのみエクスポートを発行します。短いTTLによって前に署名される。
PII:マスキング/エイリアシング;マニフェストで-唯一の技術分野。
GDPR/ローカルレギュレータ: TTLによる輸出の削除、ダウンロードの監査、理由のない地域横断発行の禁止。
料金制限&クォータ:同時輸出の数と1日/月(テナントあたり)あたりの総量を制限します。
アンチスクレイピング:リンクを発行するためのCAP/ボットフィルタ、制限範囲(最大平行部品)。
11) Observabilityおよび操作
メトリクス:- 'export_jobs_total {status}'(キュー/実行/成功/失敗/期限切れ)
- 'export_bytes_total'、 'export_part_duration_ms {p50、 p95、 p99}'
- 'download_range_requests_total'、 'resumes_total'、 'checksum_fail_total'
- 'storage_cost_estimate'''egress_bytes_cdn'
- 誰がエクスポート、フィルタ、透かし、ダウンロードリスト(IP/UA/時間)を作成しました。
- 部品ハッシュと顧客側の調整(確認)。
- スパン:スナップショット→シリアライズ→パーツのアップロード→ファイナライズ。
12)性能および費用
並列処理:複数の部品を同時に生成します(Nワーカー)が、I/Oを制限します。
メモリ:ストリーミングシリアル化(イテレータ、データベースカーソル、4-16 MBのチャンク)。
Dedup:頻繁に繰り返されるエクスポートの場合、フィルター/ハッシュによる部品のスマートキャッシュ。
CDN:「一般的な」パブリックセットに有益です。個人的な-注意(安全/PII)。
13)インタフェースの例
13.1エクスポートの作成(REST)
http
POST /exports
Content-Type: application/json
Authorization: Bearer <token>
{
"format": "parquet+zstd",
"filters": {"date_from":"2025-10-01","date_to":"2025-10-31","tenant":"acme"},
"split_size_mb": 256,
"encryption": {"mode":"server-side-kms","key_id":"kms/keys/exp"}
}
答え:
json
{
"id":"exp_2025_10_31_001",
"status":"queued",
"estimated_parts": 12,
"manifest_url": "/exports/exp_2025_10_31_001/manifest. json"
}
13.2範囲の部品を発行する
http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-
13.3 Vorker擬似コード
pseudo snapshot = db. begin_snapshot()
for shard in plan_shards(snapshot):
part_stream = encode_stream(shard. rows, format="parquet", compress="zstd")
url = object_store. upload_stream(part_stream, part_name, encryption=KMS)
manifest. add(part_name, size, sha256, url)
write_manifest(manifest)
14)デルタの輸出パターン
「updated_at> watermark」でN(曜日/週)+deltasに1時間ごとにフルエクスポートします。
消費者側では、'version'/'seq'を検証して順番にデルタを適用します。
最後の透かしを消費者とマニフェストに保管します。
15)アンチパターン
リクエストでのエクスポート生成(同期)-タイムアウトとOOM。
分割せずに巨大なファイルの1つは、ダウンロードを再開/並列化できないことです。
チェックサムとマニフェストの欠如-あなたは完全性を証明することはできません。
個人データへの永久的な公的リンクの発行。
SSE/CDNまたはdisabled Rangeのバッファリング-「リロード」を解除します。
汚れたデータをエクスポートします(スナップショット/アイソレーションなし)。
16)実装チェックリスト
- フォーマットと圧縮:CSV/JSONL/Parquet+'zstd/gzip'。
- 整合性:トランザクションスナップショットまたはウォーターマーク/オフセット。
- パーティショニング:64-512 MBの部品、並列生成およびダウンロード。
- マニフェスト:部品リスト、寸法、SHA-256、スキーマバージョン、透かし。
- リニューアル:HTTP Range、 'multipart/byteranges'サポート、クライアントリトレイ。
- セキュリティ:事前署名されたURL、 TTL、暗号化(KMS/AEAD)、 PIIマスキング。
- 制限/クォータ:テナントごと、毎日のボリューム、アクティブなジョブの数。
- Observability:ジョブ/パーツメトリック、ダウンロード監査、チェックサムフェイルアラート。
- 費用:公共セット、TTLおよび店の自動クリーンアップのためのCDN。
- Runbooks/Game Days:ネットワークブレイク、ストアの利用不能、データベースの過熱、KMS障害。
17)ゲームの日(プレイブック)
ダウンロード中のネットワークドロップ:クライアントは'Range'を続行する必要があります。
1つの部品が読み込めませんでした:エクスポート全体を再作成せずに部品リトレイ。
労働者の落ち込み:ジョブは最後の未確認のチャンクで再開します。
KMSが利用できません:安全な劣化(生成の一時停止、暗号化されていないリリースしないでください)。
データの増加× 2:生成時間をチェックし、並列性を再配布し、データベースを殺すことはありません。
18)合計
信頼できる大きなオフロードは非同期アーキテクチャ+パーティショニング+更新+検証可能な整合性です。スナップショットを取り、部品を並行して書き、チェックサムでマニフェストを公開し、HTTP Rangeと短命のリンクをサポートします。セキュリティ、限界、観測可能性を通して考える-そしてギガバイトの輸出はチームとユーザーにとって悪夢ではなくなるでしょう。