Многопоточный режим расчета моделей онлайн#
Переход от моно-режима расчета моделей к многопоточному#
Стандартный процесс расчета моделей (файл mp_calc_models.php) — это непрерывный запрос списка инструментов (pair_id + tf), где последний обработанный бар (поле dandt в табл. mp_last_calc) отличается от последнего бара в чарте (табл. mp_charts), и последовательное выполнение обработки выбранных инструментов. Примерно 95% времени занимает ожидание ответа от сервера с нейронными сетями и отправка сообщений в Telegram (если включено). Во время расчета не используются все ресурсы процессора - работает только одно ядро.
Целью внедрения многопоточного режима является увеличение скорости обработки за счет 1) создания нескольких «серверов нейронок», работающих независимо и 2) запуска нескольких процессов расчета моделей, где обработка различных инструментов производится параллельно.
Реализованные задачи#
- Запустить несколько экземпляров процесса Flask (несколько копий на одном сервере Linux, с возможностью добавления серверов по мере необходимости).
- Разработать новую версию процедуры mp_multi_calc.php (вместо mp_calc_models.php), которая позволяет многократно запускать саму себя (согласно количеству адресов серверов нейронных сетей, указанных в процедуре), обеспечивая тем самым параллельный расчет моделей по различным инструментам. Каждый запущенный экземпляр данной процедуры обозначается термином "воркер".
Реализация масштабирования серверов нейронок#
Выбрано решение запуска нескольких копий (инстансов) процесса Flask на сервере Ubuntu, каждый из которых работает на своем порту. Для каждого пользователя ("воркера") выделяется свой персональный адрес Flask, так как стандартный Flask не может одновременно обрабатывать несколько запросов.
В результате экспериментов с параллельным запуском 3 копий на разных портах (:5000,:5001,:5002) одного сервера, время ответа при полной загрузке всех трех незначительно увеличивается (приблизительно на 20-25%).
В данный момент запущены 3 Flask-инстанса для marketpawns на портах 5000, 5001 и 5002,
а также 3 Flask-инстанса mpawns.com на портах 5004, 5005 и 5006 и 1 Flask на порту 5003
(для четвертой нейронки).
Автоматический запуск трех копий Flask происходит в командном файле /root/mpawn_flask/after_reboot.sh,
который осуществляется после (пере)загрузки из cron-файла /etc/cron.d/flask-restart.
Реализация параллельного расчета моделей (mp_multi_calc.php)#
Запуск расчета в параллельном режиме осуществляется путем многократного вызова процедуры (согласно количеству нейронок, указанных в тексте в mp_db_settings.php).
При последующих запусках процедуры, она будет завершаться с сообщением о том, что все воркеры уже работают.
Запуск в настоящий момент происходит через трехкратный запрос из браузера:
https://marketpawns.com/mp_multi_calc.php
В дальнейшем можно сделать и вариант автоматического запуска при перезапуске
сервера, аналогично серверу с нейронками.
Для корректной работы воркеров необходимо уточнить настройки в файле /etc/php/8.1/fpm/pool.d/www.conf. В данный момент установлены параметры:
- pm.max_children = 32
- pm.start_servers = 8
- pm.max_spare_servers = 8
Описание воркеров#
Синхронизация (диспетчеризация) задач осуществляется блокировкой таблицы mp_workers в момент поиска воркером новой задачи и в момент фиксации выполнения задачи. Эта таблица представляет собой продвинутую версию mp_flags, где отражался только факт того, что данный процесс уже запущен - для избежания повторного запуска (что привело бы к ошибке в БД).
Основные параметры, с которыми работает воркер:
- worker — номер воркера.
- activity — статус деятельности:
0— задача выполнена,1— идет расчет,2— ожидание новых баров. - pair — валютная пара, над которой ведется работа.
- tf — выбранный таймфрейм.
- info — дополнительная информация, связанная с текущим заданием.
- started — время начала выполнения задания.
- done — время окончания расчета.
- locktime — время выполнения блокировки таблицы.
Помимо этих параметров, используются константы, определяющие частоту обновления записи и временной интервал, после которого программа считается аварийно завершившейся.
Алгоритм работы#
- Запуск: Блокируется таблица mp_workers для предотвращения конфликтов при работе с данными.
- Проверка активных воркеров: Проверка какие воркеры в данный момент активны. У работающего воркера всегда в таблице есть запись с worker=<его номер> и activity=1(считаю) или 2(жду новых баров). Если все воркеры запущены, процедура прерывается. Если есть свободные воркеры, происходит запись с активностью=2 (в ожидании задания).
- Начало непрерывного цикла. Таблица разблокируется. Запускается запрос задач по циклу.
- Получение списка задач: Запросы выполняются и получается список того, что нужно посчитать.
- Назначение задачи: Таблица mp_worker блокируется снова, и находится первый финансовый инструмент, который еще не не в работе у воркеров. Задание принимается и отмечается начало работы над ним.
- Расчет: Таблица разблокируется, производится расчет задания.
- Завершение задания: Таблица снова блокируется, отмечается завершение работы над заданием и происходит запись «в ожидании задания».
- Повторение цикла: Идем на начало цикла – там, если задания не закончились сразу берем себе новое и т.д. В случае отсутствия новых заданий, статус activity=2 сохраняется, происходит задержка в 10 секунд и повторная проверка. Каждые 10 секунд (время сна настраивается в константах) происходит обновление записи (done=now()) чтобы можно было контролировать что воркер именно ждет а не вылетел, оставив после себя последнюю запись.
Примечания#
- Цикл останавливается с помощью записи в корневой каталог файла с именем
stop.!!!, как и дляmp_calc_models.php. - В коде есть константа, определяющая, через какое время после начала выполнения задания считать, что программа не просто долго считает, а уже аварийно завершилась. Если при старте обнаруживается такой «вылетевший» воркер, запись о нем удаляется, и новый воркер стартует с тем же номером.
- У каждого воркера при запуске открывается свой файл лога, а логирование ответов нейронок идет в общий файл
nn_requests.log. - Для контроля работы воркера можно выполнить следующий SQL-запрос:
select * from mp_workers where activity > 0;
- У каждого воркера при запуске открывается свой файл лога, а логирование ответов нейронок, как и раньше, ведется в общий файл
nn_requests.log, который дополнительно режется на порции по 15 МБ.









