Серверов - несколько десятков. Запросы - простейшие SELECT / INSERT / UPDATE по первичным ключам или индексам. Много параллельных запросов, на тачку где-то 500-700 в секунду.
Проблемы только в пики нагрузки, когда юзера валом идут, с 18 до 24. В другое время все в рамках. Мы естественно разбиваем базы на более мелкие с закупкой серверов, но это время и вопрос не в том. Да, в память конечно ничего не влезает.
К сожалению, выбирать конфигурацию серверов нельзя. И менять хостера нельзя, т.к. он очень дешевый. Точную конфигурацию не помню, утром сообщу. Памяти - 6 гиг, софтварный рейд, зеркало. 8 ядер. Память уже тюнили, чтобы все работало без сваливания в своп.
Все данные - очень горячие.
Думаю, что все уперлось в винч по следующим показателям:
- CPU mysql ~0% (idle системы 70%)
- сотни php скриптов (кроны+аппликейшн) долбят параллельно базу (на веб-балансере 2000 соединений в секунду)
- увеличение кол-ва этих потоков на скорость не влияет
- сами php потоки жрут ~0% CPU и несколько метров памяти (на разных серверах), когда выполняют нагрузку
- iostat показывает 10мб/с обмен с жестким диском и кучу мелких операций
- транзакции почти все уже повыкидывал в особо узких местах
- когда глазами смотрю PROCESSLIST - там почти всегда пусто
- общую погоду портит где-то 1% запросов, которые исполняются медленно скорее всего из-за того, что база давно не читала какой-то файл и нужно его считать с диска
Из этого я делаю вывод - база мгновенно выдает ответ и сливает данные в ОС на запись, от чего в PROCESSLIST пусто, CPU почти нулевое, PHP ожидает ответа и т.д.
Некоторые базы работают хорошо, некоторые - тормозят (на них объективно подается нагрузка выше, процентов на 20-30%). На справляющихся с нагрузкой базах винч так же нагружен, но CPU mysql в районе 30-60%.
В табличках 30-150 тыщ записей. Несколько индексов. Только числовые поля. Видов таблиц - несколько, но все такие по простой структуре.
Применяю нетрадиционные методы, чтобы избегать лавинообразного накопления кол-ва запросов, когда база не справляется с какой-то из одной своих таблиц... Один крон мониторит со всех тачек SHOW PROCESSLIST и вырубает часть пользователей, которые читают тормозные таблицы. При срабатывании - новые запросы игнорируются, т.е. лавина не образуется. А спустя пару секунд, еще делается KILL всем тредам. Таких бывает очень мало и редко, но они могут завесить весь проект, пока над одной тормозной таблицей наконец не выполнятся все накопленные операции. У меня это не приводит к ошибкам, т.к. если крон не обработал запрос, то он уйдет обратно в очередь на отложенную обработку (естественно, тоже без вечного зацикливания).
SSD никак не катит. Как не настрой базу, она будет долбить винч множеством мелких запросов на всю катушку. С нашей загрузкой сдохнет через неделю, хотя и проблема seek time исчезнет как класс. Менять хостера не выгодно (а уж тем более покупать железо).
Во всех доках написано, что при innodb_flush_log_at_trx_commit=0 запись журнала идет примерно раз в секунду. И нигде не поднимался просто вопрос - а что делать, если мне надо еще реже? Я понимаю, уже и так выжали все, только жалко, что оно уперлось не в память или CPU, а в тормозной винч.