На ловца и зверь бежит!
Вопрос от нуба, а Apache обязательно должен висеть на порте отличном от Nginx?
если нет требования «всё должно работать», то необязательно :)
Теоретически можно их повесить на одном порту, только на разные ip, то есть apache будет висеть на localhost (127.0.0.1:80), а nginx на внешнем ip (8.8.8.8:80). Обычно apache вешают на 127.0.0.1, но на порт отличный от 80, например (8081), а nginx на 80 порт на все ip'шники. Это позволяет не вносить правила в фаервол, которые запрещают доступ к apache извне.
Если апач висит на 127.0.0.1 — доступа извне к нему не может быть по определению.
В этом суть!
8.8.8.8 — Google public DNS.
Используйте стандартные обозначения — localhost и example.com
ip — определяет к какому устройству(компу) в сети мы обращаемся, порт — к какому сервису(приложению) на нем.
практически апач вешается на внешний ипишник:80, а энджи на локалхост:80, и извне к апачу ты ни под каким соусом не обратишься
блин, наоборот — энджи на внешний ипишник а апал — локалхост :(
2 приложения априори не могут висеть на наборе ip:port.
А зачем для eAccelerator 2 гига? Неужели так много скриптов?!
много оперативки. Делал с запасом. Нет общий размер приложения порядка метров 300
2 гига запас для кода? Продуктивные программисты у вас, однако :)
Эффективные
CakePHP одно из узких мест на хайлоаде, проверено на опыте, переписывали на YII.
я бы и от мускуля в пользу redis'a или другого nosql решения отказался. Но на текущем этапе я не смог даже добиться что бы программисты перенесли данные сессий в memcache или хоть куда с диска.
тоже думаем в сторону nosql, но пока mysql с репликами, а cakephp тяжел, имейте в виду, так же memcache используем, ага, и связку nginx + php-fpm как ниже пишут уже
Если сессии стандартные, то это меняется в настройках php.
нет там что-то нахимичили. Не стал туда лезть пока.
Если не хотят переносить сессии с диска, поместите на tmpfs
Вообще, многое можно поместить на tmpfs, не только сессии.
hot static, mysql tmpdir & etc.
Апач не нужен. Поставьте уже php-fpm… Перенос .htaccess в конфиг nginx займет у вас совсем немного времени.
Согласен. Давно ушёл к нему. Сейчас в php5.4 вроде вообще свой сервер есть/будет.
+1 перевел почти все сервера на nginx + php-fpm, для перловых и питоновских скриптов поставил lighttpd.
согласен полностью. Проект не мой, ко мне обратились быстро найти и исправить основную проблему. И надо было что-то сделать быстро. Плюс заказчик отказался на первом этапе от переделки.
Там еще много косяков. 2 nginx'а тоже лишнее.
В общем по мере развития и запросов буду отписываться как и что делал, если интересно
Почему 2nginx? 1 nginx может справиться с обеими задачами же.
потому что там бардак, за исправление которого никто не платит. Я описывал изменение одного из 3 серверов. Вся статика как казалось заказчику находится на другом сервере с nginx'ом. А запросы шли напрямую по ip к нему. Но как оказалось не вся.
Для питона пользуйте WSGI.
можно просто проксировать на быстрые wsgi серверы как gunicorn
В 5.4 сервер есть, но только для разработки он предназначен, чтобы не поднимать веб-сервер локально, с конфигами не мучаться и т. п., а просто зайти в директорию проекта и запустить.
… на котором большими красными буквами написано «не для продакшена».
Не понял корреляции между

Так как имеем на руках InnoDB

и

myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_max_extra_sort_file_size = 10G
Насколько я понимаю, на сложных запросах mysql строит временные таблицы и они то как раз MyISAM. Действительно не нашел подтверждения что они коррелируются, но как я уже сказал, за основу взять файл из тарбола mysql, оптимизированный под innodb
Мне вседа казалось что тип временных таблиц таки MEMORY, возможно я ошибаюсь
Вот придирчивые все. Специально для Вас!
dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tmp_table_size
The maximum size of internal in-memory temporary tables. (The actual limit is determined as the minimum of tmp_table_size and max_heap_table_size.) If an in-memory temporary table exceeds the limit, MySQL automatically converts it to an on-disk MyISAM table. Increase the value of tmp_table_size (and max_heap_table_size if necessary) if you do many advanced GROUP BY queries and you have lots of memory. This variable does not apply to user-created MEMORY tables.

You can compare the number of internal on-disk temporary tables created to the total number of internal temporary tables created by comparing the values of the Created_tmp_disk_tables and Created_tmp_tables variables.
Спасибо, но я так понимаю, что в MyISAM они конвертируются только тогда, когда кладутся на диск
Тут вы правы!
dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html
In some cases, the server creates internal temporary tables while processing queries. Such a table can be held in memory and processed by the MEMORY storage engine, or stored on disk and processed by the MyISAM storage engine. The server may create a temporary table initially as an in-memory table, then convert it to an on-disk table if it becomes too large. Users have no direct control over when the server creates an internal temporary table or which storage engine the server uses to manage it.

Но на лично у меня кладется достаточно большой процент. Больше 20%. Я так понимаю это частое явление и у меня не получилось сильно на него влиять. Так что хоть немного их оптимизировать желательно.
У нас, наверное к счастью, в данный момент на 6 временных таблиц 0 на диске. Это заставляет надеяться, что у нас все неплохо :-)
Есть еще 2 сервера, один со статикой, другой с бекэнд базой.

В топе, понятное дело, MySQL и Apache дерутся за ресурсы системы.

Есть БД на другом сервере, то к чему вы это написали? :)
Не хотел акцентировать внимание на другие сервера, так как в принципе все делается на одном.
Может я не так выразился, но nginx'а 2. Один который поднимал я перед апачем. Другой висит на соседнем сервере и обслуживает часть статики. Так сделали до меня. А запись домена вела на апач и позже на мой nginx, а картинки в html коде запрашивались по ip со второго. Вроде бы я это уже описывал хотя и менее подробно.
То есть получается просто две базы данных, которые живут отдельно? Или все же слейв-мастер?
Вы вот динамику с апача закэшировали, а кэш этот никак не валидируете. А если там меняющиеся со временем картинки?
Снести всё, поставить нормально nginx, apache нафиг, на сервер с кучей оперативки докинуть memcache и кешировать всё туда.
Это будет следующим этапом. Клиент не видел нас в работе и не доверял полную переделку.
Вот с этим сисадмину уже к разработчикам.
Я что-то не понял какая нагрузка у сервера 70-100 конкурентных запросов?
С ней он справлялся и до оптимизации. Заказчик делает некую рассылку и пользователей на сайт приходит до 1500 за единицу времени. Вот тогда сервер начинал загибаться за 5-10 минут.
1500 конкурентных запросов это уже очень много, мне кажется такие оптимизации не помогут выдержать нагрузку.

По крайней мере когда я у себя тестировал, при подхождении к 500 конкурентным запросам, сервак упирался во множество параметров, даже файлы сессий на диске не успевал создавать.
В свое время такая же проблема была на высоконагруженном форуме. Оптимизация сильно не помогла и периодически сервер уходил в небытие с IO 100%, в итоге проблема решилась переездом на другой сервер в том же Hetzner:
2 SATA RAID под систему и файлики
2 SAS RAID чисто под БД (ну и ночные бекапы)
А перемонтировать FS c noatime не пробовали?
Ну проблема решилась и дальше не оптимизировали. =)
А что даст такая перемонтировка? Там таблица в БД большая и в неё постоянно новые посты пишутся. Неужели на уровне файловой системы можно что-то сделать?
Сделали совсем по другому. Сейчас там выделенный сервер под бд. 16Гб ОЗУ вместо 64, но 4x300Гб SAS диски в рейд 10, аппаратном. А бд сейчас Percona. Вот это реально дало производительности столько что сервер не нагружается вообще.
Это сейчас вы описываете нынешнее состояние сервера или я что-то путаю?
Статься примерно 3 недельной давности. На перкону переехали недели 2 назад.
Для использования Percona на сайте потребовалось переписать интерфейс общения с БД? Или просто поменяли сервер и всё работает как надо?
Если не ошибаюсь — то достаточно просто поменять сервер.
percona 100% совместима с mysql. Это ее форк. Советовать или не советовать пока не буду. Поскольку еще не сталкивался с ней с проблемами. По скорости работы дала возможно лучшие результаты, а возможно все дело в том что я запихнул базу в raw lvm раздел, а LVM как говорил ранее на 10 рейд повесил.
Помимо mysqltuner.pl есть ещё один неплохой скрипт для оптимизации БД: launchpad.net/mysql-tuning-primer
Спасибо, добавлю. Да их много. Этот понравился лаконичностью. Пробовал еще два-три.
Спасибо за статью, всегда интересовала эта тема. Теперь буду знать, как оптимизировать эту связку. Сколько искал в интернете статьи об этом — ни разу не находил, и на хабре об этом никогда не писали, а теперь вот наконец-то появилась об этом статья, огромное спасибо.
Вы зря так говорите, мне во многом помог именно habr! Посмотрите на ссылки которые я привел.
На самом деле не так просто найти хорошую грамотную информацию по этой теме. Я рад, что наконец-то на хабре стали появляться новые статьи о малоизвестных технологиях.
Статья действительно получилась очень хорошая, спасибо ещё раз: )
Я надеялся что статься будет хорошей, когда ее дополнят критикой. Потому как все что тут описано, хоть и перечитано неоднократно мной лично, не факт что является истиной. Может у кого-то есть другие мнения. Но все равно спасибо за лестные отзывы. По мере изменения буду добавлять. Могу так же описать процесс переноса на Percona если кому интересно. Хотя подводный камень там был лишь один — правильные права на lvm том. Ну и плюс некоторые изменения в синтаксисе конфигурационного файла.
Чувак просто стебет над вами, расслабьтесь.
Почему бы не подыграть? Ладно, каюсь, попался!

Если серьезно, я понимаю что все это тысячу раз описано. Цель была описать основные моменты и направления развития для того кто сталкивается первый раз. Когда я столкнулся, мне бы данная инфа или хотя бы список ссылок очень пригодились. Материал поверхностный и многие детали оставлены без внимания. А многие кучу раз уже описывались. Еще раз. Цель — собрать во едино все основные проблемы и беды подобных проектов.
Тогда почему же статья как минимум в части по mysql написана в стиле «а вот этот параметр я тоже точно не знаю что делает, но на всякий случай поменял, вдруг поможет».
Всё это очень напоминает использование «улучшителей реестра windows и отключение служб», сразу всех лишних, а уже потом выясняется, что служба WIA требуется для сканера, а ключ реестра «8.3 filenames» мешает работе парочке старых, но популярных программ.
Я уже отвечал на этот вопрос господину выше. kDas. О том что сами разработчики не знают как влияет тот или иной параметр. Потому как они могут ожидать один результат а на практике выходит другой.
Согласен с Вами что аналогия с реестром есть. Процитированные Вами строки призывали гуру подсказать что стоит менять. Я не претендую на 100% знание mysql, но поскольку результат есть, думаю и статья имеет место быть!
Эх, у вас так много догадок, а не конкретных фактов. :( Разумеется, сейчас гораздо актуальнее будет связка nginx+php-cgi (пользую через fcgi-spawn) — работает действительно лучше. :)

В Вашем случае вместо eAccelerator-a отдал бы предпочтение memcache. Приложение же одно на сервере, верно?

От себя же советую попинать кодеров и поскорее переписать приложение на yii (если обязательное требование — реализация на php, если нет — привет рельсам). И, разумеется, отказаться от MySQL в сторону nosql решений. В крайнем случае, mariadb — не поверите, но разница ощутима!
Спасибо. Если читали комменты, то уже переехали на Percona. Догадок много потому что mysql такой. Даже на www.mysqlperformanceblog.com/ неоднократно говорят о неоднозначности параметров конфига и о документации. Я лишь обратил внимание на то куда стоит смотреть.
Настчет рельсов — тут как вариант еще и торнадо и джанго. Но они все php любят почему-то.
Пинать не буду, это было условием совместной работы — то что они в данном приложении остаются на PHP. Чую уже переписывали просто и больше на это бюджета не выделят.

Что скажете про php-frm?

На memcache пытался их пересадить. Упираются пока. Но думаю все впереди. Когда следующие затыки начнутся.
Если не хотят memcache (а зря конечно), попробуйте Xcache.

И так же плюс за mariadb, только начал ее тестировать, разницу уже вижу.
Перкона и Мария по сути два форка оригинального MySQL. В перконе неплох свой движок ExtraDB, ну и handler socket у меня получалось прикрутить только к ней. В Марии новая замена MyISAM — Aria тоже весьма-весьма занятная штука. По скорости оба выигрывают у оригинала, примерно на одном уровне
Если не хотят memcache (а зря конечно), попробуйте Xcache

извините, а они взаимозаменяемые прям?

XCache is a open-source opcode cacher

memcached is a general-purpose distributed memory caching system
Как бы нет.
Вполне, разве что мемкэш байткод не умеет кэшировать =) И memcache и Xcache предоставляют хранилище типа ключ-значение.

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

В этом плане классно построена работа с кэшем в Yii Framework — есть интерфейс CCache с которым взаимодействует приложение и есть его конкретные реализации CMemCache, CApcCache, CXCache, CEAcceleratorCache,CDbCache, CZendDataCache и т.д и т.п
Конкретная реализация устанавливается в конфиге и может бытьв любой момент изменена (хоть во время выполнения), без модификации всего приложения.

Вопросы:
1. сталкивались ли с проблемой нехватки портов, и как с ней боролись?
2. есть ли реальный смысл замены работы по портам (для memcached, mysql и т.д.) на unix-сокеты?
есть ли реальный смысл замены работы по портам (для memcached, mysql и т.д.) на unix-сокеты
однозначно
Как уже говорил, бд на сегодняшний день уже на отдельном сервере. Так же я планирую сделать много виртуалок с апачем, которые будет проксировать nginx. Так что насчет сокетов, видимо не получится. А на счет портов — похоже столкнусь на nginx'e когда он будет единым и центральным
В топе, понятное дело, MySQL и Apache дерутся за ресурсы системы.

Т.е. я правильно понял, что у вас в нагруженном приложении БД и вебсервер крутятся на одной физической машине? А зачем так? Почему не сделать отдельные?
По части MySQL больше похоже на рубрику «Вредные советы».
Без понимания внутренних механизмов работы СУБД и режима эксплуатации её приложением адекватно настроить СУБД можно разве что случайно.

Для общего понимания рекомендую ознакомится с презентацией Петра Зайцева (CEO в Percona): www.percona.com/files/presentations/percona-live/dc-2012/PLDC2012-optimizing-mysql-configuration.pdf
спасибо. После беглого прочтения, вроде нигде глупостей не наделал! Завтра добавлю рекомендаций. Очень полезная статья.
а апач не пытались выкинуть из этой связки?
А вы комментарии читали?
а че комментарии, пост хотя бы
и CackePHP тоже?
и еще до кучи MySQL?
моя социгра имеет время отклика 5-15мс в зависимости от логики (логика сложная).
конфигурация nginx-php-mongoDb
 раз минусуют, значить РНР-Торт с мускулем круче,
ну и какое время отклиука у Вас?
А можете рассказать почему eAccelerator, а не APC? В статьях очень часто упоминается eAccelerator, но он мне мертвым показался: еще недавно у них на сайте заглушка апача висела, последний релиз был 2 года назад — мутно как-то все. APC как-то бодрее смотрится, и помню, грозились даже его в пхп встроить по-дефолту.
Хотел бы поправить.

Ограничения, записанные в /etc/security/limits.conf для nginx ничего не дадут, т.к. эти значения используются только через PAM (в данном случае модуль pam_limits).

Для nginx максимальное значение nofile можно задать диррективой worker_rlimit_nofile.
Ещё. Чтобы установить eaccelerator.shm_size больше 32M (по-умолчанию в Linux) нужно изменить параметр ядра kernel.shmmax, например, в /etc/sysctl.conf:
kernel.shmmax=значение_в_байтах

Иначе eAccelerator не будет работать как надо (если вообще будет).
Тут вы 100% правы. Не рискнул писать про эти переменные так как никак не могу у себя в голове уложить как они работают. Вроде как выставил почти под всю ОЗУ но не уверен что это верно. Сможете подсказать читателям как их правильно считать? Я имею в виду shmmax и shmmal
kernel.shmall — общее максимальное выделение памяти (количеством страниц по 4096 байт)
kernel.shmmax — максимум выделения памяти для одного запроса (в байтах)

Чтобы забить все 64 Гб ОЗУ:
kernel.shmall = 16777216 # подсчёт 64x1024x1024x1024/4096

Для eaccelerator.shm_size = «2096» (М)
kernel.shmmax = 2197815296 # подсчёт 2096x1024x1024
Может что-то путаю. Но после изменения файла ошибки в логах больше не появлялись.
Скорее всего вы установили значение для шелла (например, через ulimit) и перезапустили nginx. Соответственно, произошло наследование ограничений.
nginx работает от своего пользователя и у этого пользователя нет shell, но проверял применение значений я именно путем включения shella для этого пользователя и запуском ulimit из под него. Я проверю, спасибо!
абсолютно всеми запросами на сайт управляет PHP скрипт на который .htaccess переадресует любой запрос.

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

image
По моему опыту гораздо эффективнее «тонких настроек» для нагруженных проектов становятся:

1. Отказ от apache в сторону fastcgi (я пользую php-fpm). Даже самый голый апач жрет на 60-90% больше.

2. Перевод архитектуры Mysql на повсеместное использование memcached и временных таблиц типа memory с дампом их по крону. Если два пользователя могут получить одинаковые данные, то нет смысла для них два раза тревожить БД.
1. Полностью согласен и предлагал. Пока отказались.
2. По поводу memcached'a — тоже согласен, хотя и не во всем. MySQL достаточно эффективно кеширует похожие запросы на чтение, если они верны. А если они не верны то не спасет и memcached
Кеш MySQL порой работает довольно криво, насколько помню если в начале запроса добавить лишний пробел — это уже сache miss, и так далее.
Потому что он считаешь хэш от запроса. Просто используйте параметризованные запросы, оформляйте их в одном стиле (без лишних пробелов, перечисление полей в одинаковом порядке и т.д.), и всё будет хорошо.
Мне прекрасно понятно почему кеш уже другой, тем не менее факт того, что запрос хешируется нужно знать всем и постоянно следить за этим фактом. Мне кажется, реализация кеширования могла избавить разработчиков от этого ньюанса.
1. Чем аргументировали? Не представляю в чем может быть разница на стороне клиента, разве только в самописных модулях под апач? Так на адаптацию вы потратите меньше времени, чем на «тонкую настройку» воркеров.

2. Управлять встроенным кэшем вы не можете, и гарантий что из кэша выкинет нужный/сложный запрос нет. В memcached вы сами выбираете нужные значения, объемы памяти, привилегии и время хранения. И это даже не поднимая вопрос масштабируемости.
Для нагруженного проекта нужно отказываться в сторону uWSGI, а не fastcgi ;)
Спасибо. Прочитал ваш пост по этому поводу. Как минимум в тестовом варианте обязательно проверю
После проверки отпишитесь: не обязательно отдельным постом, можно комментарием к моему существующему. Описаний опыта такого рода на Хабре еще не было.
realpath_cache_size попробуйте еще покрутить в php
Только полноправные пользователи могут оставлять комментарии.
Войдите, пожалуйста.