Оптимізуємо VPS за 5$ (512MB RAM / 1 CPU) так, що сайт на wordpress витримує навантаження в 42,735,587 хітів в день

Коли ви купуєте сервер VPS з 256MB або 512MB оперативної пам'яті на борту і лише частина потужності процесора, то використовувати для таких сервісів як MySQL/PHP/Apache налаштування за замовчуванням є дуже поганою ідеєю. В даний час у мене запущено 3 сайту на найдешевшому тарифному плані з 512MB RAM/1 CPU. Не впевнений повністю, але відвідуваність складає близько 5-10 тисяч відвідувачів в день. Далі я хочу поділитися інструкцією як оптимізувати LAMP використовуючи всього лише 512 MB і при цьому не йдучи в swap. Зазвичай при такій налаштування використовується 256 — 378Mb пам'яті і все працює досить швидко.

Визначаємо доступну пам'ять і активність swap.
Перед початком оптимізації давайте поглянемо на кількість використовуваної пам'яті. Для цього необхідно виконати наступну команду:

$ free-m

Для того. щоб подивитися список запущених процесів і відсортувати їх по використанню пам'яті, необхідно виконати таку команду:

$ ps-eo pmem,pcpu,rss,vsize,args | sort-k 1-r | less


Налаштовуємо LAMP сервер для споживання невеликої кількості оперативної пам'яті. Зупиняємо, відключаємо непотрібні сервіси
Перший і очевидний питання, яке необхідно задати — це «які сервіси мені не потрібні у використанні?». Нещодавно, я виявив дуже зручну утиліту для управління сервісами. Вона називається "sysv-rc-conf" і управляє сервісами за допомогою псевдографіки та прапорцями. Выгдялит ось так:



Тут представлений список сервісів, які я змінив.
  • Postfix. Цей сервіс дозволяє відправляти і отримувати поштові email повідомлення для домену. Я використовую для цих цілей Google Apps для відправки пошти і mailchimp для новинних передплатників. Таким чином я зупинив і відключив цей сервіс.
  • Bind9. Він потрібен для керування записами DNS Вашого домену. Його можна відключити, так як всі DNS записи зберігаються у хостера.
  • SSHD. Є й інші, які використовують набагато менше пам'яті, але вони не підтримують sftp, тому даний сервіс я залишив без змін.


Не запускайте X-сервер, вимкніть всі непотрібні сервіси і налаштуйте Apache, MySQL, PHP тільки з базовою необхідною функціональністю.

Apache
Найбільша проблема Apache — це об'єм оперативної пам'яті, який він використовує. Я буду розглядати такі способи прискорення роботи і зниження споживання оперативної пам'яті:

  • Обробляти меншу кількість одночасних запитів;
  • Менша завантаження модулів(відключити невживані);
  • Менше журналювання.


Налаштувати Apache на використання тільки найменшого кількість запущених дочірніх процесів

Prefork — це десь трапляється справжня магія. Це те, де ми говоримо Apache генерувати багато процесів. За умовчанням виділяється велика кількість, що і призводить до споживання оперативної пам'яті сервера. Переконайтеся, що apache2.conf не налаштований для запуску занадто великої кількості серверів або має безліч запасних. Нижче приклад:


<IfModule mpm_prefork_module>
StartServers 1
MinSpareServers 1
MaxSpareServers 3
MaxClients 10
MaxRequestsPerChild 3000
</IfModule>

<IfModule mpm_worker_module>
StartServers 1
MinSpareThreads 5
MaxSpareThreads 15 
ThreadLimit 25
ThreadsPerChild 5
MaxClients 25
MaxRequestsPerChild 200
</IfModule>

Також обов'язково відрегулюйте параметр "KeepAliveTimeout", встановивши значення 10 або 15. На мій погляд, 15 секунд занадто багато, ніж маленької сторінці потрібно для перегляду і коротше, ніж потрібно для тривалого перегляду сторінки.

Завантажуйте тільки самі необхідні модулі
Налаштований за замовчуванням веб-сервер Apache довантажує занадто багато непотрібних модулів. Перевірити які модулі встановлені і включені можна такою командою:


# apache2ctl-M

Нижче представлений список модулів, які необхідні для роботи Wordpress.

LoadModule dir_module modules/mod_dir.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule alias_module modules/mod_alias.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule rewrite_module modules/mod_rewrite.so

Вам необхідно закоментувати інші модулі для економії пам'яті. Або ж ви можете включити/відключити модулі через командний рядок. Для включення скористайтеся командою:


# a2enmod module_name

Для відключення:


# a2dismod module_name

Після виконаних маніпуляцій вам необхідно обов'язково перезавантажити веб-сервер Apache:


# service apache2 restart

Зменшуємо журналювання
Якщо ви хочете добитися максимальної продуктивності, вам певною потрібно обмежити журналювання. На моєму сервері я встановив рівень «error» (помилок). Також, якщо вам не потрібна детальна статистика, ви можете відключити логування User-Agent або the http referer.


# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to virtual host that will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log

#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel error

Мене влаштовують такі налаштування, ну а ви самі вирішуйте.

Оптимізація MySQL сервера
Тонке налаштування MySQL для використання малої кількості оперативної пам'яті досить проста.
Далі ми будемо розглядати наступні типи налаштувань MySQL:

  • Речі, які ми можемо відключити;
  • Оптимізація параметрів MySQL сервера;
  • Сторонні інструменти налаштування конфігурації MySQL.


Для оптимізації MySQL нам необхідно відредагувати файл /etc/mysql/my.cnf.

Речі, які нам необхідно вимкнути
Mysql надає кілька движків зберігання таблиць. Два з них найбільш популярні — це InnoDB та MyISAM. Основні відмінності між ними:
  • MyISAM пропонує блокування на рівні таблиць, це означає, що коли інформація записується в таблицю, то вся таблиця блокується і якщо в цей момент будуть ще записи, які повинні виконається одночасно в ту ж таблицю, то вони повинні будуть почекати, поки перша запис додатися успішно;
  • InnoDB, з іншого боку пропонує блокування на рівні рядків, це означає, що коли відбувається запис у рядок, то тільки ця одинична рядок блокується; інші доступні для запису.


Проблеми блокувань табличного рівня помітні тільки на дуже навантажених серверах. Для звичайних веб-сайтів, MyISAM показує кращу продуктивність на дешевих серверах.

Якщо ви вирішили використовувати MyISAM таблиці, то вам необхідно додати наступні рядки в конфігураційний файл my.cnf:


default-storage-engine=MyISAM
default-tmp-storage-engine=MyISAM

Якщо у вас будуть тільки MyISAM таблиці, ви можете вимкнути InnoDB движок, тим самим заощадивши оперативну пам'ять, додавши лише один рядок у my.cnf:


skip-innodb

Якщо ви в минулому використовували InnoDB, то нижче я надаю вам скрипт, який автоматично переконверує всі таблиці InnoDB в MyISAM.


#!/bin/bash

MYSQLCMD=mysql

for in db `echo show databases | $MYSQLCMD | grep-v Database`; do
for table in `echo show tables | $MYSQLCMD $db | grep-v Tables_in_`; do
TABLE_TYPE=`echo show create table $table | $MYSQLCMD $db | sed-e's/.*ENGINE=\([[:alnum:]\]\+\)[[:space:]].*/\1/'|grep-v 'Create Table"
if [ $TABLE_TYPE = "InnoDB" ] ; then
mysqldump $db $table > $db.$table.sql
echo "ALTER TABLE $table ENGINE = MyISAM" | $MYSQLCMD $db
fi
done
done

Оптимізуємо параметри MySQL сервера
Нижче представлені кілька параметрів, які можуть бути відрегульовані з метою прискорення MySQL сервера.

Key buffer size
Це один з найважливіших параметрів, що впливає на споживання оперативної пам'яті і продуктивності, який необхідно оптимізувати. MySQL намагається класти все що проіндексовано у key buffer, тому цей параметр приносить величезну продуктивність. SQL-запит буде поданий безпосередньо з оперативної пам'яті RAM. Я не можу сказати, який розмір ви повинні встановити для key buffer, тому що тільки ви знаєте, скільки RAM є у вас вільною.

The Query Cache
Якщо ви робите однакові запити два рази підряд, то результат поміщається в кеш запитів, таким чином mysql не доведеться робити запит знову. Якщо ви збираєтеся підвищувати продуктивність, то цей параметр може принести величезну користь, але зросте споживання пам'яті. Тому вам необхідно встановити цей параметр не дуже величезним, але і не дуже маленьким, тобто стільки, скільки необхідно вашому веб-сайту.

Нижче наведено три змінні, які впливають на те, як працює ваш кеш запитів:


query_cache_size
query_cache_limit
query_cache_type


Maximum Number of Connections
Це опціональний параметр. Якщо ви вже обмежили кількість процесів apache, то все вже добре. Якщо немає і вам необхідно обробляти тисячі користувачів одночасно, необхідно збільшити значення цього параметра.

The table Cache
Кожен раз ви звертаєтеся до таблиці, MySQL довантажує посилання на таблицю як один запис у кеш таблиці. Це робиться для кожного паралельного доступу до таблиці, це дійсно важливо для продуктивності, незначно для використання пам'яті. Ви можете постійно збільшувати кеш таблиці, але тоді ли упретеся в ліміт на кількість відкритих файлів у вашій операційній системі, так що майте це на увазі. Якщо встановлено занадто маленький кеш таблиці mysql буде блювати на вас, ви ж не хочете цього.

Нижче наведено коректний my.cnf, який я оптимізував на моєму VPS з самим низьким тарифним планом.
Мій my.cnf

[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer = 16K
max_allowed_packet = 1M
table_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K

# For low memory, InnoDB should not be used so keep skip-innodb uncommented unless required
skip-innodb

# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = /var/lib/mysql/
#innodb_data_file_path = ibdata1:10M:autoextend
#innodb_log_group_home_dir = /var/lib/mysql/
#innodb_log_arch_dir = /var/lib/mysql/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
#innodb_buffer_pool_size = 16M
#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer size pool
#innodb_log_file_size = 5M
#innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit = 1
#innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[isamchk]
key_buffer = 8M
sort_buffer_size = 8M

[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M

[mysqlhotcopy]
interactive-timeout


Сторонні майстра налаштування MySQL
Я знайшов Percona, яка надає безкоштовну налаштування MySQL і допомагає вибрати найкращі можливості MySQL сервера для досягнення кращої продуктивності, а також заощадити час, уникнути складних моментів і ризиків, які можуть виникнути при самостійного налаштування my.cnf.

Моніторинг MySQL сервера
MySQL зберігає статистику, яка допомагає визначити найкращі значення для використання. Крім цього, є дві зручні утиліти, які можна використовувати для читання цієї статистики і виводити в зрозумілому форматі: tuning-primer.sh and mysqltuner.pl.
Ці скрипти дозволять моніторити ваш MySQL сервер, і після нададуть довідку про параметри, які необхідно налаштувати на вашому сервері.

Оптимізація PHP і кешування
PHP не дуже інтенсивно використовують пам'ять, тому я не думаю, що потрібно сильно турбується про споживання пам'яті цих процесів, якщо ваш додаток не потребує, але навіть в разі необхідності оптимізації, значно зменшення споживаної пам'яті не буде. Але я досліджував і потім знайшов кілька налаштувань для PHP конфігурації, які зменшують споживання пам'яті веб-сервером.


; Limit the memory to 40M should be fine for barebones Wordpress
memory_limit = 48M
realpath_cache_ttl=300
realpath_cache_size=1M

Alternative PHP Cache
Встановіть PHP Cache, наприклад, такий як, Alternative PHP Cache. PHP cache буде зберігати скомпільовані PHP скрипти таким чином, що вони будуть використані заново без компіляції, выдповыдно, не створять навантаження:


# pecl install apc

Нижче мій сконфігурований файл php.ini.
Мій php.ini

[APC]
extension=apc.so
apc.enabled=1
apc.shm_segments=1

;32M per WordPress install
apc.shm_size=128M

;Relative to the number of cached files (you may need to watch your stats for a day or two to find out a good year)
apc.num_files_hint=7000

;Relative to the size of WordPress
apc.user_entries_hint=4096

;The number of seconds a cache entry is allowed to idle in a slot before APC dumps the cache
apc.ttl=7200
apc.user_ttl=7200
apc.gc_ttl=3600

;Setting this to 0 will give you the best performance, as will APC
;not have to check the IO for changes. However, you must clear 
;the APC cache to recompile already cached files. If you are still
;developing, updating your site daily in WP-ADMIN and running W3TC
;set this to 1
apc.stat=1

;This MUST be 0, WP can have errors otherwise!
apc.include_once_override=0

;Only set to 1 while debugging
apc.enable_cli=0

;Allow 2 seconds after a file is created before it is cached to prevent users from seeing half-written/weird pages
apc.file_update_protection=2

;Leave at 2M or lower. WordPress does't have any file sizes close to 2M
apc.max_file_size=2M

;Ignore files
apc.filters = "/var/www/apc.php"

apc.cache_by_default=1
apc.use_request_time=1
apc.slam_defense=0
apc.mmap_file_mask=/var/www/temp/apc.XXXXXX
apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.lazy_classes=0
apc.lazy_functions=0


Static Cache
Інша річ, яка може бути гарною ідеєю для блогу на маленькому сервері — це поставити його перед статичним HTTP-cache, наприклад, Varnish. Що може реально збільшити вашу масштабованість. Конфігурація Varnish — це окрема велика стаття, що вимагає окремого топіка.

Висновок

Я виклав у відкритий доступ конфігурацію мого веб-сервера, щоб довести, що можна добитися високої продуктивності навіть від самого дешевого VPS контейнера з 512МБ RAM і 1Ghz CPU. Використовую я Ubuntu 12.04 LTS, LAMP, Varnish,APC Cache для розміщення 3-х сайтів, зроблених на Wordpress (не мультисайтовых) з відвідуваністю 10к в день. Давайте поглянемо на результати тестів від Blitz.io:



Як бачите, 0,23% користувачів отримують Connection Timeout, коли мій веб-сайт має 42,735,587 хітів в день (WOW), може можна ще щось оптимізувати, але я отримую задоволення від роботи мого веб-сервера. Якщо ти втомився від цього керівництва або не хочеш робити руками, то можеш скористатися такими сервісами, як PuPHPet або Vagrant.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.