我们在Heroku上托管的Rails应用程序上的后台工作程序上生成PDF文件,一旦生成它们就会上传到Amazon S3。 Heroku app和S3 bucket都位于eu-west-1区域。
我们正在经历慢速上传,非常基本的小文件。看看这个例子:
Aws.config.update({
region: 'eu-west-1',
credentials: Aws::Credentials.new(ENV['S3_USER_KEY'], ENV['S3_USER_SECRET'])
})
S3_BUCKET = Aws::S3::Resource.new.bucket(ENV['S3_PRIVATE_BUCKET'])
file = Tempfile.new(["testfile", ".pdf"], encoding: "ascii-8bit").tap do |file|
file.write("a"*5000)
end
Benchmark.bm do |x|
x.report { S3_BUCKET.put_object(key: "testfile.pdf", body: file) }
end
user system total real
0.020000 0.040000 0.060000 ( 40.499553)
我想我不能做一个更简单的例子,所以发送一个包含5000个字符的文件需要40秒才能从Heroku一次性实例上传到S3。
请注意,我在我的(国内)互联网连接和Heroku实例上进行了测试,结果几乎相似。 另一方面,我使用ForkLift.app作为GUI浏览我的存储桶,上传文件几乎是即时的。
我一直在浏览aws-sdk文档,但我无法解释如何解释这么慢的上传
答案 0 :(得分:1)
put_object和TempFile似乎有问题
尝试先将文件传递给IO
new_file = IO.read(file)
S3_BUCKET.put_object(key: "testfile.pdf", body: new_file)
答案 1 :(得分:0)
似乎AwsSdk是罪魁祸首。 我用其他方式测试了上传相同的文件:
(我使用的是手机连接,因此网络非常慢,我没有花时间在Heroku Dyno上安装/配置aws CLI)
Benchmark.bm do |x|
x.report { `aws s3 cp #{file.path} s3://#{ ENV['S3_BUCKET']}/testfile.pdf` }
end
0.000000 0.000000 0.510000 ( 2.486112)
这是从Heroku Dyno开始的。
connection = Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => ENV['S3_USER_KEY'],
:aws_secret_access_key => ENV['S3_USER_SECRET'],
region: "eu-west-1"
})
directory = connection.directories.new(key: ENV["S3_BUCKET"], region: "eu-west-1")
Benchmark.bmb do |x|
x.report do
directory.files.create(
:key => 'test-with-fog.pdf',
:body => file,
)
end
end
user system total real
0.010000 0.010000 0.020000 ( 0.050712)
我会坚持最新的解决方法。尽管如此,我还没有找到导致aws-sdk这么慢的原因。
答案 2 :(得分:0)
在创建Aws::S3::Object
并使用方法upload_file
时遇到了类似的问题。如果我传递了TempFile
对象,那么即使上传一个小文件(〜5KB)也要花费约40秒。但是,传递TempFile.path
的速度惊人地快(不到1秒)。
您可能出于自己的原因需要使用AWS::S3::Bucket
方法put_object
,但是put_object
the image in the plot pane still do not have a title是String
或IO
,不是File
或TempFile
路径。如果您可以重构以创建AWS::S3::Object
并使用upload_file
,则可以使用此替代方法。
require 'aws-sdk-s3'
s3_resource = Aws::S3::Resource.new(region: 'us-east-2')
file = Tempfile.new(["testfile", ".pdf"], encoding: "ascii-8bit").tap do |file|
file.write("a"*5000)
end
Benchmark.bm do |x|
x.report {
obj = s3_resource.bucket('mybucket').object("testfile-as-object.pdf")
#passing the TempFile object is quite slow
obj.upload_file(file)
}
end
# user system total real
# 0.010359 0.006335 0.016694 ( 41.175544)
Benchmark.bm do |x|
x.report {
obj = s3_resource.bucket('mybucket').object("testfile-as-path.pdf")
#passing the TempFile object's path is massively faster than passing the TempFile object itself
obj.upload_file(file.path)
}
end
# user system total real
# 0.004573 0.002032 0.006605 ( 0.398605)