Перенос данных из EC2 в S3? - PullRequest
       15

Перенос данных из EC2 в S3?

1 голос
/ 01 ноября 2009

Я запускаю приложение Rails, использующее Paperclip, чтобы заботиться о вложенных файлах, изменении размера изображений и т. Д. В настоящее время приложение размещено в облаке EngineYard, и все вложения хранятся в их EBS. Думая об использовании S3 для обработки всех вложений Paperclip.

Кто-нибудь знает хороший и безопасный способ для этой миграции? большое спасибо!

Ответы [ 2 ]

3 голосов
/ 17 февраля 2010

Я оказался в такой же ситуации, взял код Бенси и заставил его работать на себя - вот что я придумал:

require 'aws/s3'

# Ensure you do the following:
#   export AMAZON_ACCESS_KEY_ID='your-access-key'
#   export AMAZON_SECRET_ACCESS_KEY='your-secret-word-thingy'
AWS::S3::Base.establish_connection!


@failed = []
@attachments = Asset.all # Asset paperclip attachment is: has_attached_file :attachment....
@attachments.each do |asset|
  begin
    puts "Processing #{asset.id}"
    base_path = RAILS_ROOT + '/public/'
    attachment_folder = ((asset.respond_to?(:parent_id) && asset.parent_id) || asset.id).to_s
    styles = asset.attachment.styles.keys
    styles << :original
    styles.each do |style|
      full_filename = File.join(base_path, asset.attachment.url(style, false))


      AWS::S3::S3Object.store(
        'attachments/' + attachment_folder + '/' + style.to_s + "/" + asset.attachment_file_name,
        File.open(full_filename),
        "swellnet-assets",
        :content_type => asset.attachment_content_type,
        :access => (style == :original ? :private : :public_read)
      )

      if AWS::S3::Service.response.success?        
        puts "Stored #{asset.id}[#{style.to_s}] on S3..."
      else
        puts "There was a problem uploading " + full_filename
      end
    end
  rescue
    puts "Error with #{asset.id}"
    @failed << asset.id
  end
end

puts "Failed uploads: #{@failed.join(", ")}" unless @failed.empty?

Конечно, если у вас есть несколько моделей, вам нужно будет настроить их по мере необходимости ...

3 голосов
/ 02 ноября 2009

Вы можете выполнить задачу rake, которая перебирает ваши вложения и отправляет каждое из них на S3. Я использовал это некоторое время назад с attachment_fu - не будет слишком отличаться. Это использует драгоценный камень aws-s3.

В основном этот процесс: 1. Выберите файлы из базы данных, которые необходимо переместить 2. подтолкнуть их к S3 3. Обновите базу данных, чтобы отразить, что файл больше не хранится локально (таким образом, вы можете делать это в пакетном режиме и вам не нужно беспокоиться о том, чтобы дважды нажать один и тот же файл).

@attachments = Attachment.stored_locally
@attachments.each do |attachment|

  base_path = RAILS_ROOT + '/public/assets/'
  attachment_folder = ((attachment.respond_to?(:parent_id) && attachment.parent_id) || attachment.id).to_s
  full_filename = File.join(base_path, ("%08d" % attachment_folder).scan(/..../), attachment.filename)
  require 'aws/s3'

  AWS::S3::Base.establish_connection!(
    :access_key_id        => S3_CONFIG[:access_key_id],
    :secret_access_key    => S3_CONFIG[:secret_access_key]
  )

  AWS::S3::S3Object.store(
    'assets/' + attachment_folder + '/' + attachment.filename,
    File.open(full_filename),
    S3_CONFIG[:bucket_name],
    :content_type => attachment.content_type,
    :access => :private
  )

  if AWS::S3::Service.response.success?
    # Update the database
    attachment.update_attribute(:stored_on_s3, true)

    # Remove the file on the local filesystem
    FileUtils.rm full_filename

    # Remove directory also if it is now empty
    Dir.rmdir(File.dirname(full_filename)) if (Dir.entries(File.dirname(full_filename))-['.','..']).empty?
  else
    puts "There was a problem uploading " + full_filename
  end
end
...