问题:
我有一个rails应用程序,需要用户上传某种类型的电子表格(csv, xslx, xsl等)进行处理,这可能是一个昂贵的操作,所以我们决定将其发送到后台服务作为解决这个问题的方法。我们关心的问题是,因为我们的生产系统在Heroku上,我们需要先在AS3上存储文件,然后再检索文件进行处理。
因为上传文件到AS3本身是一个昂贵的操作,这可能也应该作为后台工作来完成。问题是,使用Resque来做这件事可能会消耗大量的RAM,因为Resque需要将文件数据放入Redis或稍后检索。如你所知,Redis只将数据存储在RAM中,并且更喜欢简单的键值对,所以我们希望尽量避免这种情况。
这里有一些伪代码作为我们想要尝试做的例子:
工人/AS3Uploader.rb
require 'fog'
class AS3Uploader
@queue = :as3_uploader
def self.perform(some, file, data)
# create a connection
connection = Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => APP_CONFIG['s3_key'],
:aws_secret_access_key => APP_CONFIG['s3_secret']
})
# First, a place to contain the glorious details
directory = connection.directories.create(
:key => "catalog-#{Time.now.to_i}", # globally unique name
:public => true
)
# list directories
p connection.directories
# upload that catalog
file = directory.files.create(
:key => 'catalog.xml',
:body => File.open(blah), # not sure how to get file data here with out putting it into RAM first using Resque/Redis
:public => true
end
# make a call to Enqueue the processing of the catalog
Resque.enqueue(CatalogProcessor, some, parameters, here)
end
控制器/catalog_upload_controller.rb
def create
# process params
# call Enqueue to start the file processing
# What do I do here? I could send all of the file data here right now
# but like I said previously that means storing potentially 100s of MB into RAM
Resque.enqueue(AS3Uploader, some, parameters, here)
end
我建议你这样做
- 将您的文件存储在您创建的
tmp
目录中,并获得file-path
- 告诉
Resque
使用file-path
上传文件 - 使
Resque
将file-path
存储在redis
而不是整个file-content
中(这将非常昂贵) 现在worker将文件上传到
AWS- S3
注意:如果你有多个实例,比如一个实例用于后台处理,一个实例用于数据库,一个作为实用程序实例,那么你的tmp目录可能对其他实例不可用。所以将文件存储在
目录下的resque
temp
目录下