环境:
- Windows 10 x64
- Ruby 2.1.0 32 位
- Chef 2015年12月12日
- azure gem 0.7.9
- Azure-Storage Gem 0.12.1.preview
我正在尝试从容器下载约 880MB 的 blob。当我这样做时,在 Ruby 进程大小达到约 500MB 后,它会抛出以下错误:
C:/opscode/chefdk/embedded/lib/ruby/2.1.0/net/protocol.rb:102:in `read': failed to allocate memory (NoMemoryError)
我已经在 Ruby 内部和外部以及 Azure gem 和 Azure-Storage gem 上尝试过此操作。所有四种组合的结果都是相同的(Chef 中的 Azure、Ruby 中的 Azure、Chef 中的 Azure-Storage、Ruby 中的 Azure-Storage)。
我发现的针对此类问题的大多数故障排除都建议对下载进行流式传输或分块下载,但似乎没有相应的方法或 get_blob 选项来执行此操作。
代码:
require 'azure/storage'
# vars
account_name = "myacct"
container_name = "myfiles"
access_key = "mykey"
installs_dir = "myinstalls"
# directory for files
create_dir = 'c:/' + installs_dir
Dir.mkdir(create_dir) unless File.exists?(create_dir)
# create azure client
Azure::Storage.setup(:storage_account_name => account_name, :storage_access_key => access_key)
azBlobs = Azure::Storage::Blob::BlobService.new
# get list of blobs in container
dlBlobs = azBlobs.list_blobs(container_name)
# download each blob to directory
dlBlobs.each do |dlBlob|
puts "Downloading " + container_name + "/" + dlBlob.name
portalBlob, blobContent = azBlobs.get_blob(container_name, dlBlob.name)
File.open("c:/" + installs_dir + "/" + portalBlob.name, "wb") {|f|
f.write(blobContent)
}
end
我还尝试使用 IO.binwrite() 而不是 File.open() 并得到了相同的结果。
建议?
最佳答案
正如 @coderanger 所说,您的问题是由于使用 get_blob
将数据立即本地化到内存中引起的。有两种方法可以解决。
- 根据官方 REST 引用 here如下。
The maximum size for a block blob created via Put Blob is 256 MB for version 2016-05-31 and later, and 64 MB for older versions. If your blob is larger than 256 MB for version 2016-05-31 and later, or 64 MB for older versions, you must upload it as a set of blocks. For more information, see the Put Block and Put Block Listoperations. It's not necessary to also call Put Blob if you upload the blob as a set of blocks.
因此,对于由 block blob组成的blob,可以尝试通过list_blob_blocks
获取 block blob列表,将这些 block blob一一写入本地文件。
- 通过
signed_uri
生成带有 SAS token 的 Blob URL,例如 this test code ,然后通过流式下载 blob 写入本地文件。
关于ruby - 在 Ruby 中下载 Azure Blob 时出现 NoMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43724274/