Импорт, изменение размера и загрузка миллионов изображений в Amazon S3 - PullRequest
2 голосов
/ 04 мая 2011

Мы используем PHP с CodeIgniter для импорта миллионов изображений из сотен источников, изменения их размера локально и последующей загрузки измененной версии в Amazon S3. Однако этот процесс занимает гораздо больше времени, чем ожидалось, и мы ищем альтернативы для ускорения процесса. Для более подробной информации:

  • В нашей базе данных MySQL производится поиск изображений, размер которых еще не был изменен. Результатом является набор изображений.
  • Каждое изображение импортируется отдельно с использованием cURL и временно размещается на нашем сервере во время обработки. Они импортируются локально, потому что библиотека не позволяет изменять размер / обрезать внешние изображения. Согласно некоторым тестам разница в скорости при импорте из разных внешних источников составляла от 80 до 140 секунд (для всего процесса, используя 200 изображений на тест), поэтому внешний источник может определенно замедлить процесс.
  • Размер текущего изображения изменяется с помощью библиотеки image_moo , которая создает копию изображения
  • Изображение с измененным размером загружается в Amazon S3 с помощью библиотеки CodeIgniter S3
  • URL-адрес S3 для нового изображения с измененным размером затем сохраняется в таблице базы данных, прежде чем начинать со следующего изображения

Процесс занимает 0,5-1 секунду для каждого изображения, а это означает, что все текущие изображения будут занимать месяц для изменения размера и загрузки в S3. Основная проблема заключается в том, что мы постоянно добавляем новые источники изображений и ожидаем, что до конца 2011 года будет получено не менее 30-50 миллионов изображений по сравнению с нынешними 4 миллионами в начале мая.

Я заметил один ответ в StackOverflow, который мог бы стать хорошим дополнением к нашему решению, где размеры изменяются и загружаются на лету , но, поскольку мы не хотим ненужных задержек, когда люди посещают страницы Нам нужно убедиться, что как можно больше изображений загружено. Кроме того, мы хотим иметь несколько форматов изображений и в настоящее время загружаем только самый важный из-за этой проблемы со скоростью. В идеале у нас должно быть как минимум три формата (например, один эскиз, один нормальный и один большой) для каждого импортированного изображения.

Кто-то предложил сделать массовую загрузку на S3 несколько дней назад - будет полезен любой опыт, позволяющий сэкономить.

Ответы на любую часть вопроса будут полезны, если у вас есть некоторый опыт аналогичного процесса. Часть кода (упрощенно)

$newpic=$picloc.'-'.$width.'x'.$height.'.jpg';
$pic = $this->image_moo
        ->load($picloc.'.jpg')
    ->resize($width,$height,TRUE)
    ->save($newpic,'jpg');
if ($this->image_moo->errors) { 
    // Do stuff if something goes wrong, for example if image no longer exists - this doesn't happen very often so is not a great concern
}
else {
        if (S3::putObject(
        S3::inputFile($newpic), 
        'someplace', 
        str_replace('./upload/','', $newpic), 
        S3::ACL_PUBLIC_READ,
        array(),
        array( 
        "Content-Type" => "image/jpeg",
    )))
 { // save URL to resized image in database, unlink files etc, then start next image

Ответы [ 2 ]

3 голосов
/ 04 мая 2011

Почему бы не добавить логику переноса, которая позволяет вам определять диапазоны или группы изображений, а затем запускать сценарий несколько раз на сервере.Если у вас может быть четыре из этих процессов, запущенных одновременно на разных наборах изображений, то он завершится в четыре раза быстрее!можно было бы посмотреть на раскрутку некоторых экземпляров Amazon EC2 и использовать их для дальнейшей параллелизации процесса.

1 голос
/ 04 мая 2011

Я предлагаю вам разбить ваш скрипт на 2 скрипта, которые работают одновременно. Можно было бы получать удаленные изображения в локальный источник, просто делая это для любых / всех изображений, которые еще не были обработаны или кэшированы локально. Поскольку удаленные источники добавляют к вашим запросам небольшую задержку, вы будете извлекать пользу из постоянной загрузки удаленных изображений, а не только при обработке каждого из них.

Одновременно вы используете второй скрипт для изменения размера любых локально кэшированных изображений и загрузки их в Amazon S3. Вы также можете разделить эту часть процесса, используя один сценарий для изменения размера локального файла, а затем другой для загрузки любых измененных файлов на S3.

Первая часть (извлечение образа из удаленного источника) будет очень полезна при запуске нескольких параллельных экземпляров, как предлагает Джеймс С. выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...