Multipart出口和大型卸货
1)什么时候需要"大"出口和重要的事情
情景:财务报告、用户活动卸载、审计/监管机构、BI卸载、合作伙伴目录、备份。关键要求:- 数据一致性(snapshot/时间点)。
- 跨范围(并行写入/阅读,流序列化)。
- 可再生性(可恢复)和部分交付。
- 完整性(checksum)和可验证性(清单)。
- 安全/PII(掩码、加密、访问控制)。
- 成本管理(压缩,超时,CDN,TTL)。
2)数据格式: 优点/缺点
CSV-紧凑,快速书写/阅读;缺点:屏蔽,类型丢失。适用于表格报告。
JSON Lines(JSONL)-逐行逐行,方便流媒体和部分采样;缺点:体积。
Parquet/Avro是柱状/方案格式,压缩和预编码推杆;非常适合分析和大数据。
混合:JSONL用于API下载→离线转换为Parquet。
压缩:"gzip"/"zstd"(更好)。对于非常大的体积-分割归档(每部分~ 128-512 MB)。
3)一致性: 如何获得"快照"
DB:REPEATABLE READ/SNAPSHOT事务隔离;对于线程-复制逻辑插槽或"watermark"标记(最大值为"updated_at"/版本)。
事件来源:导出到杂志的外部。
切片:"完全"出口+"三角洲"(自"水厂"以来的变化随后的卸载)。
4)分成部分(multipart/chunking)
4.1种"multipart"
Upload(到我们):multipart/form-data(小文件),S3 Multipart Upload (MPU)/GCS Resumable(大文件)。
下载(来自我们):HTTP Range("bytes=start-end"),"multipart/byteranges"(单一响应中的多个范围),"zip of parts",对象堆栈中的目录。
4.2分区策略
按尺寸(例如,每部分256 MB)。
按键/日期(通过"tenant_id","YYYY/MM/DD"混合)。
表/实体(每个类型的单个文件)。
平衡:64-512 MB部分并行下载良好,不会过热内存。
5)导出API体系结构(异步模型)
步骤:1. "POST/exports" →排队任务(元数据:格式、过滤器、加密、寿命)。
2.Workers构建snapshot,流式传输数据并将零件写入对象存储。
3.生成带有零件列表,尺寸,checksum和方案版本的清单(JSON)。
4.' GET/exports/{id}"返回到部分/签名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"。
客户策略:每部分平行的"窃贼",每个部分的"sha 256"验证,带有指数后退的后退。
CDN:支持范围,关闭大响应缓冲。
7)大下载我们(resumable upload)
S3 Multipart Upload:客户端加载零件(5-5000),服务器组装"CompleteMultipartUpload"。
GCS恢复:一个会话,偏移-客户端可以继续使用"内容范围"。
TUS(协议)是HTTP之上的独立可再生应用程序。
B2B模式:我们将预签名URL直接将零件升级到堆栈,并将元数据升级到我们的API。
8)压缩、加密、完整性
压制:"zstd"是首选的(优于评分/速度)。分别压缩每个部分(恢复/缓存更方便)。
加密:- 在电线上:TLS 1。2+.
- 静止:服务器侧KMS (SSE-KMS)或客户端侧(AES-256-GCM)和密钥包装(key wrapping)。
- 切勿将"原始"密钥放入宣言中。
- Checksum:整个集合的最小部分+通用部分SHA-256。在ack之前检查客户端。
9)外围集成: NGINX/CDN
NGINX (Range+大时空+禁用缓冲):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: attachment;filename="export_2025-10-31_part-00000.parquet.zst"`
- "ETag"/"If-Range"用于正确补丁。
- "Cache-Control"(例如"private,max-age=3600")用于个人卸载。
10)安全和合规性
认证/授权:仅向所有者/角色签发导出;带有短TTL的临时链接(签名前)。
PII:掩饰/化名;宣言中只有技术领域。
GDPR/地方监管机构:根据TTL删除出口,审核下载,禁止无根据的跨区域发行。
Rate limiting"as:限制同时出口的数量和每天/月的总量(每吨)。
反剪贴画:SAR/机器人过滤器,引用,限制范围(最大并行部件)。
11)可观察性和操作
度量标准:- `export_jobs_total{status}` (queued/running/succeeded/failed/expired)
- `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/时间)。
- 零件散列和客户端对账(确认)。
- 分阶段演唱:snapshot → serialize → upload part → finalize。
12)生产力和成本
并行性:同时生成多个部分(N制造商),但限制I/O。
内存:流序列化(迭代器、DB游标、Chanks 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使用Range发行零件
http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-
13.3伪代码制造商
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(每天/每周)+delta。
在消费者方面:按顺序应用三角洲,验证"版本"/"seq"。
将最后一个水库存放在消费者和清单中。
15)反模式
查询中导出的生成(同步)是taymout和OOM。
一个不分解的巨型文件是无法恢复/并行注入。
缺少checksum和宣言-无法证明完整性。
发出关于个人数据的永久公共链接。
SSE/CDN缓冲区或禁用的Range-打破"分载"。
导出"脏"数据(不带snapshot/隔离)。
16)实施支票
- 格式和压缩:CSV/JSONL/Parquet +'zstd/gzip'。
- 一致性:事务性snapshot或watermark/offset。
- 分布:64-512 MB部分,并行生成和下载。
- 宣言:零件清单,尺寸,SHA-256,方案版本,水厂。
- 恢复:HTTP Range,支持"multipart/byteranges",客户端转发。
- 安全性:预签名URL, TTL,加密(KMS/AEAD), PII掩码。
- 限额/配额:每次限额、每日数量、活跃人数。
- 可观察性:乔布/零件度量,下载审核,checksum-fail上的差分。
- 费用:用于公共套件的CDN,TTL和堆栈中的自动清洁。
- Runbooks/Game Days:网络断路器、堆栈不可用、DB过热、KMS故障。
17)游戏日(花花公子)
下载时网络断裂:客户必须继续使用"范围"。
一件装载失败:重新装配零件而不重新装配所有出口。
制造商倒台:乔巴从最后一次未经证实的投掷中恢复过来。
KMS:安全降解(暂停生成,不释放未加密)。
数据增长× 2:检查生成时间,重新分配并发,不要杀死DB。
18)结果
可靠的大上载是异步体系结构+分成部分+恢复+可验证的完整性。制作snapshot,并行编写部分,使用checksum发布宣言,支持HTTP Range和短寿命链接。考虑安全性、限制和可观察性-千兆字节出口将不再是团队和用户的夜间噩梦。