Оптимизация lamp-приложения на примере openx: разгоняемся...
DESCRIPTION
Типичная ситуация: имеется существующий веб-проект, написанный с применением Linux, Apache, MySQL и PHP, и заказчик хочет сделать проект быстрее с наиболее полным сохранением функциональности.В данном случае в качестве существующего проекта выступает open source баннерная платформа OpenX, и существенное требование заказчика — разогнать OpenX до пиковой нагрузки в 1000 запросов в секунду и долговременной нагрузки в 600 запросов в секунду.Постановка задачи: отдача JavaScript-баннеров с заданными параметрами производительности при заданном числе объектов системы.Подробно:Краткий обзор объектов предметной области OpenX: баннеры, кампании, зоны.Особенности OpenX: подходы к оптимизации, предлагаемые производителем, несколько раундов оптимизации уже было.Проблемы: алгоритм скрипта выбора баннеров плохо работает при требуемом количестве объектов, имеем CPU-bound систему (обычно IO-bound).Решение: кэширование предрассчитанных данных в БД.Новые вводные от заказчика, поиск компромисса.Сбор информации о системе: точки профилирования в коде скрипта, мониторинг с помощью Cacti и Zabbix.Архитектура системы: типы узлов и связи между узлами. Балансирование нагрузки: nginx vs. HAProxy.Действия после перенесения нагрузки на уровень БД: кэширование в памяти, проблема: много записи на диск.MySQL vs MySQL (выбор движка хранилища), MySQL vs MySQL (выбор сборки: stock, Percona Server, MariaDB), MySQL vs PostgreSQL, MySQL vs in-memory RDBMS, MySQL vs NoSQL.Тюнинг MySQL: параметры конфигурации, параметры платформы (файловая система).Нагрузочное тестирование: как получить 1000 rps от клиента? siege vs JMeter vs Tsung.Эволюция архитектуры. Поиск возможностей шардирования данных.Отказоустойчивость: memcached, moxi, Membase.Управление конфигурацией: проблема развертывания нод и управления нодами.Использование Puppet для управления конфигурацией.TRANSCRIPT
![Page 1: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/1.jpg)
Оптимизация LAMP-приложения на примере OpenX: разгоняемся до
1000 запросов в секунду Александр Чистяков, [email protected],
http://alexclear.livejournal.com
Санкт-Петербург, компания «DataArt»
![Page 2: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/2.jpg)
Кто я?
• alexander@[email protected], [email protected]
• http://alexclear.livejournal.com• Работаю разработчиком ПО с 1998 года• В настоящее время – разработка
высоконагруженных веб-проектов, консультации по вопросам связанным с высокими нагрузками
![Page 3: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/3.jpg)
Почему я?
• Нагрузка 500-5000 пользователей в день есть у всех
• Нагрузка 100500 запросов в секунду – мало у кого есть, но все читают о ней доклады
• Нагрузка 500-1000 запросов в секунду – должна быть интересна слушателям, но неинтересна докладчикам, «гонка за мегагерцы»
• Переход от 1rps к 1000rps порождает ряд однотипных классов проблем
![Page 4: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/4.jpg)
Постановка задачи
• OpenX – существующее open source веб- приложение для показа рекламы
• Linux, Apache, MySQL, PHP• Необходимо выдержать заданные
параметры производительности при заданном количестве объектов предметной области
![Page 5: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/5.jpg)
Предметная область
• OpenX: баннеры, кампании, зоны, пользователи• Баннеры – собственно, баннеры• Пользователи – управляют баннерами• Кампании – содержат баннеры, имеют
приоритеты• Зоны – группируют баннеры и кампании для
расчета весов
![Page 6: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/6.jpg)
Начало
• Одна виртуальная машина в локальной сети
• 1000 баннеров, 1 зона, 1 кампания• ~ 5 запросов в секунду
![Page 7: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/7.jpg)
Требования
• Заказчик – большая компания, требования расплывчаты
• 200000 баннеров, 400-700 запросов в секунду
![Page 8: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/8.jpg)
Особенности OpenX
• Расчет весов баннеров непосредственно в PHP коде при каждом показе
• Продукт уже оптимизирован, есть рекомендации по настройке под высокую нагрузку
• Рекомендации относятся к масштабированию DB уровня
• DB уровень не участвует в расчете весов!
![Page 9: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/9.jpg)
Расчет весов
• Несколько циклов в PHP-коде• 200000 баннеров – 200000 повторений в циклах• Внутренние объекты PHP кэшируются в
подключаемый кэш (memcached)• Максимальный размер объекта для memcached –
1Мб• 200000 баннеров – объекты размером несколько
мегабайт
![Page 10: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/10.jpg)
Оптимизация
• Декомпозиция объектов до уровня отдельных полей, вынос полей в memcached
• Веса рассчитываются один раз в 10 минут и кэшируются в DB
• Алгоритм сведения любого распределения к нормальному – веса объектов на отрезке [0,1], выбор случайного числа -> удобно построить индекс и сделать SQL-запрос
![Page 11: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/11.jpg)
Первые проблемы
• Много запросов к memcached, он почему-то не работает – переход к хранению данных в APC
• Доллго рассчитываются значения весов – необходимо версионирование
• Несколько узлов, но APC локален – у каждого узла свой кэш объектов, взаимных блокировок нет
![Page 12: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/12.jpg)
Тестирование: средства
• Siege, JMeter• JMeter: создание разветвеленных сценариев,
GUI• Siege: URL не меняется, командная строка• Siege: до 700 rps на одной машине (Core i7)• JMeter: до 240 rps на Core i7
![Page 13: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/13.jpg)
Тестирование: результаты
• От трех до семи нод, одна DB• Проблемы: ноды перетирают данные в базе
(нет синхронизации) – сделали синхронизацию через memcached
• Проблемы: APC через некоторое время перестает работать – стандартный glibc аллокатор сильно фрагментирует память (вспомните браузер FF 2.0)
![Page 14: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/14.jpg)
Решение проблем
• Назад к memcached (slab allocator)• php-memcached работает, php-memcache - нет• Нет под Debian Lenny, пришлось сдлать
бэкпорт пакета из Sid• Общий кэш, синхронизация через memcached
на одной ноде• Один экземпляр memcached на всех
![Page 15: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/15.jpg)
Новые вводные данные
• Заказчик – большая компания, нас тоже много• Требования конкретизируются прямо на ходу• Зон может быть до 100• Limitations – работают при каждом запросе,
кэширование всего ряда весов на 10 минут дает ошибочные результаты, так как limitations тоже кэшируются при этом
![Page 16: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/16.jpg)
Новые проблемы
• Если веса нельзя кэшировать, нужно их пересчитывать
• Данные кэшируются для зоны, 100 зон – 100 независимых пересчетов каждые 10 минут
• 200000 баннеров – 2000 баннеров в зоне – по 2000 повторений в циклах в коде PHP при каждом запросе (limitations!)
• 100 зон – 100 наборов таблиц в базе• Что делать?
![Page 17: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/17.jpg)
Варианты решения
• Поменять алгоритм выбора – варианты?• Non-uniform distribution -> uniform distribution – только
через отрезок, при этом 100 пересчетов• Хотим один пересчет• Вариант – наименьшее общее кратное весов, один
отрезок с весами, выраженными через НОК• 200000 баннеров - ~200000 записей в базе• Не выражать через uniform distribution, использовать
веса по-другому
![Page 18: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/18.jpg)
Компромисс
• Баннеров в зоне не более 200• Зон по-прежнему может быть 100• Всего три типа limitations• 200 повторений в циклах PHP –
приемлемо• Оставляем алгоритм расчета через
uniform distribution
![Page 19: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/19.jpg)
Изменения в коде
• Объекты баннеров до применения limitations хранятся в DB
• Limitations транслируются из срокового представления в реляционное – три связи в структуре кэш-таблиц в DB
• Применение limitations к баннерам это просто SQL-запрос
![Page 20: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/20.jpg)
Пара слов о хостинге
• Первый этап – Amazon EC2• Миграция на Rackspace Cloud• Проблемы: средняя нода облачного хостинга
недостаточно производительна, а большая – недостаточно велика
• Недостаточно производительности для создания тестовой нагрузки, недостаточно IOPS для эффективной работы DB
![Page 21: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/21.jpg)
Тестирование: средства
• Siege не подходит: 100 зон, около 50 параметров для каждого из лимитов – нужно менять URL
• JMeter: 240 rps на Core i7, в облаке – меньше
• Tsung
![Page 22: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/22.jpg)
Tsung
• Tsung: написан на Erlang – распределенность на уровне VM языка
• Создавался с учетом многонодовых конфигураций
• Может генерировать необходимую нам нагрузку
• Строит отчеты в виде веб-страниц с графиками
![Page 23: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/23.jpg)
Архитектура
• Представлена на картинке• Картинку перерисовывали 7 раз
![Page 24: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/24.jpg)
Распределение нагрузки
• nginx, HAProxy• nginx – HTTP/1.0, генерирует кучу
соединений, нет встроенного мониторинга состояния
• HAProxy – HTTP/1.1, мониторинг состояния на web-странице, предназначен именно для балансировки, можно задавать политику балансировки
![Page 25: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/25.jpg)
Тестирование: проблемы 1
• 8 web-nod, одна DB, 100 rps• Одна нода memcached не выдерживает поток
запросов• Укрупнение объектов для кэширования в
memcached• Распределенный memcached – на уровне
библиотеки• Экземпляр memcached на каждой ноде
![Page 26: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/26.jpg)
Тестирование: проблемы 2
• 12 web-nod, одна DB, ~250 rps• Большая нагрузка на web-ноды• Из 4-х циклов расчета весов после
применения лимитов к множеству баннеров в зоне 2 цикла можно кэшировать
• В коде осталось 2 цикла из 4-х
![Page 27: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/27.jpg)
Тестирование: проблемы 3
• Включили maintenance скрипт в cron – перестала справляться DB
• Суть проблемы: раз в час таблица с raw logs очищается maintenance скриптом – блокировка таблиц на время удаления
• Очевидные решения: InnoDB вместо MyISAM, разбиение операции удаления на несколько мелких запросов – не помогают
![Page 28: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/28.jpg)
Декомпозиция DB, тюнинг выделенной части
• Выделение raw logs в отдельную базу на отдельном узле
• Попытка поменять тип хранилища – MEMORY вместо InnoDB, ничего не дает, блокировки только хуже
• Мониторинг, тюнинг MySQL – добавление памяти под InnoDB buffer pool, log buffer
![Page 29: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/29.jpg)
Варианты решения
• MariaDB vs Percona Server – разницы в производительности нет
• MySQL vs PostgreSQL• NoSQL vs MySQL• memcached – нет поддержки списков, Redis –
есть поддержка списков, то, что нужно• Проблема: нужно переписывать код• Решение: никуда не мигрировать
![Page 30: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/30.jpg)
Мониторинг
• Zabbix, Cacti• Cacti: mysql-cacti-templates от коллег из
Percona• Zabbix: сильно нагружает сервер, data
backend не в RRD, а в RDBMS, неоптимальные запросы (и неоптимизируемые)
• Zabbix: выше частота опроса, легче смотреть моментальные состояния
![Page 31: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/31.jpg)
Тюнинг FS
• По умолчанию ext3 с data=ordered• Перемонтировали с data=writeback,
iowait вместо ~10% стал ~1.5%• Перемонтировали FS на всех DB нодах с
data=writeback
![Page 32: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/32.jpg)
Тестирование: проблемы 4
• Теперь не справляются кэш-таблицы• На MySQL скачки I/O• Большое количество uncheckpointed bytes в
мониторинге• Решение: вынести кэш-таблицы в отдельную DB• Решение: поменять тип хранилища на MEMORY• TRUNCATE TABLE работает очень быстро
![Page 33: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/33.jpg)
Тестирование: проблемы 5
• 12 web-нод, ~300 rps, три ноды DB• Проблема: скачки I/O на cache DB• Проблема: тест в Tsung бежит 6 часов,
после чего падает• Мониторинг: корреляция падений Tsung
и скачков I/O на DB
![Page 34: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/34.jpg)
Шардинг
• Мысли о шардинге были с самого начала, но по какому параметру разделять по шардам? И какие данные?
• После декомпозиции на три базы ответ стал очевиден: нужно шардить по номеру зоны данные, хранящиеся в кэш-таблицах
• Безграничные возможности для шардинга• Проблема: не все зоны получают одинаковую
нагрузку
![Page 35: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/35.jpg)
Тестирование
• 12 web-нод, 300 rps, три ноды cache DB, одна нода raw logs DB и одна maintenance DB – тест бежит 42 часа, потом падает
• ~650 rps – тест бежит 6-7 часов• Мониторинг: нет корреляции падений
Tsung и событий в системе• Вывод: проблемы Tsung
![Page 36: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/36.jpg)
Предел
• ~700 rps – начинаются ошибки на балансере• Мониторинг: нет корреляции с событиями в
системе• Что падает - непонятно• Но задание уже выполнено – заказчик
счастлив при 300 rps и пике в 600 rps в течение нескольких часов
![Page 37: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/37.jpg)
Отказоустойчивость
• SPOF – распределенные узлы memcached• При падении одного узла таймаут на
обращении к нему – все ложится• Варианты решения: репликация
memcached, проксирование memcached• SPOF: узлы DB
![Page 38: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/38.jpg)
Отказоустойчивость: Moxi
• Проксирование запросов к memcached – Moxi• Составная часть проекта Membase• Работает на 127.0.0.1:11211• Знает топологию узлов memcached, скрывает ее
от пользователя• Может мгновенно исключать упваший узел• Не может перенаправлять запросы к другим узлам
в standalone конфигурации
![Page 39: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/39.jpg)
Отказоустойчивость: Membase
• Работает на порту memcached по его протоколу• Два режима работы: с persistence и как кэш• Web-интерфейс (не конфигурируется через
текстовые файлы)• При падении узла запросы автоматически
перенаправляются на другие узлы• Данные, бывшие на узле, теряются – приложение
должно инициировать пересчет
![Page 40: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/40.jpg)
Отказоустойчивость: MySQL
• Master-slave репликация – не средство обеспечения автоматической отказоустойчивости
• Master-master репликация – менее распространена, делается большим напряжением ума
• SLA 99.95% - достаточно, чтобы время восстановления базы после сбоя было постоянным (InnoDB, обойдемся без репликации)
• DRBD + Heartbeat + Xen
![Page 41: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/41.jpg)
Развертывание
• Chef, Puppet• Оба написаны на Ruby• Про Puppet есть книга, про Chef нет• Chef более ориентирован на развертывание
Ruby-проектов• Puppet: вся конфигурация на сервереЮ, клиент
получает инструкции и разворачивает ноду• Написаны Puppet-скрипты
![Page 42: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/42.jpg)
Команда
• Участвовало от 5 до 8 человек• Разработка, интеграция, тестирование,
документирование, координация• Производительностью занимались
выделенные разработчики• Начало внедрения через полгода после
старта проекта
![Page 43: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/43.jpg)
Что дальше?
• Security assesment• Deployment• Релиз• Задача: распределить ввод-вывод по нескольким
нодам параллельно• Задача: обсчитывать большие объемы для
получения аналитических отчетов• Hadoop, MapReduce jobs вместо SQL
![Page 44: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/44.jpg)
Выводы
• Времени всегда очень мало, вариантов может быть очень много
• Система не должна быть черным ящиком• Не верьте в магию• Прежде, чем оптимизировать, нужно измерить• Знание высокоуровневых принципов
оптимизации не спасает от огромного количества рутины – лучше иметь ответы на вопросы заранее
![Page 45: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/45.jpg)
Вопросы?
• • • •
![Page 46: Оптимизация LAMP-приложения на примере OpenX: разгоняемся до 1000 запросов в секунду](https://reader036.vdocuments.net/reader036/viewer/2022081413/548c9be2b4795927358b4e2c/html5/thumbnails/46.jpg)
Заказчик
• DataArt, http://www.dataart.com• Enjoy IT!• СПб, Большой Сампсониевский, 60А