Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
Каждый день по крону у меня запускается скрипт. В нем в цикле просто огромное количество запросов к базе данных, но все они довольно легкие.
Работает скрипт порядка 5 минут и обычно успешно завершается. База данных порядка 2.5ГБ и 20 млн записей
Но бывают дни, когда скрипт падает не выполнившись до конца, подскажите в какую сторону копать?

Смотрел работу  скрипта с помощью vmstat.
Начало скрипта:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b swpd free buff  cache si so  bi  bo in cs us sy id wa st
 0  0 0 213436 0 1341452  0  0  49  47  0  740  9  2 88  0  0

Середина скрипта:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b swpd free buff  cache si so  bi  bo in cs us sy id wa st
29  0 0 0 0 1412016  0  0  56  47  0  753 10  3 88  0

Видно, что заканчивается свободная память и увеличивается число процессов. Потом память постепенно появляется и снова уходит до нуля.

Оперативки всего 2ГБ
memory_limit = 1 ГБ
key_buffer_size = 512M

Я в правильном направлении? Дело ведь в памяти?
Александр Ф.
34 года, Россия
1828 сообщений
#10 месяцев назад
Да, думаю что оперативку до 4 гигов расширить бы как минимум. Кеша много.
Скорее всего памяти не хватает, а кеширование может привезти к длинным запросам в мускуле, если есть возможность просмотрите советы от MySQL: увеличить квоту-размер под кеш файлы, возможно еще что то, наверняка путем поправить именно настройки мускул сервера часть проблем решится.
Ну и может быть скрипт как то ограничить по потокам, чтобы выполнение было менее агрессивное.
P.S. Также важно посмотреть где хранится база, мы тут перешли на более быстрый sas диск, так оперативы стало кушать в разы меньше, если раньше все 64 гига забивалось, то сейчас больше 20-ки не поднимается... Быстрый отклик = нет потребности откладывать в кеш + паралельность процессов чтения записи. Ранее были сата диски = дохлая тема. Ну и на ссд если переставить базу то будет вовсе пуля.
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
regado, спасибо. Ого, у вас 64 ГБ оперативки?
Александр Ф.
34 года, Россия
1828 сообщений
#10 месяцев назад
Hungry_Hunter, Да ) Свой сервер, с виртуализацией на несколько операционок под разные задачи. Это максимум сколько поддерживает железо. Были планы поменять железо с оперативкой под ~ 90-120 гигов, но не получилось официально ввезти сервак в Россию. Потом разобрались с настройками и оказалось что текущий может полноценно проработать еще год, а то и больше.
Посмотрите также включено ли индексирование для бд.
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
regado, да, индексы все прописаны необходимые.
Алексей Хомич
33 года, Россия
22 сообщения
#10 месяцев назад
Hungry_Hunter,вы с ума сошли делать очень много запросов к базе данных в цикле? да тут ни один даже хороший сервер не справится с такой задачей. конечно падать будет. в цикле никогда не делается много запросов. нужно стараться одном запросом все делать. у меня даже если нужно выполнить 500 запросов,то я все пакую в один запрос. скрипт сделает запрос,база данных вернет массив. и уже в скрипте разбирай этот массив.
Сидоров Влад
34 года, Россия
623 сообщения
#10 месяцев назад
Если пролема неконсистентна, посмотрите, что еще происходит на сервера в это время.
Возможно, это совпадает с пиком посещаемости (если это тот же сервер) или другой фоновой задачей. (это  к вопросу увеличения числа процессов). не смотрели что за процессы?

может быть банальная утечка, потыкайте memory_get_usage перед концом цикла и явно вызывать gc.

nirubus09, 32 года - не время для юношеского максимализма.
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
nirubus09, одним запросом это выполнить невозможно, там идут сотни тысяч запросов.
inter-job, посещаемость в это время минимальна. Про утечку посмотрю, спасибо)
Алексей Хомич
33 года, Россия
22 сообщения
#10 месяцев назад
И даже невозможно оптимизировать эти запросы?
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
nirubus09, навряд ли.
Все что можно было сделать по оптимизации я уже сделал) Время выполнения запроса в среднем 0.002 сек
Роман Кузнецов
36 лет, Россия
9 сообщений
#10 месяцев назад
А что в цикле перебирается?
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
Собираются все совершенные сделки (порядка 20 тыс) и дальше в цикле идет обсчет по каждой, различные вычисления по ним с участием базы данных, сбор операций за последний месяц из таблиц, начисления, списания итд. В общем биллинг проходит ежедневный.
Роман Беляев
33 года, Украина
15310 сообщений
онлайн
#10 месяцев назад
Грубо разделить выполнение на несколько частей, запускать не один раз, а несколько, обрабатывая частями.
Смотреть в код и разбираться почему тупит
Елена Б.
34 года, Украина
6649 сообщений
#10 месяцев назад
Мне кажется, дело не в запросах к базе. Искать, где не убираются из памяти устаревшие (не нужные в текущей итерации) данные. Все, что можно, сохранять и забывать. 
Проверить, используюются ли везде оптимальные типы данных.  Все структуры, которые передаются, как аргументы, должны быть объектами или передаваться строго по ссылке, а те, что не передаются - оставлять массивами.
Стоит, также, использовать редиз или мемкеш, отправляя в него любые промежуточные данные (и сразу удаляя из оперативной памяти).  
Так, во-первых, использование памяти будет под контролем программиста, а во-вторых, в элементе перенесется в облако, если действительно уменьшить объем не удастся. 
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
Цитата (frig):
Грубо разделить выполнение на несколько частей, запускать не один раз, а несколько, обрабатывая частями.

Вот тоже об этом думал. Покрутил пока настройки сервера, если будет падать - придется делить.
floppox, а вот про чистку памяти от устаревших данных пхп-программисты привыкли не заботится (и я в том числе), ведь "php создан чтобы умирать". Пожалуй стоит об этом задуматься и попробовать чистить память по мере прохождения цикла. Благодарю за совет)
Елена Б.
34 года, Украина
6649 сообщений
#10 месяцев назад
Hungry_Hunter, добро пожаловать в мир консольных приложений
Пых форева. 
Сергей Н.
76 лет, Португалия
2 сообщения
#10 месяцев назад
А какую СУБД используете?

А если логику из php скрипта перенести в SQL? 
Сидоров Влад
34 года, Россия
623 сообщения
#10 месяцев назад
Цитата:
А какую СУБД используете?
А если логику из php скрипта перенести в SQL?
key_buffer_size настройка от mysql. (Кстати, посмотрите на кол-во блокировок)
Переносить логику, это отгрести несколько проблем вместо одной.
Сергей Н.
76 лет, Португалия
2 сообщения
#10 месяцев назад
Цитата (inter-job):
Переносить логику, это отгрести несколько проблем вместо одной.

Есть разные мнения по этому вопросу.  Но в общем все определяется целесообразностью и прочими нюансами. Не видя конкретных данных о текущей конфигурации м реализации можно только предполагать что будет лучше.
Артем Л.
32 года, Россия
10931 сообщение
#10 месяцев назад
SergeyND, MySQL MyISAM
inter-job, вот такие настройки в my.cnf стоят:
max_allowed_packet = 32M
query_cache_size=64M
key_buffer_size = 512M