Как при помощи WP-CLI пересоздать150k изображений

Для сайтов с большим количеством контента, каждый редизайн обычно превращается в целое большое дело, потому как размеры и пропорции изображений использованных в постах часто меняются, а как известно в WordPress изображения создаются только при загрузке и после хранятся на диске в виде файлов фиксированного размера.

С другими CMS ситуация не всегда лучше например Drupal 7 при отсутствии необходимого размера изображения пытается создать его что называется «на лету» и записать результат в виде метаинформации в базу, это удобно когда изображений мало, сайт не посещаемый и не используется какое либо агрессивное кеширование, в противном случае либо кеш не даст картинка создаться, либо поток посетителей просто положит сервер, множеством запросов создание новых изображений. А в моем случае нужно было пересоздать около 150 000 изображений на не очень мощном сервере при этом сайт был очень даже посещаемый.

Для WordPress есть замечательный плагин Regenerate Thumbnails он хорош всем но как я уже говорил, картинок было очень много у меня были вполне конкретные сомнения на его счет например на счет времени в течении которого придется держать открытой вкладку браузера несколько суток, и того что будет с браузером и оперативной памятью после того как на страницу добавится сотня тысяч элементов Javascript-ом.

WordPress Regenerate Thumbnails bulk action

Поэтому я решил искать промышленное решение.

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

Поэтому я решил попробовать WP-CLI — wp-cli.org это консольная утилита, а значит я точно смогу запустить её в фоновом процессе через screen как я это делал в случае с дампом и не держать свой рабочий компьютер включенным в течении всего процесса. Она способна выполнять некоторые манипуляции с ядром и плагинами WordPress и даже исполнять произвольный код при помощи eval.

Я конечно же очень быстро установил WP-CLI и начал пробовать стандартную рекомендуемую команду из мануала:

 wp media regenerate --yes 

Но результат меня не впечатлил своей своей скоростью нужно было запустить несколько потоков дабы успеть к установленному сроку.

Решение нашлось достаточно быстро:

wp media regenerate $(wp eval 'foreach (get_posts(array("post_type" => "attachment","posts_per_page" => -1,"year" => 2012)) as $post) {echo $post->ID . " ";}')

При помощи ранее упомянутого eval делаем запрос на получение всех изображений например за 2012 год после выводим их ID через пробей и записываем весь код в строку.

В результате так я и расапаралелил процесс в сроки уложился но по пути нашел еще одни грабли, в некоторые годы фотографий было особенно много и WP-CLI ругался на то что достигнуто максимально возможное число аргументов для передачи в командной строке и обработать не в силах. Такого по идее не должно быть потому как во всех мануалах что я видел по php написано что лимитов на число аргументов нет. Тогда я с этим не стал разбираться и разбил год еще и на месяцы, а сейчас руки не доходят найти причину так просто примите во внимание если ваш сайт уж очень большой, и отпишитесь в комментариях если знаете с чем это связанно.

2 Комментариев

  1. Есть еще такой вариант регенерации:

    wordpress.org/plugins/ajax-thumbnail-rebuild/

    Но вообще решение с помощью wp-cli очень изящное.

    • Ну да по сравнению с regenerate thumbnails этот плагин должен быстрее справится, но нужно уточнить что 150 тыс. было оригиналов и 5 размеров нужно было нарезать дополнительно, поэтому все равно было бы долго)) была еще мысль оригинальная в качестве запасного варианта если wp-cli не справится сделать ресайз на уровне модулей nginx прямо на лету, но не довелось

      Надо будет как нибудь попробовать, как так сделать, но в 90% случаев лучше photon включить.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *