Загружает ли AWS SDK для Ruby объекты S3 во время перечисления сегментов?

При использовании Amazon Ruby SDK для S3 мне нужно перечислить ВСЕ файлы в огромной корзине, чтобы определить любые пустые файлы, т. е. obj.content_length == 0

Я написал скрипт, чтобы сделать это следующим образом:

bucket.objects.each() do |obj|
  total_objs += 1

  if obj.content_length == 0 then
    empty_files += 1
    puts obj.key
  end
end

... но я обеспокоен тем, что это приведет к загрузке каждого файла для определения размера файла. Действительно ли SDK загружает файл, чтобы узнать размер, или это просто метаданные, которые извлекаются, а затем объект загружается лениво, если вызывается соответствующий метод?

Кроме того, есть ли более эффективный способ добиться того, что я пытаюсь сделать?


person RTF    schedule 12.01.2015    source источник


Ответы (1)


Самый простой способ получить то, что вы хотите, — это использовать SDK AWS v2 для Ruby, доступный как aws-sdk-core:

require 'aws-sdk-core'

empty_files = 0    

s3 = Aws::S3::Client.new
s3.list_objects(bucket:'aws-sdk').each do |resp|
  resp.contents.each do |obj|
    if obj.content_length == 0
      empty_files += 1
      puts obj.key
    end
  end
end

Приведенный выше код выполняет ровно 1 запрос на 1 тыс. объектов (S3 возвращает информацию только о 1 тыс. объектов на ответ). Он использует встроенную в SDK функцию пейджинга ответов клиентов, чтобы гарантировать, что вы продолжаете вызывать #list_objects, пока не исчерпаете корзину. Это не загрузит тела объектов, для этого вы можете вызвать Aws::S3::Client#get_object.

ОБНОВИТЬ:

SDK версии 2 теперь поддерживает это с интерфейсом, ориентированным на ресурсы. Тот же пример кода выше с использованием aws-sdk-resources:

require 'aws-sdk' # must be v2 sdk

empty_files = 0

s3 = Aws::S3::Resource.new
s3.bucket('aws-sdk').objects.each do |obj|
  if obj.size == 0
    empty_files += 1
    puts obj.key
  end
end
person Trevor Rowe    schedule 14.01.2015
comment
Пока я работал над своим скриптом (делал что-то немного другое, но все еще искал размер файла), я случайно попытался получить длину содержимого объекта, которого нет в моей корзине. Я не спасал ошибку, и трассировка стека указывала, что для получения длины содержимого выполняется head request. Поэтому я думаю, что даже старый SDK загружает объект только в случае необходимости. Тем не менее, ваше решение кажется гораздо более эффективным. - person RTF; 14.01.2015
comment
Да, SDK v1 отправляет запрос HEAD для получения длины содержимого. Но он не загружает объект, а получает только заголовки объекта. Все еще не идеально, но данные объекта не загружаются. - person Trevor Rowe; 15.01.2015