Артем Л.
11416 сообщений
#4 года назад
Есть высоконагруженный проект, при большом количестве одновременных подключений (например 100 запросов в секунду) все начинает дико тормозить, страницы сайта открываются несколько минут. При этом нагрузка на сервер не превышает 0.5, а оперативная память используется на 25% только. Т.е. мощностей сервера еще с запасом.
Подозреваю что выстраивается очередь в БД. Как это все проверить, в какую сторону копать, какие параметры в настройках можно поправить? Хоть какие-то идеи. Сломал всю голову. Большое спасибо!
Поковырялся в настройках mysql, но особо ничего не помогло
Приложения:
  • 20 КБ
Давыдов М.
40 сообщений
#4 года назад
Ссылку в студию
Александр Ф.
3318 сообщений
#4 года назад
Смею предположить, что тормоза из-за дисковой системы. Дисковая система - слабое место, особенно там где вместо серверных ссд всякий шлак. Проверить просто - смотрите очередь по иопсам в статистике на накопители. Вы делаете запрос - требуется динамическая обработка с коннектом и запросами - выводами Базы Данных. А база находится на накопителе.
Еще можете взять часть рам и использовать ее под накопитель только базы данных. То есть вся база будет в оперативке. Тоже круто будет работать. (Но все упадет если внезапно отрубят электричество, поэтому бекапы наше все и как можно чаще)
Еще вопрос - используете ли марью дб или старый добрый мускул? Первая на последней стабильной версии дает ощутимый прирост... ну и если все плохо - то может закешировать все нафиг. Тогда кеш как статику будет пулять быстро, не будет лишних обращений к БД и не будет тормозов.
Артем Л.
11416 сообщений
#4 года назад
freelansonly, ссылка ничего не даст.

regado, спасибо. Диски стоят SSD.
Цитата (regado):
о есть вся база будет в оперативке.
Не вариант. Тут как раз идет на запись больше данных, чем отдается.

Цитата (regado):
используете ли марью дб или старый добрый мускул


  • Сервер: MySQL (Localhost via UNIX socket)
  • Тип сервера: MariaDB
  • Версия сервера: 5.5.64-MariaDB

Кеширование тоже не подходит, т.к. надо писать много данных. Проблема именно с записью.
Грубо говоря это парсер, собираются данные - отдаются пользователю, в БД пишется статистика.
Елена Б.
6863 сообщения
#4 года назад
Буквально на днях обнаружила просто дичайшую разницу между mysql и postgres.  Настолько ощутимую, что поверить трудно. На простом селекте с лимитом. Без условий. Без офсета. Просто select * from table limit 500.
Всего имелось 49 тыс. строк. 
Один нюанс. В таблице было поле jsonb. 
В общем, такой вот совет, меняйте нафиг мускул.
И рискну посоветовать очевидное: проверьте индексы вдольи поперек. Они тоже могут творить чудеса. 
Еще можно разделить реплики на чтение и запись. Могут всплыть нюансы с консистентностью и придется химичить в коде. Но иногда это вполне подходящий вариант. 
Алексей Ч.
15 сообщений
#4 года назад
Если много записей, может блокировки в базе? 
Процессы не нагружены, но ждут пока освободится ресурс.
Елена Б.
6863 сообщения
#4 года назад
Еще можно создавать таблицы для периодов времени. Запись в одну большую таблицу может сильно тормозить только из-за количества.
То-есть, создаем вместо table - table_2020_03 или даже table_2020_03_14, поправляем код, чтоб работал с этим хозяйством. Таблиц получается много, но быстрые. 
Так же, можно разделить таблицы по любому другому параметру, который похож на enum. Какой-нибудь тип, статус, город и т.д.
Артем Л.
11416 сообщений
#4 года назад
Цитата (alex_tche):
Процессы не нагружены, но ждут пока освободится ресурс.
Скорее всего это как раз и происходит.

floppox, есть операция обновления баланса при каждом запросе, она происходит путем UPDATE по user_id и дате а таблице содержащей 50 млн записей.
Но при апдейте одной записи это занимает очень мало времени, даже если умножить это число на 200.
Но как приходит 100-200 одновременных обращений то все висит и долго думает, но в итоге выполняется успешно.
Спасибо за советы, буду думать в этом направлении.

За одно обращение примерно происходит
select 7 шт
update 5 шт
insert 2 шт

Все ключи проверил и проставил, в основном по id идет выборка везде.
Александр Ф.
3318 сообщений
#4 года назад
Hungry_Hunter, актуальная марья 10.3 Обновите для начала ее.. Тут на веблансере есть Дима Шпак, обратитесь к нему, пропишет какой надо конфиг, обновит что надо и взлетит база.
Насчет того, что надо много на запись - тут как раз кеш от батарейки помогает. И насчет дисков тоже вопрос, что там за ссд - тоже немаловажно. При одновременном множестве запросов сата ссд могут быть слабоваты. нужны сас ссд. А еще лучше Fusion IODRIVE. поставил такой и просто космос.
P.S. Может быть еще продумать алгоритм записи и обращения к базе на программном уровне, на уровне архитектуры базы. Порой облегчение скрипта обращений к базам дает ощутимей перфоманс чем все тюнинги сервера вместе взятые.
Артем Л.
11416 сообщений
#4 года назад
regado, спасибо попробую. Чем может быть чревато обновление? Версии с 5 по 10 разница довольно ощутимая.
Может что-то поломаться?
Артем Л.
11416 сообщений
#4 года назад
Причем еще такой нюанс. Когда все висит, пробую сделать SELECT элементарный к таблице, которая там вообще не участвует и он тоже не может выполнится, висит пару минут прежде чем выполнится.
Алексей Ч.
15 сообщений
#4 года назад
Странно, может таблица всё-таки участвует. База InnoDB или ISAM? Погуглите просмотр информации по блокировкам MySQL (наизусть не помню, но что-то можно было увидеть)
Артем Л.
11416 сообщений
#4 года назад
alex_tche, точно не участвует. MyISAM. Спасибо посмотрю.
Алексей Ч.
15 сообщений
#4 года назад
Ну, в ISAM read и write операции, вроде как, блокируют друг  друга. 
Перепроверьте что таблица не используется, (создайте левую таблицу - проверьте на ней).
Если точно не используется, то вероятно копать в сторону параметра аля MAX_TABLE_LOCKS 
(не знаю такого и не нагуглил).
Впрочем для ISAM, это скорее всего параметр OS количество блокировок файлов.


Другие советы: 
а) максимально сократить время блокировки рабочих таблиц т.е.
CREATE TEMPORARY table tmp_table like work_table
INSERT INTO tmp_table  VALUES 
...
В конце INSERT INTO work_table SELECT * FROM tmp_table

б) переконвертить таблицы в INNODB 
Александр Ф.
3318 сообщений
#4 года назад
Цитата (alex_tche):
б) переконвертить таблицы в INNODB
ценное замечание. Там еще и конфиг под иннодб должен потом быть соответствующий. Но когда мы перешли на это - прирост был приличный. Я все же повторюсь - надо обращаться к спецу, потому что он решает проблему комплексно, понимая что за чем и где узкое место. Потом уже разобраться в этом самому. Потому как методом тыка такие вещи могут не сработать. Также в phpmyadmin есть советчик, можно посмотреть процессы в реальном времени и пораскинуть мозгами где какой надо кеш и размер страницы памяти и прочее.

Насчет перехода - да риск есть, ну для этого бекапится вся виртуальная машина и потом делаются обновы. Не получилось - откат и попытка обновиться пошагово.
Артем Л.
11416 сообщений
#4 года назад
Все ясно спасибо всем за советы, будем пробовать.
Сергей Глушко
834 сообщения
#4 года назад
Hungry_Hunter, не с пятой на десяткую, а с 5,6 на 5,7 mysql
мария это форк, версионность у нее своz, но в основе лежит mysql 5.7
Не чревато ничем с таким небольшим количеством запросов, даже если что то и будет, то поправить 5 сек

regado,  актуальная мария 10.4)

и вообще когда тупит mysql ресурсы жрутся безбожно, например нагрузка на CPU 1000% ну рам конечно должен быть слимитирован
а так как проблема такая что CPU не кушается, скорей всего дело в лимитах использования сервера mysql(а еще скорей всего зарезано все лимитами)
Александр Ф.
3318 сообщений
#4 года назад
Цитата (micros):
regado, актуальная мария 10.4)
Так то она официально стабильная и давно, но считаю что рановато ) Недаром в whm/cPanel марья 10.3 прописана
Андрей М.
295 сообщений
#4 года назад
Цитата (Hungry_Hunter):
UPDATE по user_id и дате а таблице содержащей 50 млн записей.
померяйте запросы по отдельности и вместе и прикинте насколько целесообразен такой подход исходя из собственного опыта. Можно конечно поискать волшебную конфигурацию сервера но скорее всего нужно переделывать схему бд и далее код.
Артем Л.
11416 сообщений
#4 года назад
andrew-projects, Померил. UPDATE по user_id и дате а таблице содержащей 50 млн записей занял 0.0171 сек.
Это самый тяжелый из всех запросов, которые участвуют.