Чеклист по оптимизации VPS на PHP/Mysql/Nginx

Как обеспечить более высокую производительность VPS сервера, который работает на Nginx + PHP + Mysql? В этой статье приведен чеклист основных настроек, которые позволят существенно оптимизировать работу сервера. Настройка займет не более 10 минут и не требует ничего, кроме редактирования конфигурационных файлов.

Примеры настроек приведены для операционной системы Debian 7 и VPS сервера с 1 процессором и 512Мб оперативной памяти.

Nginx


Настройки выполняются в файле /etc/nginx/nginx.conf, а также в настройках виртуального хоста (обычно в папке /etc/nginx/sites-enabled)

Количество воркеров

Количество воркеров nginx'a должно совпадать с количеством ядер:

worker_processes  1;


Cache-Control заголовки

Установка заголовков Cache-Control позволит существенно разгрузить Ваш сервер от повторных обращений к файлам которые не изменяются (или изменяются редко, например css/js/jpg/png/gif):

location ~* \.(css|js|png|gif|jpg)$ {
    expires max;
}


Access log

Лишние дисковые операции из-за записи логов нам не нужны, отключаем:

access_log off;


Unix socket'ы

Включаем unix-сокеты для работы с PHP:

location ~ \.php$ {
	fastcgi_split_path_info ^(.+\.php)(/.+)$;
	fastcgi_pass unix:/var/run/php5-fpm.sock; # также необходимо настроить php-fpm, см. ниже
	fastcgi_index index.php;
	include fastcgi_params;
}


PHP


Настройки выполняются в файле конфигурации fpm php-fpm.conf, который в нашем случае находится тут /etc/php5/fpm/pool.d/www.conf.

Unix socket'ы

Убеждаемся, что php-fpm работает с unix-сокетами, а не с tcp:

listen = /var/run/php5-fpm.sock


APC

Устанавливаем расширение APC — внутренний кеш PHP, который позволит существенно сэкономить ресурсы парсеру PHP:

apt-get install php-apc


Настройка MySQL


Все настройки MySQL выполняются в файле my.cnf, который обычно находится тут /etc/my.cnf.

key_buffer

Если Вы используете только MyISAM таблицы, устанавливайте это значение в 30%...40% всей доступной оперативной памяти на сервере:

key_buffer = 128M


innodb_buffer_pool_size

Если Вы используете только InnoDB таблицы, устанавливайте это значение максимально возможным (80% доступной памяти). В нашем случае устанавливаем:

innodb_buffer_pool_size = 350M


Внимание, устанавливать такое знание можно только значительно уменьшив '''key_buffer'''. Т.е. между этими двумя настройками нужно сделать выбор, который зависит от типа используемых таблиц (MyISAM либо InnoDB).

innodb_flush_log_at_trx_commit

Значительного ускорение записи для таблиц innoDB можно добиться установкой этого параметра в 0, когда буфер записи будет сбрасываться на диск не после каждой операции, а раз в секунду:

innodb_flush_log_at_trx_commit = 0


innodb_flush_method

Установка этой опции в O_DIRECT позволяет избежать двойного кеширования (она выключает операционный кеш для файлов данных MySQL):

innodb_flush_method = O_DIRECT


thread_cache_size

Эта опция определяет размер кеша для созданных тредов. Подбирается экспериментально, но лучше стартовое знание увеличить до 16:

thread_cache_size = 16


query_cache_size

Включаем внутренний кеш MySQL:

query_cache_size = 16М


Значение стоит увеличивать по мере необходимости. Не стоит забывать, что кеш перестает работать эффективно на таблицах, которые часто обновляются.

Резюме


В качестве резюме — краткий список с выделенными наиболее важными настройками:

  • Nginx
    • worker_processes
    • expires max для статики
    • access_log off
    • unix-сокеты

  • PHP
    • APC модуль

  • MySQL
    • key_buffer
    • innodb_buffer_pool_size
    • innodb_flush_log_at_trx_commit = 0
    • query_cache_size
    • innodb_flush_method = O_DIRECT
    • thread_cache_size



Источники


Приведенные статьи содержат более подробное описание данных настроек, а также дополнительные методы оптимизации серверной части.

Share post

Comments 21

    0
    А вообще начать стоит с этого habrahabr.ru/post/53236/
      +1
      worker_processes 1;


      Спорно. Количество воркеров должно соответствовать количеству жестких дисков, с которых береться статика. Т.к. тут важно не количество процессоров, а количество возможных потоков блокирующих операций.
        +2
        nginx.org советует отталкиваться от числа процессорных ядер.
        Но да, все тюнится уже потом в зависимости от других факторов.
          0
          Посмотрел официальную документацию, на самом деле даже так:
          The optimal value depends on many factors including (but not limited to) the number of CPU cores, the number of hard disk drives that store data, and load pattern. When one is in doubt, setting it to the number of available CPU cores would be a good start (the value “auto” will try to autodetect it).

          Спасибо за замечание.
            0
            а в nginx используются блокирующие обращения к OS?
              0
              Конечно, если других нет.
            +3
            innodb_flush_log_at_trx_commit =0

            Плохой совет.

            habrahabr.ru/post/66684/
            innodb_flush_log_at_trx_commit — жалуетесь, что InnoDB работает в 100 раз медленнее MyISAM? Вероятно, Вы забыли про настройку innodb_flush_log_at_trx_commit. Значение по умолчанию «1» означает, что каждая UPDATE-транзакция (или аналогичная команда вне транзакции) должна сбрасывать буфер на диск, что достаточно ресурсоёмко. Большинство приложений, в особенности ранее использовавшие таблицы MyISAM, будут хорошо работать со значением «2» (т.е. «не сбрасывать буфер на диск, только в кэш ОС»). Лог, однако, всё равно будет сбрасываться на диск каждые 1-2 секунды, поэтому в случае аварии Вы потеряете максимум 1-2 секунды обновлений. Значение «0» повысит производительность, но Вы рискуете потерять данные даже при аварийной остановке mySQL-сервера, в то время как при установке значение innodb_flush_log_at_trx_commit в «2» Вы потеряете данные только при аварии всей операционной системы.

              0
              Согласен — совет плохой. Как-то проводил экстремальное тестирование PostgreSQL (с жестким отключением тестируемой машины) с установкой аналогичного параметра — при таких значениях там все кончалось плохо. И мастер-сервер и слэйв (была настроена репликация) падали так что не смогли подняться. Так что с этим лучше не шутить.
              +14
              В этом месяце еще не было.
                0
                На своем опыте получилось так что от unix-socket пришлось отказаться в пользу tcp, только тогда ушла ошибка ( connection refused by peer), и мало того стал быстрее работать, так что спорный вопрос какой то
                  +2
                  Возможно стоило просто увеличить /proc/sys/net/core/somaxconn
                  0
                  Тоже имхо неплохой чеклист
                    0
                    access_log off;
                    Насколько это важно для увеличения производительности?
                      0
                      При большом потоке трафика, в случае когда логи пишутся на локальный диск, то запись access_log'а дает некоторую нагрузку на дисковую подсистему. Для этого и отключают.

                      Для случаев когда логирование таки нужно оставить используют разные фокусы, типа buffer= для nginx, «отключение» fsync для rsyslog и т.п.
                        0
                        Важность растет с ростом количества запросов, но существенно отражаться начнет с сотен запросов в секунду.
                        0
                        expires max;
                        Мина замедленного действия. Сработает, когда надо будет обновить сайт. Применять можно только совместно с методикой включения версии файла в uri.
                          0
                          Да, обычно делают что-то типа:
                          /filename-version.css
                          либо
                          /filename.css?version

                          Вроде второй случай не очень хорошо в некоторых браузерах работает.
                            0
                            Вряд ли. Второй случай — это настолько древний трюк, что он даже «тайно» вошел в jquery (кто сходу может вспомнить, что делает именованный параметр cache в функции ajax)? Первый же вариант мне не нравится, поскольку дефис часто используется и в исходных названиях файлов.

                            Но такой трюк с версией — это всего лишь полдела. Главное — проставлять эту версию хотя бы полуавтоматически, а лучше — полностью автоматически. Иначе легко получить ситуацию, когда у программистов все работает — а у посетителей сайта — нет, причем программисты об этом не знают.
                              0
                              /filename.css?version не будет кэшироваться.

                                0
                                Даже при явном указании возможности кэширования в заголовках?
                                  0
                                  Ходят слухи, что Chrome иногда игнорирует то, что находится после знака вопроса при установленом Cache-Control. Проверю.

                            Only users with full accounts can post comments. Log in, please.