1

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

2 回答 2

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)
于 2014-07-31T22:09:58.520 回答
0

据我所知,这里包含的算法是删除云文件容器及其包含的任何对象的最可靠和性能最高的算法。该算法可以根据您的目的进行修改,方法是包含一个带有要删除的项目名称的参数,而不是调用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);
}
于 2014-08-01T15:11:50.930 回答