Мотиватор :)
С нами с 06.05.09
Сообщения: 3028
Рейтинг: 607
|
Добавлено: 16/07/10 в 01:15 |
Прочитал вчера статью на Хабре и стал потирать руки - а ну-ка я переведу naughtyconnect с ImageMagick на GraphicsMagick и сайт сразу станет работать в 3 раза быстрее.
Всё выглядело слишком хорошо, чтобы быть правдой. Поэтому я установил GraphicsMagick 1.3.12 и расширение php_gmagick. Написал скрипт для теста, который берёт 2740 реальных изображений с сайта (были предварительно свалены в /path-to-pictures/01/) и сделал два бенчмарка: один с использованием gmagick, второй - imagick. Результаты разочаровали.
Тестовый скрипт ресайзит кучу картинок до 150х150 (оригиналы все разного размера, до 1024х768).
Код: [развернуть] |
<?php
$t1 = time();
// get all the JPEG files in a directory
$fileList = glob("/path-to-pictures/01/*.jpg");
foreach ($fileList as $file)
{
$image = new Gmagick();
try
{
$image->readImage($file);
}
catch (exception $e)
{
}
try
{
$image->thumbnailImage(150, 150);
}
catch (exception $e)
{
}
$thumbFile = "./thumbs/" . basename($file, ".jpg") . ".jpg";
try
{
$image->writeImage($thumbFile);
}
catch (exception $e)
{
}
try
{
$image->destroy();
}
catch (exception $e)
{
}
}
$totaltime = time() - $t1;
$total = count($fileList);
$ips = sprintf("%1.2f", $total / $totaltime);
echo "{$total} images thumbnailed, {$totaltime} seconds taken, {$ips} images/sec\n";
?>
|
Тесты запускались на двух разных системах.
Система 1: тестовый сервак на Celeron 1.8 GHz (single core), 1GB RAM, Centos 5.2.
GMagick: 2740 изображений, время выполнения 104 сек, 26.35 изображений/сек
IMagick: 2740 изображений, время выполнения 139 сек, 19.71 изображений/сек
Далее, тот же тест был запущен на другой системе.
Система 2: рабочий сервак на двух Xeon 2.2 Ghz Core 2 Quad (всего 8 ядер), 8GB RAM, Centos 5.2.
GMagick: 2740 изображений, время выполнения 75 сек, 36.44 изображений/сек
IMagick: 2740 изображений, время выполнения 60 сек, 45.55 изображений/сек
Результаты теста показывают, что GMagick на многопроцессорной многоядерной системе делает ресайз изображений медленнее, чем IMagick.
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 16/07/10 в 01:35 |
Дык! Там же про это и написано:
Цитата: | После этого провели ещё один важный тест, чтобы определить оптимальное соотношение потоков в Perl (children) и GraphicsMagick (threads). |
То есть надо именно ресайзящий скрипт пускать в несколько потоков.
|
|
|
|
Мотиватор :)
С нами с 06.05.09
Сообщения: 3028
Рейтинг: 607
|
Добавлено: 16/07/10 в 01:56 |
Noobus Boobus писал: |
Дык! Там же про это и написано:
То есть надо именно ресайзящий скрипт пускать в несколько потоков. |
Это сработает, если одновременно ресайзить 180 миллионов изображений, но как это применить, когда ресайзится в реальном времени, когда юзер просматривает какой-либо профайл?
Можно конечно, создавать тумбы пачкой сразу при загрузке оригинальных картинок на сайт, но опять же, мало кто загружает сразу скажем, 10 изображений.
Цитата: |
После этого процесс запустили на четырёх 16-ядерных серверах Nehalem. В реальности скорость была не такой высокой — опять всё тормозила NFS, но в сумме четыре сервера стабильно выдавали около 180 изображений в секунду.
|
Имхо, замена одного 8-ядерного на четыре 16-ядерных сервера поможет лучше, чем замена ImageMagick на GraphicsMagick :-)
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 16/07/10 в 04:02 |
|
|
|
|
www.phpdevs.com
С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105
|
Добавлено: 16/07/10 в 10:09 |
nginx конечно хоть и народный вэб сервер, но ресайзить им картинки с gdlib - это уже что то вроде бдсм, при этом явно ты не в позиции госпожи
|
|
Пишу на php/mysql/django за вменяемые деньги.
Обращаться в личку.
|
6
|
|
|
С нами с 01.02.07
Сообщения: 231
Рейтинг: 294
|
Добавлено: 16/07/10 в 13:42 |
собственно, а чему тут удивляться ?
gmagic использует несколько ядер для работы над одним изображением, но добавляются накладные расходы на синхронизацию и межядерное копирование данных.
Изначально понятно что ресайзить много картинок эффективнее всего (в плане КПД использования процессорной мощности) в несколько потоков(процессов), каждый из которых занимается только своим файлом. Кол-во потоков равно кол-во ядер плюс несколько резервных чтоб минимизировать простой ядер при блокировании процесса на дисковых операциях.
ЗЫ. статья на хабре действительно интересная, но неправильная: надо было сразу использовать imagic и не nfs, а локальную фс, а файлы заливать (и забирать результат конвертации) по ftp или любым другим удобным способом.
|
|
|
|
Мотиватор :)
С нами с 06.05.09
Сообщения: 3028
Рейтинг: 607
|
Добавлено: 16/07/10 в 15:56 |
zuborg писал: |
ЗЫ. статья на хабре действительно интересная, но неправильная: надо было сразу использовать imagic и не nfs, а локальную фс, а файлы заливать (и забирать результат конвертации) по ftp или любым другим удобным способом. |
конечно же, только на локальной ФС :-) правда, ФТП ещё тот тормоз (слишком много накладных расходов в самом протоколе).
я что-то сомневаюсь, что встроенный ресайз в nginx умеет делать unsharp mask, а без него тумбы выглядят как кучка говна да и не подходит он нам, это же не статика и не блог, а нагрузка бывает весьма серьёзной.
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 16/07/10 в 16:59 |
Нет, бдсм это написание для нгинкса imagick-модуля %)
А вообще, когда-то это делали так:
1. в нгинксе прописываем реврайт с изображения на скрипт
2. скрипт проверяет, есть ли такое изображение в нужном размере, если нет - уменьшает (здесь можно сделать любую обработку)
3. если изображение есть - fpassthru или что-нибудь в этом роде %)
Если хочется еще сильнее ускорить - можно сделать реврайт на скрипт только в случае отсутствия файла, тогда скрипт будет запускаться единожды для каждой картинки.
ЗЫ: ты про кеширование забыл
|
|
|
|
Мотиватор :)
С нами с 06.05.09
Сообщения: 3028
Рейтинг: 607
|
Добавлено: 16/07/10 в 18:38 |
Noobus Boobus писал: |
Если хочется еще сильнее ускорить - можно сделать реврайт на скрипт только в случае отсутствия файла, тогда скрипт будет запускаться единожды для каждой картинки.
ЗЫ: ты про кеширование забыл |
кстати, у меня ещё красивше сделано через самописный плагин к смарти (function thumbnail) - когда смарти парсит темплейт, то проверяет наличие тумб в кэше, и если их нет - создаёт их, а на выходе получаем хтмл с линками на статические картинки :-)
|
|
|
|
www.phpdevs.com
С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105
|
Добавлено: 16/07/10 в 18:56 |
alex.raven: поделись плагинчиком
|
|
Пишу на php/mysql/django за вменяемые деньги.
Обращаться в личку.
|
6
|
|
|
Мотиватор :)
С нами с 06.05.09
Сообщения: 3028
Рейтинг: 607
|
Добавлено: 16/07/10 в 19:07 |
Stek писал: |
alex.raven: поделись плагинчиком |
без проблем - выковыряю только код, специфичный для сайта. тебе понадобится также установленный ImageMagick и расширение php_imagick (или php_magickwand, поддерживаются оба).
|
|
|
|
С нами с 01.02.07
Сообщения: 231
Рейтинг: 294
|
Добавлено: 17/07/10 в 13:19 |
Noobus Boobus писал: | Нет, бдсм это написание для нгинкса imagick-модуля %)
А вообще, когда-то это делали так:
1. в нгинксе прописываем реврайт с изображения на скрипт
2. скрипт проверяет, есть ли такое изображение в нужном размере, если нет - уменьшает (здесь можно сделать любую обработку)
3. если изображение есть - fpassthru или что-нибудь в этом роде %)
Если хочется еще сильнее ускорить - можно сделать реврайт на скрипт только в случае отсутствия файла, тогда скрипт будет запускаться единожды для каждой картинки.
ЗЫ: ты про кеширование забыл |
Правильный подход, от себя добавил бы что надо и блокировками пользоваться, а-ля flock(2) - чтоб не запускать 100 процессов ресайза одновременно и не ресайзить один и тот же файл в нужный размер несколько раз паралельно.
|
|
|
|
С нами с 01.03.06
Сообщения: 629
Рейтинг: 620
|
Добавлено: 17/07/10 в 15:33 |
Оффтопик: только вот flock хреновый помощник при даже небольшой конкуренции, не работает он как обычно хочется, о чем в офф. доке кстати и написано. на семафоры уже переходить прийдется, если нет желания дважды/трижды работу одну и туже на серве делать
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 18/07/10 в 01:57 |
Опережающее обновление кеша здесь не прокатит по понятным причинам, так что да, race conditions в полный рост. Хорошо, что ресайз не занимает столько времени, как, например, толстый запрос к БД.
|
|
|
|
С нами с 01.02.07
Сообщения: 231
Рейтинг: 294
|
Добавлено: 19/07/10 в 15:07 |
Heavy писал: | Оффтопик: только вот flock хреновый помощник при даже небольшой конкуренции, не работает он как обычно хочется, о чем в офф. доке кстати и написано. на семафоры уже переходить прийдется, если нет желания дважды/трижды работу одну и туже на серве делать |
А подробней можно, если не секрет ? В чем проблема с использованием flock ?
Для блокирования файлов он подходит идеально.
Для установки N одновременных блокировок на N ядер да - надо использовать семафоры, по определению. Но для случая когда нагрузка не высокая и все N ядер одновременно блокируются нечасто можно в цикле пытаться ставить лок на каждое ядро через flock и делать sleep на короткое время в расчете что когда-то какое-то ядро окажется свободным - тоже будет работать.
Просто flock здесь в паралельной конвертации файлов - защита от лишней работы и предохранитель от перегруза сервера.
|
|
|
|
Чингачгук, вождь красноглазых
С нами с 14.05.04
Сообщения: 4744
Рейтинг: 1824
|
Добавлено: 19/07/10 в 20:45 |
Вообще это жестоко - такие конкурирующие процессы толстые запускать на каждый запрос по HTTP. Процесс такой, конвертирования, должен быть один - проверяем, запущен или нет (еще лучше - постоянно запущен), если нет - запускаем, потом коннектимся по сокету юниксовому, скармливаем задачу, и ждем сигнала. Он ставит их в очередь и обрабатывает по мере сил, обработал картинку - кидает сигнал ждущему процессу. Минимальное количество процессов => максимальная производительность сервера. Плюс никаких проблем с межпроцессными блокировками файлов, которые, на самом деле, на одной OS заработают по одному, а на другой - хз как или вообще не заработают. Чисто кондовый юниксовый API времен SunOS
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 20/07/10 в 00:43 |
Dr.Syshalt писал: | Вообще это жестоко - такие конкурирующие процессы толстые запускать на каждый запрос по HTTP. |
Да ну, это разве толстые. Толстые - они совсем другие %)
Цитата: | В чем проблема с использованием flock ? |
Проблема в том, что скрипт натыкается на флок уже в тот момент, когда обнаруживает, что картинки нет, и ее пора генерить. То есть, в обычной ситуации, он дождется окончания флока и сгенерит картинку еще раз.
В общем, тут логику надо писать уже по ситуации. На мой непросвещенный взгляд, в большинстве случаев не стоит и огород городить. Оченно дешевые нынче железяки пошли.
|
|
|
|
Чингачгук, вождь красноглазых
С нами с 14.05.04
Сообщения: 4744
Рейтинг: 1824
|
Добавлено: 20/07/10 в 11:49 |
Noobus Boobus писал: | Да ну, это разве толстые. Толстые - они совсем другие %)
...
Оченно дешевые нынче железяки пошли. |
Вот так и рождается говнософт наподобие mechtube всяких, где запрос на морде отрабатывает по 40 секунд.
|
|
|
|
С нами с 16.10.09
Сообщения: 343
Рейтинг: 419
|
Добавлено: 20/07/10 в 13:58 |
Есть прекрасная альтернатива в виде заоптимизированного по самые уши суперсофта со вставками на ассемблере, который так никогда и не будет дописан до конца %)
|
|
|
|