Артем Л.
11416 сообщений
#6 лет назад
Каждый день по крону у меня запускается скрипт. В нем в цикле просто огромное количество запросов к базе данных, но все они довольно легкие.
Работает скрипт порядка 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

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

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

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

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

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

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