Grabduck

Сервер на стероидах: FreeBSD, nginx, MySQL, PostgreSQL, PHP и многое другое

:

Нравится мне эта картинка, у меня, вот никогда такие красивые графики в какти не получались =(

Введение


С момента написания мной предыдущей статьи по оптимизации этой связки прошло довольно много времени. Тот многострадальный Pentium 4 c 512Мб памяти, обслуживающий одновременно до тысячи человек на форуме и до 150,000 пиров на трекере уже давно покоится на какой-нить немецкой, свалке, а клуб сменил уже не один сервер. Всё сказанное в ней всё ещё остаётся актуальным, однако есть вещи которые стоит добавить.
Статья большая, так что будет поделена на логические блоки:
0. Зачем вообще что-то оптимизировать?
  
1. Оптимизация ОС (FreeBSD)
  1.1 Переход на 7.х 
  1.2 Переход на 7.2
  1.3 Переход на amd64
  1.4 Разгрузка сетевой подсистемы
  1.5 FreeBSD и большое кол-во файлов
  1.6 Softupdates, gjournal и mount options
  
2. Оптимизация фронтенда (nginx)
  2.1 Accept Filters
  2.2 Кеширование
  2.3 AIO
  
3. Оптимизация бэкенда
  3.1 APC
  3.1.1 APC locking
  3.1.2 APC hints
  3.1.3 APC fragmentation
  3.2 PHP 5.3
  
4. Оптимизация базы данных
  4.1 MySQL 
  4.1.1 Переход на 5.1
  4.1.2 Переход на InnoDB
  4.1.3 Встроеный кеш MySQL - Query Cache
  4.1.4 Индексы
  
4.2 PostgreSQL
  4.2.1 Индексы
  4.2.2 pgBouncer и другие.
  4.2.3 pgFouine
  
4.3 Разгрузка базы данных
  4.3.1 SphinxQL
  4.3.2 Не-RDBMS хранилище
  4.4 Кодировки
  4.5 Асинхронность
  
Приложение. Мелочи.
  1. SSHGuard или альтернатива.
  2. xtrabackup
  3. Перенос почты на другой хост
  4. Интеграция со сторонним ПО
  5. Мониторинг
  
 6. Минусы оптимизации


0. Зачем вообще что-то оптимизировать?


Вообще расти можно:
  • Scale up (Наращивать железо)
  • Scale out (Увеличивать количество фронтендов/машин в middle tier)
  • Оптимизируя

Первый вариант лучше использовать когда у вас много денег, второй, когда хорошая архитектура. Ну а третий, который буду описывать я, используют когда нет ни первого, ни второго, а хочется выжать максимум из имеющегося железа.

1. Оптимизация ОС (FreeBSD)


1.1 Переход на 7.х


Что же мы получим при переходе на новую версию FreeBSD?
По мне самое главное это:
Новый ULE 3.0 Scheduler и jemalloc весьма полезны на многоядерных (>=4) системах.
MSI (Message Signaled Interrupts) — они же часто упоминаются в драйверах как Fast Interupts.

Так что если у вас есть legacy 6.x система, которая начинает прогибаться под нагрузкой, возможно стоит перевести её на 7.х.

1.2 Переход на 7.2


Superpages, увеличенный KVA, оптимизированные по-дефолту sysctl'и. Всё это вы получите абсолютно бесплатно просто перейдя на последний релиз ОС.

Прогресс тоже не стоит на месте и вот уже FreeBSD 8.0 готовится к выходу, там нам обещают дальнейшее увеличение производительности. В качестве подтверждения стабильности www.FreeBSD.org был переведён на FreeBSD-CURRENT ещё во времена первых beta-версий. Так что на staging машинах можно её уже начинать гонять.

1.3 Переход на amd64


Переходя на amd64 вы дополнительно получите гиганские размеры KVA и Shared Mem >2Gb. Однако это далеко не самое главное...

Заметьте, что 4 Gb памяти в 2009 году уже во всю ставят на ноутбуки, и ставить столько на сервер с БД довольно смешно. Конечно, для маленькой БД это нормально, но что делать когда она разрастётся и перестанет влезать в память? C i386 ОС доставить ещё памяти будет проблематично, ибо PAE это отдельный глюк. Да и INT64 уже давно много где используется и даёт прирост производительности таким приложениям как, например, базы данных и OpenSSL. (Если у кого есть линки на адекватные бенчмарки "***SQL i686 vs amd64" — кидайте в комменты).

1.4 Разгрузка сетевой подсистемы


Тут во FreeBSD не то что поле, а целый полигон для испытаний.
Всю оптимизацию можно разделить на 2 части: Тюнинг параметров ifconfig и настроек sysctl.conf/loader.conf, давайте в таком порядке и пойдём.
Для начала нужно посмотреть на что наши сетевухи вообще способны, для этого можно воспользоваться такой командой:
# ifconfig -m
capabilities=399b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_UCAST,WOL_MCAST,WOL_MAGIC>

В случае если у вас хорошая сетевуха класса em (Intel Gigabit) / bge (Broadcom Gigabit) можно попробовать опции ifconfig:
  • tso (tso4, tso6) — TCP Segent Offloading
  • lro — Large Recive Offload
  • txcsum, rxcsum — RX / TX Checksum Offload
  • link0, link1, link2 — зависят от драйвера, надо смотреть его код. Иногда включают некоторые оптимизации, иногда просто переключает сетевуху в MASTER на Gigabit линках.

Также, на em сетевухах и многоядерных процах можно попробовать драйверы от Яндекса, которые осуществляют обработку пакетов в несколько потоков. Так же очень много всего про тюнинг сетевой подсистемы можно прочитать на nag.ru

Если же у вас третьесортная сетевуха ( re/rl/sk/nfe...), то вышеописанные опции могут работать неправильно и приводить к зависанию сервера, так что лучше остановиться на polling'e.

Ну и напоследок рекомендую всем посмотреть обновлённую версию тюнинга FreeBSD 7 «по Сысоеву» и мой лист sysctl'ей с комментариями.

1.5 FreeBSD и большое кол-во файлов


Во FreeBSD есть прекрасная технология кеширования имён файлов в директориии. Так, если у вас в одной директории находится множество файлов, то намного лучше использовать поиск по хеш таблице, нежели постоянно пробегать по всему дереву вширь/вглубь в поисках нужного файла. Однако, макс. кол-во памяти выделенное под dirhash (так называется эта технология) ограничена vfs.ufs.dirhash_maxmem и по-умолчанию составляет, вроде, 2Мб, что весьма мало. Рекомендуется увеличивать память до тех пор пока vfs.ufs.dirhash_mem не перестанет упираться в «потолок».

1.6 Softupdates, gjournal и mount options


Новые терабайтные винты просто шикарны — стоят дешево, да и производительность у них просто касс. Однако, есть один нюанс: когда в датацентре отрубят электричество, то fsck таких терабайтников может занять не один час. Решить эту проблему можно используя softupdates или же прикрутить к системе журналирование через gjournal. Что именно, решать вам.
Пара советов по журналированию: чтобы не потерять производительность, лучше журнальный раздел оправить на отдельный диск, а чтобы не ловить паники из-за его переполнения, лучше сделать раздел журнала побольше (например, RAM+swap).
Если же у вас есть raid с BPU, или вам просто нечего терять, то можно в /etc/fstab добавлять опцию async. А такую опцию как noatime можно практически без опаски порекомендовать всем. (читать комментарий пользователя giner вот тут)

2. Оптимизация фронтенда (nginx)


На самом деле, я крайне против чрезмерной и/или преждевременной оптимизации, к коим относится оптимизация фронтенда. Обычно на веб проектах, где nginx занимается не только статикой, он потребляет 1%-5% CPU в зависимости от характера его использования, остальное же кушает php.
Однако, оптимизация конфига nginx может повлиять на общий response time сайта, так что есть моменты о которых стоит поговорить.
Из стандартных оптимизаций могу порекомендовать
 reset_timedout_connection  on;
 sendfile                   on;
 tcp_nopush                 on;
 tcp_nodelay                on;

Ну и поиграться с количеством воркеров, а не просто ставить их по кол-ву CPU/Винтов. Также рекомендую всем ознакомится с этим документом и темой Nginx best-practices на Serverfault, очень вероятно, что вы узнаете что-то новое.

2.1 Accept Filters


Во FreeBSD имеется технология, позволяющая передавать пакет от ядра к процессу только в случае прихода 1) каких либо данных 2) валидного http запроса. Технология эта называется accept filters. Такие фильтры помогут как разгрузить сервер в случае большого кол-ва соединений, так и немного защитить от DDoS'a (Хотя со вторым лучше справляется ngx_http_limit_req_module, о котором уже не раз писалось на хабре)
Чтобы включить обработку соединений с использованием фильтров, нужно для начала загрузить модуль ядра:
#ls /boot/kernel/|grep acc
   accf_data.ko
   accf_http.ko
#kldload accf_http

Далее в конфиге nginx.conf включить фильтр httpready:
listen 80 default accept_filter=httpready;

2.2 Кеширование


В nginx имеется очень гибкая система кеширования ответов, как от fastcgi, так и от proxy backend'ов. Я думаю у каждого прочитавшего документацию в голове сразу возникло несколько сценариев применения кеширования в своём проекте. Я могу дать только общие советы:
Не дай Бог у вас rss отдаётся через php скрипт. Если так, то спокойно можно кешировать ответ на 3-5 минут.
Думаю почти всю версию сайта для гостей можно запихнуть в кеш тоже минут на 5 (ну если конечно у вас не новостной сайт)

Кроме серверного кеша существует ещё и кеш клиентский. Я бы рекомендовал на всю статику повесить expire в месяц:

    
        location ~* \.(jpg|jpeg|gif|png)$ {
    	   root   /var/nnm-club;
    	   expires      30d;
        }

2.3 AIO


Про введение AIO в nginx уже писали на хабре, там же имеются довольно интересные обсуждения в комментах. Вкратце, AIO полезен на весьма специфичных нагрузках, а так же помогает сохранить response time при уменьшении количества воркеров.
Для использования aio нужно подгрузить модуь ядра aio.ko:
#kldload aio
а затем включить aio и sendfile в nginx.conf
 
 sendfile        on;
 aio             sendfile;

Новые версии nginx позволяют использовать aio вместе с sendfile. По поводу такой конфигурации в документации сказано:
В такой конфигурации используется флаг SF_NODISKIO и sendfile() не блокируется на диске, а сообщает об отсутствии данных в памяти, после чего nginx инициирует асинхронную подгрузку данных, читая только один байт. При этом ядро FreeBSD подгружает в память первые 128K файла, однако при последующих чтениях файл подгружается частями только по 16K. Поэтому этот режим лучше применять для раздачи небольших, до 128K, файлов.

Патч для FreeBSD, для решения этой проблемы тут, возможно со временем он войдёт в -CURRENT и будет портирован в 8.0 и 7.х

3. Оптимизация бэкенда


Тут особо много мне расскажешь, у java, например, есть волшебные строки из серии "-Xms768m -Xmx1280m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseCompressedOops -Djava.net.preferIPv4Stack=true -XX:+DoEscapeAnalysis", которые способен понять только наш java-программер, а у PHP 50% оптимизации деает кеширование opcode, остальной прирост наблюдается от кеширования ответов от БД. Так что эта часть топика будет весьма скупой.

3.1 APC


Про оптимизацию APC рассказывали разработчики Facebook. Очень рекомендую почитать, если будет время.

3.1.1 APC locking


Старый File Locking, это именно тот «тормоз», из-за которого вместо APC начинают использовать eAccelerator. Так, что дефолтный locking часто рекомендуют менять на spinlock или pthread mutex. Насколько я помню, pthread mutex стал дефолтным начиная с 3.0.16, так что, если у вас есть сервера со старым APC рекомендую его обновить.

3.1.2 APC hints


Если у вас много .php файлов или вы много кешируете в APC user cache, то весьма вероятно вам придётся поднимать значения
apc.num_files_hint и apc.user_entries_hint соответственно в php.ini. Эти значения отвечают за размеры hash таблиц APC (на самом деле они ещё удваиваются перед применением), а мы знаем что хеш таблицы работают весьма плохо при load factor >= 0.75

3.1.3 APC fragmentation


Фрагментация в APC — это такая штука, из-за которой этот самый кеш хочется взять, скомкать и выкинуть в окно. APC не являтеся заменой нормальному key-value по причине его неспособности удалять автоматом записи по TTL или LRU. То есть, нету никакого GC и записи попавшие в кеш от туда могут уйти только в двух случаях:
  • Когда к ним обратились после истечения их ttl
  • Вся память кончилась и APC прибег к экстренной мере — сброс всего кеша целиком.

Суммируя, можно сказать: Высокая фрагментация является признаком того, что вы используете APC не по назначению.
Тут нужно добавить заметку, судя по комментам тут, в 3.1.х очень многое поправили в плане аллокации памяти, однако судя по этому, 3.1.х работает не у всех.

3.2 PHP 5.3


Тут всё кажется простым — обновляем PHP, получаем прирост производительности. Однако, посмотрев на список deprecated функций в 5.3 можно ужаснутся, благо они пока ещё работают.
Несмотря на всю простоту, думаю, переход от 5.2 до 5.3 будет ойойой каким долгим, особенно в продакшне.

4. Оптимизация базы данных


На самом деле лучшими оптимизациями БД у нас в клубе признаны:
  • Не использование RDBMS вообще (sphinxsearch)
  • Не использование базы (кеширование)
  • Batch запросы (where in (...), batch insert/update)
  • Ассинхронная работа с БД (memcacheQ, apacheMQ, AQMP, crontab)

Однако, большая часть вышеописанных средств требуют довольно серьёзного переписывания приложения.

4.1 MySQL


Мануалов в инете по оптимизации MySQL довольно много, есть грамотные, есть не очень. В любом случае, за время жизни любого веб-проекта его база успеет упереться и в память, и в диск, и может даже в процессор, так что простыми howto не обойтись, придётся смотреть конференции, учится пользоваться профайлерами(oprofile, systemtap, dtrace) и использовать большое кол-во дополнительного ПО. Иными словами, не только понимать, что такое индексы, сортировки и группировки, но так же понимать как MySQL их использует внутри, знать что такое EXPLAIN, Query cache, преимущества и недостатки различных storage engine'ов, в общем, быть 100% DBA для своего проекта.
Далее я опишу способы которые помогут с минимальными изменениями кода (а то и вовсе без них), оптимизировать MySQL.
Как я уже говорил в предыдущей части, 50% тюнинга MySQL можно провести в полуавтоматическом режиме всего двумя утилитами:

4.1.1 Переход на 5.1


Переход на 5.1 приносит множество бонусов, мне конкретно были интересны:
  • Оптимизация оптимизатора (особенно GROUP BY)
  • InnoDB plugin
  • Partitioning
  • Row based replication

Всё это может прибавить производительности, так что на 5.1 перелезать стоит. По поводу шума вокруг того что 5.1 не стабильна, то всё это уже не актуально, да и изначально было слишком раздуто (если у кого есть какие противопоказания или bad expirience перехода на 5.1 — прошу в комменты).
Самые экстрималы, конечно, уже давно тестируют 5.4, там говорят производительность очень хорошо подняли (не без помощи патчей от Гугла и Percona, я думаю). Но до продакшна 5.4 ещё далеко.

4.1.2 Переход на InnoDB


Вот скажите, если у вас используется MyISAM, то почему именно он? Я вообще не понимаю как может продакшн сервер жить на MyISAM (хотя, говорят такие существуют), где нет транзакций (если сервер упадёт во время большого UPDATE, то половина данных будет изменена, а половина нет), есть TABLE LOCK (во время записи в таблицу она блокируется на чтение и vice vresa), а REPAIR после пропадания электричества в датацентре может занимать десятки часов. Единственное, что спасает MyISAM — это наличие Fulltext Index, но даже он вряд ли может конкурировать по качеству и скорости со sphinxsearch.

Да, у InnoDB есть свои недостатки (deadlock'и, бОльшие по размеру индексы, отсутствие FTS), но бонусов, имхо, в разы больше: Во-первых, InnoDB полностью ACID-совместим, а значит любая операция, даже такая как дамп базы данных, может быть произведена в одну транзакцию (опция mysqldump --single-transaction), а во-вторых, он имеет row-level locking (против TABLE LOCK у myisam), это означает, что данные могут одновременно и читаться и писаться в несколько потоков не блокируя друг друга.
Опять же, люди совсем озабоченные производительностью сердца своего стартапа могут использовать XtraDB, говорят оно сильно помогает на I/O-bound workload'ах.

4.1.3 Встроеный кеш MySQL — Query Cache


Query Cache — это одна из самых «недопонимаемых» частей MySQL. Многие его ставят в 512Mb и думают, что «щас всё залетает», многие его отключают вообще потому, что «всёравно не работает». Попытаюсь пролить свет на значение этого параметра. Начну с того, что больше, в данном случае, не лучше, так что задирать его не стоит. Далее, надо уточнить, что Query Cache — это полностью не распараллеленная подсистема, так что на кол-ве процессоров >=8 её лучше отключать, ибо будет только тормозить. Ну и последнее, но не самое бесполезное — суть Query Cache в том, что его содержимое, относящееся к какой либо таблице, полностью сбрасывается при любом изменении этой самой таблицы. Тоесть, фактически, Query Cache даёт прирост производительности только на грамотно нормализованных таблицах.
Подробнее о QC можно прочитать тут.

4.1.4 Индексы


Как отсутствие индекса вредно для SELECT'a, так и лишние индексы вредны для INSERT/UPDATE. Часто бывает так, что старый, когда-то сделанный индекс, может жить в базе не один год, занимая драгоценную память и замедляя изменения данных. Тут приходит на помощь простенький SQL запрос. Полезно? Множество подобных tips'ов можно найти тут.

4.2 PostgreSQL


Для меня Postgres остаётся довольно странной системой: с одной стороны это база Enterprise класса и на нём бегает Skype, с другой настройки по умолчанию такие, что он может запустится даже на моём мобильнике. В общем надо тюнить, а тюнить тут можно практически всё. Из возможных почти 200 параметров, за тюнинг отвечают основные 45 =)
Кстати, что ещё поразило, так это то, что при закомменчивании строки в конфиге, PostgreSQL не сбрасывает её на «дефолт», а использует ту, что «запомнил»… Показалось?
По тюнингу Postgres в инете много всего (часть мануалов устарела, так что обращайте внимание на дату публикации и ключевое слово vacuum_mem, которое заменено на maintenance_mem в новых версиях). Есть что-то типа FAQ: вскользь о главном, есть очень глубокомысленные трактаты для продвинутых администраторов БД… Я расскажу лишь основы которые помогут проекту продержаться на ногах, пока админ с програмером ищут квалифицированного DBA.

4.2.1 Индексы


Тут у некоторых может возникнуть справедливый вопрос: почему, мол, у MySQL индексы были на последнем месте, а у PosgreSQL на первом? Всё просто, ибо возможности его в этом плане намного выше, чем у MySQL. B-tree, hash, GiST, GIN, а также multicolumn, partial и indexes on expressions: во всём этом должен разбираться человек который программирует под PostgerSQL. И не просто знать, что такие существуют, а понимать, в каких случаях нужно использовать одни типы индексов, а в каких другие.
Полезные для мониторинга SQL-запросы (в том числе и статистику по индексам) можно найти тут.

4.2.2 pgBouncer и другие.


pgBouncer (или его альтернатива) — первое, что должно быть установлено на сервере с базой данных. Я уже насмотрелся на cacti-графики показывающие десятикратное падение нагрузки от простой установки менеджера соединений. Если пулер соединений у вас не установлен, то на каждое соединение с базой у вас запускается отдельный процесс, далее этот процесс отъедает, как минимум, work_mem оперативки и начинает бороться за CPU и жесткий диск с себе подобными выполняя SQL запрос. Всё бы хорошо, но вот когда количество таких процессов зашкаливает за 200-500 серверу, даже очень мощному, становится туго. Очень туго. pgBouncer нас от этого спасает.
Также список полезных или даже незаменимых приложений для работы с PostgreSQL можно найти на сайте postgresqlrussia.org.

4.2.3 pgFouine


pgFouine как раз одна из таких незаменимых программ. Это очень продвинутый аналог mysqlsla на php. В комплекте с Playr (реплэйер продакшн логов) она позволяет проводить оптимизацию запросов на staging серверах в практически «боевых» условиях.

4.3 Разгрузка базы данных


Как я уже говорил, лучший способ оптимизировать работу БД и увеличить её производительность — это обращаться к ней как можно реже.

4.3.1 SphinxQL


В прошлой статье я говорил, про то что мы ввели поиск на основе sphinxsearch. Но не все смогут перерыть тысячи строк кода, чтобы начать использовать SphinxAPI, а потом потратить ещё 1-2 итерации на тестирование и отлов багов. Проблема решилась очень элегантно: SphinxSearch научился притворяться MySQL сервером, то есть для того чтобы начать его использовать необходимо лишь создать sphinx.conf, создать записи для indexer'a в cron'e и переключить поиск на другую «как бы mysql» базу. Есть вероятность, что дальнейшей правки кода не понадобиться.
Что вы получаете при переходе на сфинкс? Кроме улучшений скорости и качества поиска, вы сможете избавиться от MyISAM и его FTS, ну и, что очень интересно, так это придумать новые применения вашему поиску, мы вот, объединили поиск с RSS, что оказалось весьма удобным.
А вот и пара примеров, в которых можно выиграть от наличия sphinxsearch (придумано почти с ходу, так что сильно не бейте):
Пример 1: Я давно жду Starcraft 2, я всегда могу добавить в Google Reader RSS вида: rss.php?q=«starcraft 2» и увидеть все сообщения в которых его обсуждают. Так же, я, как участник форума, хочу видеть все посты где упоминается мой ник. Это тоже не проблема, надо всего лишь подправить урл.

Пример 1.5: Пользователь зашёл на сайт увидел строку поиска, ввёл запрос, нечего не нашлось, но появилась ссылка «Подписаться на этот поиск», со ссылкой на RSS для этого запроса. Так просто пользователь от вас не уйдёт =))

Пример 2: Я хочу найти фильм 21, или, не дай Бог, фильм 9 — MySQL не самоубийца, он такой запрос просто откинет, посетовав на то, что ft_min_word_len больше, чем длинна запроса. Сфинкс практически мгновенно вернёт результат в виде «Двадцать Одно / 21», а во втором случае даже даст выбор между «Район №9 / District 9» и «Девять / 9».

4.3.2 Не-RDBMS хранилище


Существует очень много мест в проекте, где можно не использовать реляционную базу данных. Достаточно простого key-value хранилища. Благо таких сейчас хватает.
Также есть весьма интересные проекты как, например, Hive (Data Warehouse с SQL-подобным QL и бекендом в виде Hadoop). В общем с хранилищем данных, можно ой как поэкспериментировать, не одним Oracle'ом (MySQL'ем, PostgreSQL'ем, FoxPro, нужное подчеркнуть) живы.
Также key-value БД из-за своей скорости используются для кешиорвание выборок из реляционных баз. По поводу самого кеширования: после пролистывания презентации, просмотра видео и прочтения полного текста доклада из блога Андрея Смирнова, мне практически нечего добавить. Лишь пара советов:
Если у вас действительно большой проект на PHP, то не забываете про возможность opcode cache хранить custom данные. В нём можно хранить самые часто используемые глобальные переменные: во-первых их не много и они маленькие, так что памяти кушать они будут совсем чуть-чуть, во-вторых скорость выборки будет выше, чем из memcached находящегося на соседней машине. Ну и самое интересное: в больших проектах бывали случаи когда блок глобальных переменных записывали на какую-то одну машину из memcached-фермы, так как эти переменные юзают все бэкенды, то трафик на эту машину возрастал до неприличных размеров и машинка начинала очень сильно тормозить, а вместе с ней и все бэкенды. Выходом из такой ситуации являлось бы либо хранение глобальных переменных в opcode cacher'e типа APC/eAccelerator, либо клонирование переменных на все сервера из memcached-фермы и внесение исключений в алгоритм consistency hashing'а.

4.4 Кодировки


Небольшая заметка по поводу кодировок:
UTF-8 хорош всем кроме одного — русский текст в нём занмает ровно в два раза больше места, так что иногда есть над чем задумываться перед тем как его использовать, если у вас целиком одноязычный контингент.

4.5 Асинхронность


На самом деле, далеко не всегда требуется синхронная обработка данных, довольно часто её можно заменить асинхронной.
Асинхронная обработка помогает 1) Улучшить время реакции сайта/приложения 2) Уменьшить нагрузку на сервер.
Если с первым всё понятно, то второе является следствием того, что batch запросы выполняются быстрее одиночных.
Асинхронность можно организовать по разному. В крупных проектах для этого используют очереди сообщений ( ApacheMQ, RabbitMQ, ZeroMQ. Про AQMP уже несколько раз писалось на хабре), в мелких можно обойтись и cron'ом.

Приложение. Мелочи.


1. SSHGuard или альтернатива.


Кроме того, что это стандартная практика ставить анти-брутфорс для ssh, так это ещё и дополнительно помогает защитить сервер от резких всплесков Load Avarenge когда на него нападают совсем офигевшие боты и начинают брутфорсить пары логин-пасс десятками тысяч.

2. xtrabackup


LVM снапшоты — это тормоз. mysqldump — лочит таблицы и делает текстовые бэкапы, которые могут восстанавливаться неделями. Очень хорошим инструментом для бэкапа MySQL является xtrabackup от Percona. Сильно расписывать его не буду, ибо русская часть инета о нём наслышана. Вкратце, xtrabackup это инструмент, позволяющий проводить не блокирующий бинарный бэкап InnoDB/XtraDB таблиц и имеющий кучу настроек. Почему очень хороший, а не отличный? Поскольку самым лучшим инструментом, на мой взгляд, являются клоны в ZFS. Делаются мгновенно, а восстановление базы с них это просто изменение пути к файлам в конфиге мускула, да и при неудачном востановлении можно откатится обратно. Также с клонов можно восстанавливать систему целиком, например в случае неудачного апгрейда ядра.
А вообще, вроде, в 5.4 нам обещают встроеный online backup

3. Перенос почты на другой хост


Данная оптимизация кажется минорной, однако при большом кол-ве спама льющегося на сервер помогает сильно уменьшить трафик и спасти множество IOPs.

4. Интеграция со сторонним ПО


Как-то на хабре проскакивала статья про online игры, мол, для всего нужно использовать наиболее подходящие средства (кто-нибудь помнит как она называлась?). Так, например, для того, чтобы дать возможность пользователям обмениваться почтовыми сообщениями с вложениями, не нужно начинать писать PHP скрипт с бэкендами в виде БД/ФС, можно использовать для этого, то что в реальной жизни применяется для обмена текстовыми сообщениями — связку smtp/imap и написать к ним простенький адаптер. По аналогии, чат для пользователей можно организовать на основе jabber сервера с javascript клиентом, который вообще не будет грузить сервер. Нужно отмечать объекты на на карте? Тут легче лёгкого написать mashup с использованием Yandex/Google карт. Что интересно, так такие системы, написанные на основе адаптера к готовым продуктам зачастую очень хорошо масштабируются, по крайней мере, на порядки лучше, чем решения на PHP и MySQL.

5. Мониторинг


Нечего оптимизировать, если не знаешь текущего состояния. Метрики производительности, задержек, свободных ресурсов, всё это должно мониториться, логироваться и, желательно, рисоваться на графиках. Благо инструментов хватает: Nagios, Zabbix, Cacti, Munin....

Берите любой, ставьте на сервак(и) и наблюдайте за влиянием оптимизаций на нагрузку сервера. Также мониторинг поможет предвидеть появление проблем с производительностью.

6. Минусы оптимизации


Bleeding-edge он, ведь, не случайно так назван. Во время переезда клуба на новый сервер мы это почувствовали на своей шкуре, умудрившись найти баги практически во всём ( APC1, APC2, MySQL, nginx, xbtt), благо OpenSource, что-то простое можно самим починить.

Вместо послесловия


Ну вот, вроде, и всё. Почти неделю печатал… Что осилил, то осилил, за кадром оставил ZFS, распределённые ФС, репликацию и шардинг, ибо это темы для отдельных постов. С грамматикой и пунктуацией у меня всё очень плохо, хоть я конечно и проверил всё несколько раз в ворде и тавтологии, так что если что найдёте — пишите в личку, поправлю.

Критика в адрес статьи приветствуется, ибо если нашли косяк в посте, то, скорее всего, нашли косяк в одном из моих проектов.