使用雾删除Rackspace中的大量文件

时间:2014-07-31 20:22:05

标签: ruby fog rackspace cloudfiles rackspace-cloudfiles

我的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

2 个答案:

答案 0 :(得分:1)

是的,您可以使用delete_multiple_objects

  

使用单个请求删除多个对象或容器。

     

要从单个容器中删除对象,可能会提供containerobject_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);
}