Linux, Apache, MySQL и PHP (или Perl) являются основой многих Web-приложений, от текущих задач до блогов на сайтах электронной торговли. WordPress и Pligg -- вот только два распространенных пакета программ, приводящих в действие крупномасштабные Web-сайты. Эта архитектура приобрела известность просто как LAMP. Apache, MySQL, PHP и Perl включаются почти во все дистрибутивы Linux, поэтому установить программное обеспечение LAMP почти также просто, как сказать об этом.
Эта легкость установки создает впечатление, что программное обеспечение работает само, что конечно не так. В конечном счете нагрузка на приложение перерастает параметры, связанные с back-end серверами, и страдает производительность приложения. Инсталляции LAMP требуют постоянного мониторинга, настройки и анализа.
Настройка системы для разных людей имеет разное значение. Эта серия статей сфокусирована на настройке компонентов LAMP -- Linux, Apache, MySQL и PHP. Настройка самих приложений -- еще одна непростая задача. Между приложениями и back-end серверами существует симбиотическая связь: плохо настроенный сервер заставляет рушиться под нагрузкой даже хорошее приложение, и только тщательная настройка сервера может предотвратить замедление его работы из-за плохо написанного приложения. К счастью правильная настройка и мониторинг системы могут указать на проблемы приложения.
Первый шаг в настройке любой системы -- понимание того, как система работает. В простейшем случае приложения на базе LAMP написаны на скриптовом языке, например PHP, который работает как часть Web-сервера Apache, запущенного на Linux-хосте.
Для того чтобы определить дальнейшие действия, приложения PHP получают информацию от клиента через запрашиваемый URL, из любых данных формы, независимо от того, какая информация о сессии была получена. Если необходимо, сервер извлекает информацию из базы данных MySQL (также работающей под Linux), комбинирует информацию с какими-то шаблонами HTML (Hypertext Markup Language) и возвращает результат клиенту. Этот процесс повторяется, поскольку пользователь работает с приложением, а также выполняется параллельно, поскольку множество пользователей получает доступ к системе. Однако поток данных не является односторонним, потому что база данных может быть обновлена информацией, полученной от пользователя в форме данных сеанса, статистической подборкой (включая голосование) и содержимым, предоставленным пользователю, например, комментарии или обновление сайта. Вдобавок к динамическим элементам существуют также статические элементы, такие как изображения, коды JavaScript и CSS (Cascading Style Sheets).
Посмотрев на поток запросов через систему LAMP, вы можете увидеть места, где могут произойти замедления. База данных предоставляет большое количество динамической информации, так что клиент замечает любую задержку реакции на запрос. Web-сервер должен быть доступен для быстрого выполнения скриптов, а также управления множеством конкурирующих запросов. Наконец, для поддержки приложений базовая операционная система должна быть в добром здравии. Другие настройки, распределяющие файлы между различными серверами по сети, также могут являться узким местом.
Постоянное измерение производительности помогает в двух случаях. Первое -- измерение помогает выявлять тенденции, как хорошие, так и плохие. Вот простой пример: наблюдая за использованием центрального процессора (CPU) на Web-сервере, вы можете заметить его чрезмерную загрузку. Подобным образом, наблюдение за использованием общей пропускной способности в прошлом и экстраполяция на будущее помогает выявлять моменты, когда необходимо обновление сети. Эти измерения взаимосвязаны с другими измерениями и наблюдениями. Например, вы можете решить, что когда пользователи жалуются на медленную работу приложений, диски работают с максимальной нагрузкой.
Другое применение измерений производительности -- определение, помогла ли настройка решению ситуации или ухудшила положение. Вы делаете это, сравнивая результаты измерений до и после произведенных изменений. Однако, чтобы это принесло результат, для определения эффекта от изменений одновременно должен меняться только один критерий, и должны сравниваться соответствующие показатели. Причина одновременного изменения только одного компонента должна быть очевидна. Ведь вполне возможно, что два одновременно произведенных изменения могли нейтрализовать друг друга. Причина для выбора измерений является гораздо более тонкой.
Решающим является то, что измерения, которые вы выбираете для исследования, должны отражать интенсивность использования приложения. Если цель изменения состоит в уменьшении объема памяти, используемой базой данных, устранение различных буферов, конечно, поможет за счет скорости запроса и производительности приложения. Взамен одно из измерений должно быть временем отклика приложения, что позволит обнаружить возможности настройки других показателей, не только использования памяти базой данных.
Вы можете измерить время отклика приложения разными способами. Возможно, самый простой способ -- использовать команду curl, как показано в Листинге 1.
Листинг 1. Использование curl для измерения времени отклика Web-сайта
$ curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total}\
http://www.canada.com
0.081:0.272:0.779
|
В Листинге 1 показана команда curl, используемая для поиска популярных новостных сайтов. Вывод, который обычно был бы HTML-кодом, направлен при помощи опции -o в /dev/null, а также использована опция -s, отключающая вывод информации о ходе процесса. Опция -w дает указание вывести некоторые данные о ходе процесса, например, показанные в Таблице 1 таймеры:
Таблица 1. Таймеры, используемые
curl
| Таймер | Описание |
|---|---|
| time_connect | Время, необходимое для установки TCP-соединения с сервером |
| time_starttransfer | Время, необходимое Web-серверу для возврата первого байта после того как произведен запрос |
| time_total | Время, необходимое для полного выполнения запроса |
Все эти таймеры ведут отсчет от старта транзакции, даже перед обращением к Domain Name Service (DNS). Таким образом, после того как был сделан запрос, требуется 0.272 - 0.081 = 0.191 секунды, чтобы Web-сервер обработал запрос и начал возвращать данные. Клиент затратил 0.779 - 0.272 = 0.507 секунды, загружая данные с сервера.
Наблюдение за данными curl и временной тренд позволят вам получить представление, насколько быстро реагирует сайт на запросы пользователей.
Конечно, Web-сайт -- больше чем просто отдельная страница. Он содержит изображения, код JavaScript, CSS и cookies. Команда curl способна получать время отклика для одного элемента, но иногда вам необходимо видеть, как быстро загружается целая страница.
Tamper Data, расширение браузера Firefox (ссылку см. в разделе Ресурсы), регистрирует все запросы, сделанные Web-браузером, и показывает время, затраченное на загрузку каждого запроса. Чтобы использовать расширение, выберите Tools > Tamper Data, откроется окно Ongoing requests. Загрузите страницу, о которой идет речь, и вы увидите статус каждого запроса, сделанного браузером, а также время, затраченное на загрузку элемента. На Рисунке 1 показан результат загрузки домашней страницы developerWorks.
Рисунок 1. Схема организации запросов для загрузки домашней страницы developerWorks
Каждая строка описывает загрузку одного элемента. Показаны разнообразные данные, например, время отправки запроса, как долго он загружается, размер и результаты. Колонка Duration (Продолжительность) показывает время, которое требуется на загрузку элемента, в то время как колонка Total Duration (Общая продолжительность) показывает, сколько времени занимает загрузка всех суб-элементов. На Рисунке 1 видно, что на загрузку главной страницы затрачено 516 миллисекунд (мсек), но потребовалось 5101 мсек, прежде чем все было загружено, и могла быть показана вся страница.
Другой полезный вариант использования расширения Tamper Data -- изображение данных о загрузке страницы в виде графика. Щелкните правой кнопкой в верхней части окна Ongoing requests и выберите Graph all. На Рисунке 2 показано графическое изображение данных из Рисунка 1.
Рисунок 2. Графическое изображение запросов для загрузки домашней страницы developerWorks
На Рисунке 2 продолжительность каждого запроса показана темно-синим цветом и показывается относительно начала загрузки страницы. Таким образом, вы можете видеть, какие запросы замедляют загрузку всей страницы.
Несмотря на то, что внимание сосредоточено на времени загрузки страницы и опыте пользователя, важно не упускать из виду основные показатели системы, такие как диск, память, CPU и сеть. Для получения этой информации имеется множество утилит; возможно, наиболее полезные из них -- sar, vmstat и
iostat. Для получения более подробной информации об этих утилитах обратитесь к разделу Ресурсы.
Прежде чем вы настроите компоненты системы Apache, PHP и MySQL, вы должны потратить некоторое время на то, чтобы убедиться, что основные компоненты Linux функционируют правильно. Разумеется, вы уже отобрали из списка запущенных сервисов только те, которые вам необходимы. Помимо того, что это является хорошей практикой обеспечения безопасности, это экономит память и циклы CPU.
Большинство дистрибутивов Linux поставляется с традиционно определенными параметрами для буферов и других характеристик TCP (Transmission Control Protocol). Вы должны изменить эти параметры, чтобы выделить больше памяти для повышения производительности сети. Параметры ядра установлены через интерфейс proc путем чтения и записи переменных в /proc. К счастью программа sysctl управляет ими немного более легким образом, читая переменные из /etc/sysctl.conf и занося их при необходимости в /proc. В Листинге 2 показаны некоторые наиболее радикальные сетевые настройки, которые должны применяться на Интернет-серверах.
Листинг 2. Демонстрация наиболее радикальных сетевых настроек в /etc/sysctl.conf
# Использовать, когда необходимо, TCP syncookies
net.ipv4.tcp_syncookies = 1
# Разрешить масштабирование окна TCP
net.ipv4.tcp_window_scaling: = 1
# Увеличить максимальный размер буфера TCP
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Увеличить максимальное значение самонастраиваемого буфера TCP в Linux
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Увеличить количество доступных портов
net.ipv4.ip_local_port_range = 1024 65000
|
Добавьте эти настройки к тому, что уже имеется в файле /etc/sysctl.conf. Эта первая настройка разрешит TCP SYN cookies. Когда клиент устанавливает новое TCP-соединение при помощи пакета с установленным битом SYN, сервер создает запись для наполовину открытого соединения и отвечает пакетом SYN-ACK. При нормальной работе удаленный клиент отвечает пакетом ACK, что меняет соединение с наполовину открытого на полностью открытое. Атака, называемая SYN flood, гарантирует, что пакет ACK никогда не будет возвращен из-за того, что процесс сервера исчерпал доступную память для входящих соединений. Функция SYN cookie учитывает это обстоятельство и начинает использовать изящный метод, сохраняющий место в очереди (более подробно см. в разделе Ресурсы). В большинстве систем эта возможность разрешена по умолчанию, но стоит удостовериться, что она сконфигурирована.
Возможность масштабирования окна TCP позволяет клиентам загружать данные с высокой скоростью. TCP позволяет отправку удаленной стороной без подтверждения многочисленных пакетов, по умолчанию до 64 килобайт (Кбайт), которые могут быть заполнены при информационном обмене с более высокой степенью задержки. Масштабирование окна позволяет использовать в заголовке некоторые дополнительные биты, чтобы увеличить размер этого окна.
Следующие четыре элемента конфигурации увеличивают буферы TCP для отправки и приема. Это позволяет приложениям быстрее избавиться от их информации, так что они могут обслужить другой запрос, и это также повышает возможность удаленного клиента отправлять данные, когда сервер занят.
Последний элемент конфигурации увеличивает количество разрешенных для использования локальных портов, что увеличивает максимальное количество соединений, которые могут быть обслужены одновременно.
Эти настройки вступят в силу при следующей загрузке или при следующем запуске sysctl -p /etc/sysctl.conf.
Конфигурирование дисков для достижения максимальной производительности
В архитектуре LAMP диски играют существенную роль. Статические файлы, шаблоны и коды обслуживаются диском, как таблицы данных и индексы, составляющие базу данных. Большинство настроек, особенно те, которые имеют отношение у базе данных, сфокусированы на том, чтобы обойтись без доступа к диску, поскольку это влечет относительно высокую задержку. Поэтому имеет смысл затратить некоторое время на оптимизацию дисковой подсистемы.
Первым делом необходимо убедиться, что журналирование atime в файловых системах отключено. atime -- время последнего доступа к файлу, и при каждом обращении к файлу основная файловая система должна записывать эту отметку времени. Поскольку atime редко используется системными администраторами, ее отключение снизит нагрузку на диск. Это достигается путем добавления опции noatime в четвертой колонке файла /etc/fstab. В Листинге 3 показан пример конфигурации.
Листинг 3. Образец файла fstab, показывающий, как разрешить
noatime
/dev/VolGroup00/LogVol00 / ext3 defaults,noatime 1 1
LABEL=/boot /boot ext3 defaults,noatime 1 2
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
LABEL=SWAP-hdb2 swap swap defaults 0 0
LABEL=SWAP-hda3 swap swap defaults 0 0
|
В Листинге 3 изменения сделаны только для файловых систем типа ext3, поскольку опция noatime полезна только для файловых систем, расположенных на диске. Чтобы изменения вступили в силу, перезагрузка не нужна; вам только необходимо вновь подмонтировать каждую файловую систему, выполнив
mount / -o remount.
Возможны разнообразные комбинации жестких дисков, и Linux не всегда верно определяет оптимальный метод доступа к жесткому диску. Команда hdparm используется для получения и установки методов, используемых для доступа к дискам IDE (integrated development environment, интегрированная среда разработки). hdparm -t /path/to/device выполняет тест скорости, который вы можете использовать в качестве точки отсчета. Для получения более достоверных результатов при запуске этой команды система должна быть незанята. В Листинге 4 показан тест скорости, выполняемый на hda.
Листинг 4. Тест скорости, выполняемый на
/dev/hda
# hdparm -t /dev/hda
/dev/hda:
Timing buffered disk reads: 182 MB in 3.02 seconds = 60.31 MB/sec
|
Как видно из теста, диски читают данные со скоростью около 60 мегабайт (Мбайт) в секунду.
Прежде чем углубиться в изучение некоторых опций настройки диска, необходимо сделать предостережение. Неправильная настройка может разрушить файловую систему. Иногда вы получаете предупреждение, что выбор несовместим с вашим оборудованием; иногда нет. Поэтому тщательно проверяйте настройки, прежде чем запустить систему. Здесь также поможет наличие стандартного оборудования на всех ваших серверах.
В Таблице 2 перечислены некоторые часто используемые опции.
Таблицы 2. Часто используемые опции
hdparm
| Опция | Описание |
|---|---|
| -vi | Опрашивает устройство с целью определения, какие настройки оно поддерживает и какие использует. |
| -c | Запрос/включение поддержки 32-битного (E)IDE ввода/вывода.
hdparm -c 1 /dev/hda включает. |
| -m | Запрос/установка нескольких секторов в режиме прерывания. Если значение параметра больше нуля, повышение до такого количества секторов может быть передано через прерывание. |
| -d 1 -X | Включение передач DMA (direct memory access, прямой доступ к памяти) и установка режима передачи IDE. Страница справки man команды hdparm уточняет число, которое может стоять после -X. Вы должны использовать эту опцию, только если -vi показывает, что вы не используете самый быстрый режим. |
К сожалению для систем Fiber Channel и Small Computer Systems Interface (SCSI) настройка зависит от конкретного устройства.
Вы должны добавить в ваш стартовый скрипт, например, rc.local, те настройки, которые считаете полезными.
NFS (network file system, сетевая файловая система) -- способ предоставления доступа к томам диска по сети. Использовать NFS полезно, чтобы гарантировать, что каждый хост имеет одну и ту же копию данных и что изменения отражены на всех узлах. Тем не менее по умолчанию NFS не сконфигурирована для массового использования.
Каждый клиент должен подмонтировать удаленную файловую систему при помощи
rsize=32768,wsize=32768,intr,noatime, чтобы гарантировать следующее:
- Используются большие размеры блоков чтения/записи (до определенного размера, в данном случае 32Кбайт).
- Операции NFS могут быть прерваны в случае зависания.
-
atimeне будет постоянно обновляться.
Вы можете поместить эти настройки в файл /etc/fstab, как показано в
Листинге 3. Если вы используете автомонтирование, они входят в соответствующий файл /etc/auto.*.
На стороне сервера важно удостовериться, что имеется достаточное количество NFS kernel thread'ов, доступных для обслуживания всех клиентов. По умолчанию запущен только один thread, хотя системы Red Hat и Fedora запускают 8. Для сильно загруженного сервера NFS вы должны повысить это число, например, до 32 или 64. Вы можете отследить, была ли блокировка, при помощи команды nfsstat -rc, показывающей статистические данные Remote Procedure Call (RPC) клиента. В Листинге 5 показаны статистические данные клиента для Web-сервера.
Листинг 5. Демонстрация статистических данных RPC при использовании NFS-клиента
# nfsstat -rc
Client rpc stats:
calls retrans authrefrsh
1465903813 0 0
|
Во второй колонке, retrans, стоит ноль, что показывает, что, начиная с последней перезагрузки, не было необходимости ни в каких передачах. Если это число растет, вы должны подумать о добавлении большего количества NFS kernel thread'ов. Это делается путем передачи желаемого числа thread'ов rpc.nfsd, например, rpc.nfsd 128 запускает 128 thread'ов. Вы можете сделать это в любое время. Thread'ы запускаются или уничтожаются по мере необходимости. Кроме того, это должно войти в ваши стартовые скрипты, предпочтительно в скрипт, который стартует NFS на вашей системе.
Последнее замечание относительно NFS: если возможно, откажитесь от NFS версии 2, поскольку его производительность намного ниже производительности NFS версий 3 и 4. В современных дистрибутивах Linux это не является проблемой, но проверьте вывод nfsstat на сервере, чтобы узнать, делаются ли какие-либо запросы через NFS версии 2.
Эта статья охватила некоторые основы LAMP и рассмотрела некоторые простые настройки Linux для установок LAMP. Вы можете установить все параметры, описанные в этой статье, за исключением NFS kernel thread'ов, и затем не обращать на них внимания. Следующие две статьи из этой серии сфокусированы на настройке Apache, MySQL и PHP. Их настройка значительно отличается от настройки Linux, поскольку вам необходимо постоянно заново пересматривать такие параметры, как увеличение объема трафика, изменение распределений при чтении/записи и следить за эволюцией самого приложения.
Научиться
-
Tuning LAMP systems, Part 1: Understanding the LAMP architecture -- оригинал этой статьи на developerWorks.
- "Простой мониторинг системы при помощи SAR (Easy system monitoring with SAR)" (developerWorks, февраль 2006) -- руководство по отслеживанию основных показателей системы с использованием
sar. - "Выявление проблем, связанных с производительностью Web, при помощи RRDtool (Expose Web performance problems with the RRDtool)" (developerWorks, март 2006) -- учебное пособие, написанное Шоном, которое подробно излагает технологию cURL и представляет в виде графика данные долгосрочного анализа.
- Из статьи Мониторинг виртуальной памяти при помощи vmstat (Monitoring Virtual Memory with
vmstat) (Linux Journal, октябрь 2005) вы узнаете, как отслеживать активность пейджинга на вашей системе Linux.
- Если вы не знакомы с NFS, статья Хранить и защищать: предоставление информации для кластера (To Protect and Serve: Providing Data to Your Cluster) (Prentice Hall Professional Technical Reference, февраль 2005) -- хорошее введение в
NFS и автомонтирование, которая поможет при развертываниях крупномасштабных NFS-сервисов.
- В статье "TCP и алгоритмы Linux для Pluggable Congestion Control (TCP and
Linux' Pluggable Congestion Control Algorithms)" (Linux Gazette, февраль 2007) обсуждается, как испробовать множество поддерживаемых Linux алгоритмов для осуществления контроля перегрузок, и, что более важно, значение и воздействие потерь и задержек в ваших сетевых сессиях.
- TCP SYN cookies,
как отмечалось ранее, защищают от атак отказа в обслуживании (DOS, denial of service) через SYN floods. В Wikipedia описана их реализация. Это блестящая идея.
- В Linux-разделе developerWorks найдите дополнительные ресурсы для Linux-разработчиков.
- Регулярно посещайте раздел
технических мероприятий и Web-трансляций developerWorks.
Получить продукты и технологии
-
Tamper Data -- расширение для Firefox, позволяющее на лету просматривать и модифицировать заголовки HTTP и показывать загрузку элементов страницы в виде графика.
-
Закажите инструментарий SEK для Linux,
комплект из двух DVD, содержащий новейшие пробные версии программного обеспечения IBM DB2®,
Lotus®, Rational®, Tivoli® и WebSphere® для Linux.
- Постройте ваш следующий проект разработки в Linux при помощи
ознакомительных версий ПО IBM,
доступных для загрузки непосредственно с сайта developerWorks.
Обсудить
- Примите участие в обсуждении материала на форуме.
- Читайте
блоги developerWorks и принимайте участие в жизни
сообщества developerWorks.
В академической, корпоративной средах, среде поставщиков интернет-услуг Шон Волберг (Sean Walberg) работает с системами Linux и UNIX с 1994 года. За последнюю пару лет он очень много написал о системном администрировании. Вы можете написать ему на sean@ertw.com.