zfconf 2010: performance of zend framework applications
DESCRIPTION
TRANSCRIPT
Zend Frameworkи производительность
Александр Махомет
27 марта 2010 г.
Санкт-Петербург
О докладчике
• PHP разработчик
• PHP 5 лет
• Zend Framework 3 года
• Создатель сообщества http://zendframework.ru
Производительность это мера скорости работы системы.
Что тестируем?
- Hello World
- Demo сайт
Приложение “Hello World”
• zf create project• ZF ~ 67 файлов• Приложение ~ 5 файлов• Zend_Application, Zend_Loader,
Zend_Controller, Zend_View, Zend_Layout, Zend_Filter
Приложение «Demo сайт»
• Базовые функции среднестатистического сайта• ZF ~ 180 файлов• Приложение ~ 34 файла
• Zend_Application, Zend_Loader, Zend_Controller, Zend_View, Zend_Layout, Zend_Filter
• Zend_Form, Zend_Db, Zend_Translate, Zend_Cache, Zend_Captcha, Zend_Session
Приложение «Demo сайт»
• Статьи и пользователи• Форма, 12 элементов• Блоки, 12 штук• Плагины для фронтконтроллера• Помощники действий• Правила маршрутизации
Где тестируем?
Параметры сервера
• Intel(R) Core(TM)2 Duo CPU E7200 @ 2.53GHz• 2 GB RAM• Linux Debian lenny 8• Apache 2.0• PHP 5.2.6 mod_php + Suhosin Patch 0.9.6.2• Mysql 5.0.51a• Загрузка ~ 0%• Zend Framework 1.10.2 (~ 2700 файлов)
Как тестируем?
Утилиты для тестирования
• Apache Benchmark
• Siege
• Apache Jmeter
Apache Benchmark
• http://httpd.apache.org/docs/2.0/programs/ab.html
• Простой консольный интерфейс
• -с – количество одновременных пользователей
• -n – количество запросов
Concurrency Level: 20Time taken for tests: 1.791 secondsComplete requests: 300Total transferred: 384900 bytesRequests per second: 167.55 [#/sec] (mean)Time per request: 119.370 [ms] (mean)
Percentage of the requests served within a certain time (ms) 50% 108 66% 111 75% 114 80% 115 90% 122 95% 150 98% 200 99% 225 100% 364 (longest request)
Siege
• http://www.joedog.org/index/siege-home
• Простой консольный интерфейс
• Возможность тестировать по набору адресов
• -с – количество одновременных пользователей
• -r – количество запросов
Transactions: 100 hitsAvailability: 100.00 %Elapsed time: 9.10 secsData transferred: 0.10 MBResponse time: 0.12 secsTransaction rate: 10.99 trans/secThroughput: 0.01 MB/secConcurrency: 1.37Successful transactions: 100Failed transactions: 0Longest transaction: 0.55Shortest transaction: 0.10
Apache JMeter
• http://jakarta.apache.org/jmeter/• Графический интерфейс• Широкие возможности• Тестирование по access логу• Различные планы тестирования• Генерация пауз, Pre-Processor и Post-Processor • Assertion механизм• Различные графические и текстовые отчеты
Наш выбор
• Apache Benchmark, как простой и эффективный инструмент
Xdebug
• Читабельные сообщения об ошибках• Трасировка приложения• Профилирование приложения• Отладка приложения
• KCachegrind• WinCachegrind• Webgrind
Акселераторы PHP
Сценарий работы PHP скрипта:
1. Чтение файла
2. Генерация байт-кода
3. Выполнение кода
4. Выдача результата
Задача акселератора – избавиться от шага 2, путем кеширования байт-кода в памяти или на диске.
APC
• http://pecl.php.net/package/apc
• От команды PHP, возможно войдет в ядро PHP6
• Конфигурация APC 3.0.19 :apc.enabled = 1;
apc.shm_size = 30;
apc.max_file_size =10M;
apc.stat = 1;
eAccelerator• http://eaccelerator.net/• Версия eAccelerator 0.9.6 eaccelerator.shm_size="16"accelerator.enable="1"eaccelerator.optimizer="1"eaccelerator.check_mtime="1"eaccelerator.debug="0"eaccelerator.filter=""eaccelerator.shm_max="0"eaccelerator.shm_ttl="0"eaccelerator.shm_prune_period="0"eaccelerator.shm_only="0"eaccelerator.compress="1"eaccelerator.compress_level="9"
Что замеряем
• Количество запросов в секунду- Apache Benchmark (10-30 тестов)- ab -c 50 -n 500 - ab -c 50 -n 300
• Время выполнения скрипта (сек)- PHP функция microtime (10 тестов)
• Память выделяемая для скрипта (мб)- PHP функция memory_get_peak_usage
Перейдем к замерам
• Req/s = 57.69• Time = 0.0286 • Memory = 4.483
• Zend_Application ~ 50%• Action_Helper_ViewRenderer ~ 13%
Hello world
Hello world + Акселераторы
Apc:• Req/s = 135.39• Time = 0.0067 • Memory = 1.423
eAccelerator:• Req/s = 138.73• Time = 0.0065 • Memory = 1.194
Demo сайт
Demo сайт• Req/s = 12.99• Time = 0.1265 • Memory = 14.946
• Zend_Application ~ 15%
• Помощник вида action ~ 30%
• Zend_Form ~ 16%
Замена actionПомощник действия ActionStack:• Req/s = 13.28• Time = 0.12647• Memory = 14.791
Свои помощники вида:• Req/s = 14.41• Time = 0.1148• Memory = 14.45• ~ на 10% уменьшили нагрузку
Zend_Cache
• Поддержка различных бекэнд и фронтэнд адаптеров
• Кэширование на уровне функций, классов, файлов, страниц
• APC, Memcache, File, Sqlite и другие бэкенды
• Кешированние метаданных Zend_Db_Table Zend_Db_Table_Abstract::setDefaultMetadataCache
Кэшируем форму
• Req/s = 17.2• Time = 0.0968• Memory = 13.141• ZF – 165 файлов
Отключаем ViewRenderer
• Zend_Layout и Zend_Form используют ViewRenderer
$front->setParam('noViewRenderer', true);
…
$view = new Zend_View();
$view->setBasePath(APPLICATION_PATH . '/views/');
$layout->setView($view);
…
$form->setView($v);
Результаты
• Req/s = 17.9
• Time = 0.0959
• Memory = 12.551
Небольшой прирост
Отключаем Zend_Application
• Заменяем самописным класом• Req/s = 18.5• Time = 0.0923• Memory = 11.999
Все тесты
Тест 1 Тест 2 Тест 3 Тест 4 Тест 5 Тест 6
Req/s 12.99 13.28 14.41 17.2 17.9 18.5
Time 0.1265 0.12647 0.1148 0.0968 0.0959 0.0923
Mem 14.946 14.791 14.45 13.141 12.551 11.999
Все тесты + APC
Тест 1 Тест 2 Тест 3 Тест 4 Тест 5 Тест 6
Req/s 26.8575 27.295 32.5375 41.95 42.01 42.95
Time 0.05986 0.05947 0.04891 0.03768 0.0361 0.03623
Mem 5.794 5.571 5.306 4.854 4.669 4.497
Все результатыHello worldReq\s: 57.69 → 138.73 (2.4 раза)Time: 0.286 → 0.0065 (4.4 раза)Mem: 4.483 → 1.194 (3.7 раз)
Demo сайт без акселератораReq\s: 12.29 → 18.5 (1.4 раза)Time: 0.1265 → 0.092 1.3 раза)Mem: 14.946 → 11.99 (1.24 раза)
Demo сайт + акселераторReq\s: 26.85 → 42.95 (1.5 раз)Time: 0.0598 → 0.036 1.6 раз)Mem: 5.794 → 4.497 (1.3 раза)
Итого
• Req\s: 12.29 → 42.95
• Time: 0.12 → 0.03
• Memory: 14.94 → 4.49
• ~ 3.5 раза
• Используйте акселераторы
• Кешируйте ресурсоемкие объекты
Сборка ZF в один файл• Большое количество ресурсоемких операций по
подключению файлов• http://isalmin.ru/zfp/• Сборка нужных классов занимает 1.4 мегабайта
Time - 0.1095 sec (Ранее 0.02)Memory - 30.558 Mb (Ранее 4.48)• После включения APCTime - 0.01235 sec (Ранее 0.006)Memory - 9.963 Mb (1.423)• AB показал ухудшение до 85 запросов (~ 1.5 раза)• Вырезание require_once из ZF также не дало
ощутимых результатов
Другие советы от ZF team
• Уменьшайте количество путей в include_path• Добавляйте путь к ZF первым• Используйте абсолютные пути вместо
относительных• Используйте PluginLoader include file cache• Используйте быстрые адаптеры для языковых
данных, array и csv адаптеры• Кешируйте а не считывайте файлы локализации и
интернациолизации• Определяйте наследника Zend_View с часто
используемыми функциями• Используйте render вместо partial
Замечания
• Быстрая, гибкая разработка важнее производительности.
• Тесты теоритические, на реальных проектах все может быть по другому, только экспериментируя и наблюдая за реальным проектом можно существенно улучшить его производительность
• То что работает в одном проекте может не работать в другом.
Спасибо за внимание