当前位置: 首页 > 知识库问答 >
问题:

如何将S3扩展到每秒数千个请求?

糜征
2023-03-14

AWS S3文件状态(https://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html):

Amazon S3会自动扩展到高请求率。例如,您的应用程序可以在存储桶中的每个前缀每秒至少实现3,500个PUT/POST/DELETE和5,500个GET请求。

为了测试这一点,我有以下NodeJS代码(使用aws sdk),它异步启动1000个零字节的上传(因此,只需向bucket中添加空条目)。有一个计时器用于测量吞吐量:

var t0 = new Date().getTime()
for (var i = 0; i < 1000; i++) {
  var s3 = new AWS.S3()
  var id = uuid()
  console.log('Uploading ' + id)
  s3.upload({
      Bucket: bucket,
      Body : '',
      Key : "test/" + id
    },
    function (err, data) {
      if (data) console.log('Uploaded ' + id + ' ' + (new Date().getTime() - t0))
      else console.log('Error')
    })
}

完成所有上传请求大约需要25秒。这显然与据称的每秒3500个请求相去甚远,而大约是每秒40个请求。

我有大约1MB的网络上传速度,网络统计数据显示,大部分时间带宽仅饱和约25%。同样,CPU利用率也很低。

所以问题是:

如何扩展S3上传吞吐量以实现接近每秒3500个请求的目标?

编辑:

我修改了如下代码:

var t0 = new Date().getTime()
for (var i = 0; i < 1000; i++) {
  var s3 = new AWS.S3()
  var id = String.fromCharCode('a'.charCodeAt(0) + (i % 26)) + uuid()
  console.log('Uploading ' + id)
  s3.upload({
      Bucket: bucket,
      Body: '',
      Key: id
    },
    function (err, data) {
      if (data) console.log('Uploaded ' + id + ' ' + (new Date().getTime() - t0))
      else console.log('Error')
    })
}

这使用了26个不同的前缀,AWS留档声称应该将吞吐量扩展26倍。

“以指数方式提高读写性能很简单。例如,如果在Amazon S3存储桶中创建10个前缀以并行读取,则可以将读取性能扩展到每秒55000个读取请求。”

然而,吞吐量没有明显的差异。行为上存在某种差异,因此请求似乎以更并行的方式完成,而不是按顺序完成——但完成时间几乎相同。

最后,我尝试在x4个单独的bash线程(4个线程、4个内核、4x1000个请求)中运行该应用程序。尽管使用多核增加了并行性,但总执行时间约为80秒,因此无法扩展。

for i in {0..3}; do node index.js & done

我想知道S3速率是否会限制单个客户端/IP(尽管这似乎没有记录在案)?

共有2个答案

陈斌
2023-03-14

您应该查看的另一件事是使用的HTTPS代理。

AWSSDK使用全局代理曾经是这样(现在可能仍然是这样)。如果您使用的代理将重用连接,它可能是HTTP/1.1,并且可能出于兼容性原因禁用了流水线。

使用Wireshark等数据包嗅探器查看是否正在建立多个外部连接。如果只建立了一个连接,您可以在httpOptions中指定代理。

公羊涛
2023-03-14

在我直接回答你的问题之前,我有几件事要提。

首先,我在某个时候做了一个实验,我在大约25分钟内实现了200000个PUT/DELETE请求,即每秒130多个请求。我上传的对象每个大约10 kB。(我在同一时间跨度内也有大约125000个GET请求,所以我确信如果我只做PUTs,我可以实现更高的PUT吞吐量。)我在一个m4.4x大实例上实现了这一点,它有16个vCPU和64GB的RAM,与S3存储桶在同一个AWS区域中运行。

要获得更多吞吐量,请使用更强大的硬件并最大限度地减少网络跳数和您与S3之间的潜在瓶颈。

S3是一个分布式系统。(他们的留档说数据被复制到多个AZ。)它旨在同时满足来自多个客户端的请求(这就是为什么它非常适合托管静态Web资产)。

实际上,如果您想测试S3的限制,您也需要通过旋转一组EC2实例或将测试作为Lambda函数运行来进行分布式。

编辑:S3不能保证为您的请求提供服务的延迟。这样做的一个原因可能是因为每个请求可能具有不同的负载大小。(对10 B对象的GET请求将比10 MB对象快得多。)

您不断提到服务请求的时间,但这并不一定与每秒的请求数相关。S3每秒可以处理数千个请求,但据我所知,没有一台个人笔记本电脑或商品服务器能够每秒发出数千个单独的网络请求。

此外,总执行时间不一定代表性能,因为当您通过网络发送内容时,总是存在网络延迟和数据包丢失的风险。您可能有一个不幸的请求在网络中的路径较慢,或者该请求可能只是比其他请求经历更多的数据包丢失。

你需要仔细定义你想要找出什么,然后仔细确定如何正确测试它。

 类似资料:
  • 如何每秒触发10个请求,而不是等待前面的线程在jmeter中完成。 需要打1000次, 当前线程组中的以下配置,用户数:10循环:100 我猜线程正在等待响应,即使在第二秒之后。 但是我需要每秒发出10个请求,不管响应如何。 恒定吞吐量计时器将有助于做到这一点?如果是这种情况,我应该提供什么配置。 非常感谢您的帮助。。

  • 我们有一个使用vert.x开发的rest服务,每秒钟都会有大量的请求。我将StatsdMeterRegistry用于其他指标,如计时器,以测量处理不同业务逻辑所采取的措施。我如何使用micrometer测量每秒钟到来的http请求?在我的本地我已经安装了statsd代理和碳/石墨/耳语,但在生产它将是statsd和sysdig。不使用Spring框架或Spring靴。我不能使用vertx内置的千分

  • 我正在将一个微服务更新到spring Boot2,并将度量标准从dropwizard迁移到Micrometer。我们正在使用普罗米修斯来存储度量标准,并使用格拉法纳来显示它们。我想测量每秒对所有URL的请求。千分尺文档说明:

  • 问题内容: Vert.x是用于在JVM上构建响应式应用程序的工具包。 我想对基于JVM的自动可伸缩RESTful后端API使用vertx。 到目前为止,我从文档中发现,默认情况下,它需要计算机中的内核数,假设您有N个内核并为每个内核创建N个线程,每个线程是一个事件总线,每个线程包含vertx实例。问题是,Vertx如何控制实例数量?基于负载压力? 关于控制通过给定线程运行的Verticles数量的

  • 我正在按照这个教程使用s3和lambda实现即时生成缩略图。我被困在将不存在的请求重定向到lambda上 我的s3存储桶是私有的,我使用带有Cognito idToken的预签名url来访问其内容,它可以工作。 现在,如果我向尚未生成的缩略图(s3中不存在)发出请求,我希望s3将请求重定向到lambda。我不知道如何做这件事。 以下是s3路由角色 > < li> 当我使用预先签名的url访问不存在

  • 我想使用部分模板专门化,以便将数组(在编译时创建)“分解”为由其值组成的参数包(以便与我在代码中定义的其他结构接口)。以下内容(我的第一次尝试)不编译 因为模板参数不得涉及模板参数。正如我所理解的,在部分模板专门化中提供非类型参数是不可能的,如果它们不是非常依赖于模板参数的话。因此,我试图通过在类型中包含值来解决这个问题: 我使用并通过,因为我使用非类型模板参数,所以需要c++2a。 在我的实际代