R2 本地上传功能:提升全球上传性能

发表于:昨天 12:41 8
R2 本地上传功能:提升全球上传性能

今天,我们正式推出 R2 本地上传功能的公开测试版。启用本地上传后,对象数据会先自动写入靠近客户端的存储位置,然后异步复制到存储桶所在区域。数据立即可用,并保持强一致性。上传速度更快,数据感觉就像全球分布一样。

对于许多应用来说,性能需要全球化。例如,用户从不同地区上传媒体内容,或设备从世界各地发送日志和遥测数据。但你的数据必须存放在某个地方,这意味着远距离上传需要跨越整个距离才能到达你的存储桶。

R2 是基于 Cloudflare 全球网络构建的对象存储。开箱即用,它自动在全球缓存对象数据,实现快速读取——同时保持强一致性和零出口费用。无论你使用 S3 API、Workers Bindings 还是普通 HTTP,这一切都在后台进行。现在有了本地上传功能,全球任何地方的读写操作都可以变得快速。

在这个演示中亲自尝试,体验本地上传的好处。准备好尝试了吗?在 Cloudflare Dashboard 的存储桶设置下启用本地上传,或使用单个 Wrangler 命令在现有存储桶上启用。
  1. npx wrangler r2 bucket local-uploads enable [BUCKET]
复制代码

全球上传总请求时长降低 75%

本地上传使上传请求(如 PutObject、UploadPart)更快。在我们与客户的私有测试和合成基准测试中,当上传请求与存储桶位于不同区域时,我们看到最后一个字节时间(TTLB)最多减少了 75%。

在这些结果中,TTLB 是从 R2 接收上传请求到 R2 返回 200 响应的时间。在我们的合成测试中,我们使用合成工作负载模拟跨区域上传工作流,测量了本地上传的影响。我们在北美西部部署了一个测试客户端,并配置了一个位置提示为亚太地区的 R2 存储桶。客户端在 30 分钟内每秒执行约 20 个 PutObject 请求,上传 5 MB 大小的对象。

下图比较了这些请求的 p50(或中位数)TTLB 指标,显示了上传请求时长的差异——首先没有本地上传(TTLB 约 2 秒),然后启用本地上传(TTLB 约 500 毫秒):



工作原理:距离问题

要理解本地上传如何改进上传请求,我们先来看看 R2 的工作原理。R2 的架构由多个组件组成,包括:


  • R2 网关 Worker:所有 API 请求的入口点,处理身份验证和路由逻辑。它通过 Cloudflare Workers 部署在 Cloudflare 全球网络上。
  • Durable Object 元数据服务:基于 Durable Objects 构建的分布式层,用于存储和管理对象元数据(如对象键、校验和)。
  • 分布式存储基础设施:持久存储加密对象数据的基础设施。


没有本地上传时,上传对象到存储桶的过程如下:请求首先由靠近用户的 R2 网关接收,进行身份验证。然后,当客户端流式传输对象数据字节时,数据被加密并写入存储桶所在区域的存储基础设施中。完成后,网关联系元数据服务发布对象元数据,并在提交后向客户端返回成功响应。

如果客户端和存储桶位于不同区域,由于请求必须传输更长的距离,上传对象数据字节的过程中可能会引入更多变异性,导致上传速度变慢或可靠性降低。



客户端从北美东部上传到东欧存储桶,未启用本地上传。

现在,当你向启用本地上传的存储桶发出上传请求时,有两种情况:


  • 客户端和存储桶区域在同一区域
  • 客户端和存储桶区域在不同区域


在第一种情况下,R2 遵循常规流程,对象数据写入存储桶的存储基础设施。在第二种情况下,R2 写入客户端区域的存储基础设施,同时仍将对象元数据发布到存储桶区域。重要的是,初始写入完成后,对象立即可用。在整个复制过程中,它都保持可访问——无需等待后台复制完成才能读取对象。



客户端从北美东部上传到东欧存储桶,启用本地上传。

请注意,这适用于非管辖限制的存储桶,本地上传不适用于启用管辖限制(如 EU、FedRAMP)的存储桶。

何时使用本地上传

本地上传专为接收大量来自与存储桶位置不同地理区域的上传请求的工作负载而构建。此功能在以下情况下理想:


  • 你的用户全球分布
  • 上传性能和可靠性对你的应用至关重要
  • 你想在不更改存储桶主要位置的情况下优化写入性能


要了解读写请求发起的地理分布,你可以访问 Cloudflare Dashboard,转到 R2 存储桶的指标页面,查看按区域划分的请求分布图。



我们如何构建本地上传

通过本地上传,对象数据写入靠近客户端的位置,然后在后台复制到存储桶区域。我们称此复制作业为复制任务。鉴于这些复制任务,我们需要一个异步处理组件,这往往是 Cloudflare Queues 的绝佳用例。队列允许我们控制处理复制任务的速率,并提供内置的故障处理功能,如重试和死信队列。

在这种情况下,R2 将复制任务分片到每个存储区域的多个队列中。

发布元数据和调度复制

发布启用本地上传的对象的元数据时,我们原子性地执行三个操作:


  • 存储对象元数据
  • 创建待处理副本键,跟踪哪些复制仍需进行
  • 创建按时间戳键控的复制任务标记,控制任务何时应发送到队列


待处理副本键包含完整的复制计划:复制任务数量、从哪个源位置读取、写入哪个目标位置、复制模式和优先级,以及成功复制后是否应删除源位置。这为我们移动对象数据提供了灵活性。

例如,跨长地理距离移动数据成本高昂。我们可以尝试通过并行处理所有副本来尽快移动,但这会增加成本并对网络基础设施造成压力。相反,我们通过首先在目标存储桶区域创建一个副本,然后使用此本地副本在存储桶区域内创建额外副本,来最小化跨区域数据移动次数。



后台进程定期扫描复制任务标记,并将它们发送到与目标存储区域关联的队列之一。标记保证至少一次传递到队列——如果入队失败或进程崩溃,标记会持久化,任务将在下次扫描时重试。这也允许我们在不同时间处理复制,并仅入队有效任务。一旦复制任务到达队列,它就可以被处理。



异步复制:拉取模型

对于队列消费者,我们选择了拉取模型,其中集中轮询服务从区域队列消费任务,并将它们分派给网关 Worker 执行。



工作原理如下:


  • 轮询服务从区域队列拉取:消费者服务轮询区域队列获取复制任务,然后根据要移动的数据量批处理任务以创建统一批次大小。
  • 轮询服务分派给网关 Worker:消费者服务将复制作业发送给网关 Worker。
  • 网关 Worker 执行复制:Worker 从源位置读取对象数据,写入目标位置,并更新 Durable Object 中的元数据,可选标记源位置进行垃圾回收。
  • 网关 Worker 报告结果:完成后,Worker 将结果返回给轮询器,轮询器将任务确认为已完成或失败。


通过使用这种拉取模型方法,我们确保复制过程保持稳定和高效。服务可以根据实时系统健康状况动态调整其节奏,保证数据安全地跨区域复制。

立即尝试

本地上传现已提供公开测试版。启用本地上传无需额外费用。启用此功能的上传请求产生标准的 A 类操作成本,与未启用本地上传的上传请求相同。

要开始使用,请访问 Cloudflare Dashboard 的存储桶设置,找到本地上传卡片启用,或简单地使用 Wrangler 运行以下命令在存储桶上启用本地上传。
  1. npx wrangler r2 bucket local-uploads enable [BUCKET]
复制代码

在存储桶上启用本地上传是无缝的:现有上传将按预期完成,流量不会中断。更多信息,请参阅本地上传文档。

如果你有问题或想分享反馈,请加入我们的开发者 Discord 讨论。



原文链接:Improve global upload performance with R2 Local Uploads
收藏
送赞
分享

发表回复