我的Rackspace文件中有数百万个文件。我想删除它们中的一部分,传递文件名列表而不是逐个删除,这非常慢。有没有办法用雾做这个?现在,我有一个删除每个文件的脚本,但是能够获得更好的性能会更好。
connection = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => "xxxx",
:rackspace_api_key => "xxxx",
:rackspace_region => :iad
})
dir = connection.directories.select {|d| d.key == "my_directory"}.first
CloudFileModel.where(duplicated: 1).each do |record|
f = record.file.gsub("/","")
dir.files.destroy(f) rescue nil
puts "deleted #{record.id}"
end
答案 0 :(得分:1)
是的,您可以使用delete_multiple_objects。
使用单个请求删除多个对象或容器。
要从单个容器中删除对象,可能会提供
container
,object_names
应该是容器中的对象名称数组。要从多个容器中删除对象或删除容器,
container
应为nil
,所有object_names
都应以容器名称为前缀。删除时容器必须为空。
object_names
按给定的顺序处理,因此应首先列出容器中的对象以清空容器。单个请求中最多可删除10,000个对象。对于所有请求,服务器将使用
200 OK
进行响应。必须检查response.body
的实际结果。实施例: 从容器中删除对象
object_names = ['object', 'another/object']
conn.delete_multiple_objects('my_container', object_names)
从多个容器中删除对象
object_names = ['container_a/object', 'container_b/object']
conn.delete_multiple_objects(nil, object_names)
删除容器及其所有对象
object_names = ['my_container/object_a', 'my_container/object_b', 'my_container']
conn.delete_multiple_objects(nil, object_names)
答案 1 :(得分:0)
据我所知,此处包含的算法是最可靠,性能最高的算法,用于删除Cloud Files容器及其包含的任何对象。可以通过在参数中包含要删除的项目名称而不是调用ListObjects
来为您的目的修改算法。在撰写本文时,没有能够及时满足您需求的服务器端功能(即批量操作)。批量操作的速率限制为每秒2-3次删除操作,因此每删除10,000个项目至少需要55分钟。
以下代码显示了基本算法(稍微简化了.NET SDK中实际需要的语法)。它假定在执行此方法后,任何其他客户端都不会在任何时候向容器添加对象。
请注意,您将被限制为最多包含文件的每个容器每秒100次删除操作。如果涉及多个容器,请分发并发请求以将请求循环到每个容器。将并发级别调整为接近硬率限制的值。使用这种算法可以让我在涉及多个容器时达到超过450个物体/秒的长期持续删除率。
public static void DeleteContainer(
IObjectStorageProvider provider,
string containerName)
{
while (true)
{
// The only reliable way to determine if a container is empty is
// to list its objects
ContainerObject[] objects = provider.ListObjects(containerName);
if (!objects.Any())
break;
// the iterations of this loop should be executed concurrently.
// depending on connection speed, expect to use 25 to upwards of 300
// concurrent connections for best performance.
foreach (ContainerObject obj in objects)
{
try
{
provider.DeleteObject(containerName, obj.Name);
}
catch (ItemNotFoundException)
{
// a 404 can happen if the object was deleted on a previous iteration,
// but the internal database did not fully synchronize prior to calling
// List Objects again.
}
}
}
provider.DeleteContainer(containerName);
}