Ключевые слова:apache, web, optimization, tune, speed, (найти похожие документы)
From: Александр Кубышкин <http://www.techinfo.net.ru>
Date: Mon, 14 Feb 2005 18:21:07 +0000 (UTC)
Subject: Заметки по производительности Apache
Оригинал: http://www.techinfo.net.ru/web/optimization/perf-tuning.ru.php
Заметки по производительности Apache
* Введение
* Вопросы о "железе" и ОС
* Вопросы Run-Time конфигурации
* Вопросы компилирования
* Приложение
+ Модель Пред-Ветвления
Введение
Apache - это обычный веб-сервер, спроектированный чтобы во-первых быть
корректным, а во-вторых - быстрым. И даже при этих условиях его
производительность довольно хороша. Большинство сайтов имеют меньше,
чем 10Мбит/сек. исходящяго канала, который Apache может забить
используя всего лишь старенький Pentium-сервер. На практике, сайты с
более широкими каналами требуют более чем одну машину чтобы заполнить
канал, из-за других ограничений (таких как CGI или расходы на
транзакции баз данных). Из-за этих причин разработка была
сфокусирована на корректности и конфигурировании.
К сожалению, многие люди не обращают внимания на эти факты и цитируют
сырые значения производительности, как будто они отражают качество
продукта. Существует четкий минимум производительности, который
является приемлемым, за этим минимумом экстра-скорость выводит продукт
на много меньший сегмент рынок. Но для того, чтобы избежать барьеров в
выводе Apache на некоторые рынки, были приложены некоторые усилия к
Apache 1.3, чтобы достичь той производительности, когда разница с
другими high-end серверами будет минимальна.
В конце концов есть люди, которые всего лишь хотят увидеть насколько
быстро что-то может работать. Автор попадает в эту категорию.
Оставшаяся часть документа посвящена тем людям, которые хотят выжать
до последнего бита производительности из текущей модели Apache и хотят
понять, откуда берутся вещи, которые его тормозят.
Замечу, что все это относится к Apache 1.3 под Unix. Некоторые вещи
применимы к Apache под NT. Производительность Apache под NT еще не
была оптимизирована; фактически, он, возможно, выполняется очень
медленно, так как производительность под NT требует другую модель
программирования.
Вопросы о "железе" и ОС
Единственный огромнейший вопрос, касающийся производительности
веб-сервера - это RAM. Веб-сервер не должен никогда свопиться, так как
своп увеличивает задержку каждого запроса выше точки, которую
пользователь считает "достаточно быстро". Вы можете (и должны)
контролировать параметр MaxClients, чтобы ваш веб-сервер не создал
столько копий процесса, чтобы начать свопиться. Процедура для этого
проста: определите средний размер процесса Apache, просматривая список
процессов при помощи top, и разделите общий размер памяти на это
число, оставив некоторый запас для других процессов.
После этого всё остальное - более "земное": найдите достаточно быстрый
CPU, достаточно быструю сетевую карту, достаточно быстрые диски, где
термин "достаточно быстрые" определяется экспериментальным путем.
Выбор ОС во многом дело личных предпочтений. Но основное указание -
это всегда применять последние TCP/IP патчи от производителя.
Вопросы Run-Time конфигурации
HostnameLookups и другие рассуждения про DNS
До 1.3, HostnameLookups по умолчанию установлен в On. Это
добавляет задержку на каждый запрос, потому что он требует поиск DNS
для выполнения, до окончания запроса. В Apache 1.3 этот параметр по
умолчанию установлен в Off. Если вам нужно, чтобы адреса в лог файлах
были определены в имена хостов, используйте logresolve программу,
которая идет вместе с Apache, или один из множества пакетов создания
отчетов по лог файлам.
Рекомендуется делать пост-обработку лог файлов на другой машине,
нежели на "рабочем" веб-сервере, чтобы эта деятельность не отразилась
неблагоприятно на производительности веб-сервера.
Если вы используете одну из Allow from domain или Deny from
domain директив (т.е., используете имя хоста или доменное имя вместо
IP адреса), тогда вы платите за двойное обратное разрешение имени
DNS(обратное следует за прямым, чтобы быть уверенным в том, что
обратный не был подделан). Поэтому, для лучшей производительности,
используйте IP адреса, вместо имен, когда используете эти директивы,
если это возможно.
Замечу, что можно ограничить область действия этих директив, например
с помощью <Location /server-status> секции. В этом случае поиск DNS
будет выполнен только на запросах, которые удовлетворяют критериям.
Вот пример, который запрещает разрешение имен для всех, кроме .html и
.cgi файлов:
HostnameLookups off
<Files ~ "\.(html|cgi)$">
HostnameLookups on
</Files>
Но даже если вам нужны DNS имена в некоторых CGI программах, вы можете
обдумать выполнение вызова gethostbyname в тех специфичных CGI
программах, которым это надо.
FollowSymLinks и SymLinksIfOwnerMatch
В каком бы месте URL у вас не были включены Options FollowSymLinks или
Options SymLinksIfOwnerMatch Apache выполнит дополнительные системные
вызовы для проверки символических ссылок. Один дополнительный запрос
на каждый компонент имени файла. К примеру, если у вас есть:
DocumentRoot /www/htdocs
<Directory />
Options SymLinksIfOwnerMatch
</Directory>
и запрос сделан для URI /index.html, тогда Apache сделает lstat(2) на
/www, /www/htdocs и /www/htdocs/index.html. Результаты этих lstats
никогда не кэшируются, поэтому они будут происходить на каждом
запросе. Если вам действительно нужны проверки безопасных
символических ссылок, вы можете сделать, к примеру, так:
DocumentRoot /www/htdocs
<Directory />
Options FollowSymLinks
</Directory>
<Directory /www/htdocs>
Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>
По крайней мере, так не будут выполнены проверки для пути
DocumentRoot. Замечу, что вам нужно добавить подобные секции, если у
вас есть что-нибудь из Alias или RewriteRule путей снаружи вашего
корня документов(document root). Для наивысшей производительности и
отсутствия защиты символических ссылок установите везде FollowSymLinks
и никогда не устанавливайте SymLinksIfOwnerMatch.
AllowOverride
Если где-нибудь в URL-пространстве вы разрешите
переопределения(overrides) (обычно файлы .htaccess) Apache будет
пытаться открыть .htaccess для каждого компонента имени файла. К
примеру,
DocumentRoot /www/htdocs
<Directory />
AllowOverride all
</Directory>
и запрос сделан для URI /index.html, тогда Apache будет пытаться
открыть /.htaccess, /www/.htaccess и /www/htdocs/.htaccess. Решения
похожи на предыдущий случай Options FollowSymLinks. Для наибольшей
производительности используйте AllowOverride None везде в вашей
файловой системе.
См. также руководство по .htaccess для дальнейших обсуждений этой
темы (http://httpd.apache.org/docs/howto/htaccess.html).
Согласование (Negotiation)
Если возможно, избегайте согласования содержания(content-negotiation),
если вы действительно заинтересованы до последней унции
производительности. На практике преимущества согласования перевешивают
понижение в производительности. Есть один случай, когда вы можете
ускорить сервер. Вместо использования джокера(wildcard) так:
DirectoryIndex index
Используйте полный список опций:
DirectoryIndex index.cgi index.pl index.shtml index.html
где вы указываете самый употребительный выбор вначале.
Если вашему сайту нужно согласование содержания, подумайте над
использованием файлов type-map, вместо директивы Options MultiViews
для выполнения согласования. См. документацию [19]Content Negotiation
для более полного обсуждения методов согласования и инструкций для
созданий файлов type-map.
Создание процесса
До Apache 1.3 все параметры MinSpareServers, MaxSpareServers,
и StartServers имели огромные эффекты на результатах измерений
скорости. В частности, Apache требовал нарастающий("ramp-up") период
для того, чтобы достигнуть количества потомков, способных обслужить
возросшую нагрузку. После начального создания потомков в количестве
StartServers штук, только один потомок в секунду мог быть создан,
чтобы удовлетворить параметру MinSpareServers. Поэтому, серверу, к
которому одновременно обратились 100 клиентов, используя значение
StartServers по умолчанию равным 5, потребуется 95 секунд, чтобы
создать требуемое для нагрузки количество потомков. Это отлично
работает на практике в реальной жизни серверов, потому что они не
рестартуют часто. Но это дает плохие результаты при измерениях
скорости, которые могут продолжаться всего лишь 10 минут.
Правило "один-в-секунду" было внедрено, как попытка избежать
торможения машины, связанное с созданием новых потомков. Если машина
занята созданием потомков, она не может отвечать на запросы. Но это
имело такой глубокий эффект, связанный с ощущаемой
производительностью, что он должен был быть заменен. Начиная с Apache
1.3, код ослабляет правило "один-в-секунду". Он создает 1, ждет
секунду, затем создает 2, ждет секунду, затем создает 4 и продолжает
экспоненциально, пока не достигнет 32 потомков в секунду. Он
прекращает их создавать, если достигнет параметра MinSpareServers.
Кажется, что это довольно отзывчиво к нагрузке и почти нет
необходимости в регулировке параметров MinSpareServers,
MaxSpareServers и StartServers. Когда создается больше, чем 4 потомка
в секунду, в ErrorLog будет помещено сообщение. Если вы видите много
таких ошибок, подумайте над изменением этих параметров. В качестве
руководства к действию используйте вывод mod_status.
В частности, возможно, вам необходимо увеличить MinSpareServers, если
трафик на вашем сайте сильно пульсирует - это значит, что количество
соединений к вашему сайту радикально меняется за короткий промежуток
времени. Это может быть в случае, к примеру, если трафик к вашему
сайту сильно зависит от событий, таких как крупные спортивные события
или другие сайты могут стимулировать пользователей посетить ваш сайт
(скорей всего автор имеет ввиду рекламу на сайтах - прим. пер.).
Еще есть относящийся к процессу создания процесс смерти, связанный с
параметром MaxRequestsPerChild. По умолчанию он равен 0, что значит,
что нет ограничений на количество обслуженных клиентов потомком. Если
в вашей конфигурации установлен этот параметр на очень низкую
величину, к примеру 30, вы, возможно, захотите значительно увеличить
его. Если у вас машина работает под SunOS или старой версией Solaris,
ограничьте его в 10000 или около того, из-за утечек памяти.
Когда используются keep-alive соединения, потомки будут заняты, при
этом ничего не выполняя, лишь ожидая еще запросов по уже открытому
соединению. Значение по умолчанию KeepAliveTimeout равное 15 секунд
пытается уменьшить этот эффект. Это компромисс между полосой
пропускания сети и ресурсами сервера. Ни в коем случае вы не должны
увеличивать его выше 60 секунд, так как большинство преимуществ
будет потеряно (http://www.research.compaq.com/wrl/techreports/abstracts/95.4.html).
Модули
Так как использование памяти также является важным положением в
производительности, вы должны попытаться исключить модули, которые вы
реально не используете. Если вы построили модули как DSO,
исключить модули можно простым комментированием строчек с директивами
AddModule и LoadModule, ассоциированными для этих модулей. Это
позволит вам экспериментировать с удалением модулей и видеть, что ваш
сайт еще функционирует в их отсутствие.
Если, с другой стороны, у вас есть модули, статически связанные в
бинарник Apache, вам нужно перекомпилировать Apache для исключения
ненужных модулей.
Здесь сразу возникает ассоциированный вопрос, какие модули вам реально
нужны, а какие нет. Здесь ответ, конечно, может отличаться от одного
сайта к другому. Однако минимальный список модулей, которые вы должны
включить это mod_mime, mod_dir и mod_log_config.
mod_log_config является, конечно, опциональным, так как вы можете
запустить веб-сайт без лог файлов. Однако это не рекомендуется.
mod_mmap_static
Apache поставляется с этим модулем, mod_mmap_static, который не
включен по умолчанию. Он позволяет отображать файлы в RAM и отдавать
их прямо из памяти, вместо отдачи с диска, что должно привести к
значительному увеличению производительности при отдаче часто
запрашиваемых файлов. Замечу, что когда файлы изменяются, вам нужно
рестартовать сервер, чтобы сервер отдавал последние версии файлов,
поэтому это неудобно для файлов, которые часто изменяются. См.
документацию на этот модуль для более полной информации.
Вопросы компилирования
mod_status и ExtendedStatus On
Если вы включите mod_status и также установите ExtendedStatus On,
тогда на каждый запрос Apache будет выполнять два вызова
gettimeofday(2) (или times(2), в зависимости от вашей ОС), и (pre-1.3)
несколько дополнительных вызовов time(2). Когда это все выполнено,
отчет по статусу содержит временные метки. Для наилучшего
быстродействия установите ExtendedStatus off (это сделано по
умолчанию).
mod_status возможно нужно сконфигурировать так, чтобы только несколько
пользователей имели к нему доступ, вместо открытия его для всех, но
это имеет очень малое значение на общую производительность.
DYNAMIC_MODULE_LIMIT
Если у вас нет намерения использовать динамически подгружаемые модули
(его скорей всего не будет, если вы читаете этот документ и
оптимизируете ваш сервер до последней унции производительности) тогда
вам нужно добавить -DDYNAMIC_MODULE_LIMIT=0 при компиляции вашего
сервера. Это сохранит RAM, которая выделенна только для поддержки
динамически подгружаемых модулей.
Приложение: Модель Пред-Ветвления
Apache (под Unix) является сервером с пред-ветвлением. Родительский
процесс отвечает только за ветвление процессов-потомков и не отвечает
ни на какие запросы и не обслуживает никакие сетевые соединения.
Реально обслуживают соединения процессы-потомки, они обслуживают
многочисленные соединения (по одному за раз), пока не умрут.
Родительский процесс создает новые или убивает старые потомки,
согласно изменениям нагрузки на сервер (он это делает наблюдая счетную
доску(scoreboard), который постоянно обновляют потомки.
Эта модель для серверов предлагает выносливость, которую другие модели
предложить не могут. В частности, код родителя очень просто и с
высокой степенью уверенности родитель будет выполнять свою работу без
ошибок. Потомки сложны и, когда вы добавляете код от третьей стороны
через модули, вы рискуете получить ошибки сегментации и другие виды
ошибок. Даже когда такой случай произойдет, он затронет только одно
соединение, а сервер будет продолжать обслуживание соединений.
Родитель быстро заменит умершего потомка.
Пред-ветвление также хорошо переносится между диалектами Unix.
Исторически это было важной целью для Apache и продолжает ей
оставаться и по сей день.
Модель пред-ветвления попадает под критику из-за различных аспектов,
связанных с производительностью. Частично это относится к издержкам на
ветвление процесса, издержкам на переключение контекста между
процессами и издержками памяти на поддержку множества процессов. Кроме
того, модель не предлагает множества благоприятных возможностей на
кэширование данных между запросами (такие как пул mmapp'ированных
файлов. Различные другие модели также существуют и исчерпывающий
анализ может быть найден в документах проекта JAWS
(http://www.cs.wustl.edu/~jxh/research/research.html). На практике
все эти затраты радикально различаются, в зависимости от операционной
системы.
Ядро Apache уже является многопоточной, и Apache версии 1.3 под NT
многопоточен. Были как минимум два других экспериментальных варианта
поточности Apache, первый использовал код 1.3 на DCE, а второй
использовал пакет потоков пользовательского уровня и код 1.0; ни тот
ни другой публично не доступны. Существует также экспериментальный
порт Apache 1.3 на Netscape's Portable Run Time
(http://www.mozilla.org/docs/refList/refNSPR/), который
доступен http://arctic.org/~dean/apache/2.0/ (но вам желательно
присоединиться к рассылке (http://httpd.apache.org/lists.html)
new-httpd если хотите его использовать). Часть нашей реструктуризации
для версии Apache 2.0 включает абстракции серверной модели, поэтому мы
можем продолжать поддерживать модель пред-ветвления, при этом
поддерживая различные другие поточные модели.
Автор: Dean Gaudet
Перевод: Александр Кубышкин
Дата перевода: 12 марта 2005
URL оригинала: http://httpd.apache.org/docs/misc/perf-tuning.html