Skip to main content

Documentation

Многопоточный режим расчёта моделей

Стандартный процесс расчета моделей (файл mp_calc_models.php) — это непрерывный запрос списка инструментов (pair_id + tf), где последний обработанный бар (поле dandt в табл. mp_last_calc) отличается от последнего бара...

Section Documentation
Updated 12.07.2023

Многопоточный режим расчета моделей онлайн#

Переход от моно-режима расчета моделей к многопоточному#

Стандартный процесс расчета моделей (файл 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,

Multi scr1.png
Содержимое скрипта after_reboot.sh, который поднимает Flask-инстансы после перезагрузки

который осуществляется после (пере)загрузки из cron-файла /etc/cron.d/flask-restart.

Multi scr2.png
Cron-задача, которая запускает автоподнятие Flask-сервисов после загрузки сервера

Реализация параллельного расчета моделей (mp_multi_calc.php)#

Запуск расчета в параллельном режиме осуществляется путем многократного вызова процедуры (согласно количеству нейронок, указанных в тексте в mp_db_settings.php).

Multi scr3.png
Пример ручного запуска mp_multi_calc.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, где отражался только факт того, что данный процесс уже запущен - для избежания повторного запуска (что привело бы к ошибке в БД).

Multi scr4.png
Пример структуры таблицы mp_workers, через которую координируются воркеры

Основные параметры, с которыми работает воркер:

  • worker — номер воркера.
  • activity — статус деятельности: 0 — задача выполнена, 1 — идет расчет, 2 — ожидание новых баров.
  • pair — валютная пара, над которой ведется работа.
  • tf — выбранный таймфрейм.
  • info — дополнительная информация, связанная с текущим заданием.
  • started — время начала выполнения задания.
  • done — время окончания расчета.
  • locktime — время выполнения блокировки таблицы.

Помимо этих параметров, используются константы, определяющие частоту обновления записи и временной интервал, после которого программа считается аварийно завершившейся.

Алгоритм работы#

  1. Запуск: Блокируется таблица mp_workers для предотвращения конфликтов при работе с данными.
    Общая схема работы воркеров
  2. Проверка активных воркеров: Проверка какие воркеры в данный момент активны. У работающего воркера всегда в таблице есть запись с worker=<его номер> и activity=1(считаю) или 2(жду новых баров). Если все воркеры запущены, процедура прерывается. Если есть свободные воркеры, происходит запись с активностью=2 (в ожидании задания).
  3. Начало непрерывного цикла. Таблица разблокируется. Запускается запрос задач по циклу.
  4. Получение списка задач: Запросы выполняются и получается список того, что нужно посчитать.
  5. Назначение задачи: Таблица mp_worker блокируется снова, и находится первый финансовый инструмент, который еще не не в работе у воркеров. Задание принимается и отмечается начало работы над ним.
  6. Расчет: Таблица разблокируется, производится расчет задания.
  7. Завершение задания: Таблица снова блокируется, отмечается завершение работы над заданием и происходит запись «в ожидании задания».
  8. Повторение цикла: Идем на начало цикла – там, если задания не закончились сразу берем себе новое и т.д. В случае отсутствия новых заданий, статус activity=2 сохраняется, происходит задержка в 10 секунд и повторная проверка. Каждые 10 секунд (время сна настраивается в константах) происходит обновление записи (done=now()) чтобы можно было контролировать что воркер именно ждет а не вылетел, оставив после себя последнюю запись.
    Схема работы отдельного воркера

Примечания#

  • Цикл останавливается с помощью записи в корневой каталог файла с именем stop.!!!, как и для mp_calc_models.php.
  • В коде есть константа, определяющая, через какое время после начала выполнения задания считать, что программа не просто долго считает, а уже аварийно завершилась. Если при старте обнаруживается такой «вылетевший» воркер, запись о нем удаляется, и новый воркер стартует с тем же номером.
  • У каждого воркера при запуске открывается свой файл лога, а логирование ответов нейронок идет в общий файл nn_requests.log.
  • Для контроля работы воркера можно выполнить следующий SQL-запрос:
select * from mp_workers where activity > 0;
Тут видим, что все три воркера ждут новых баров и сколько времени ждут
Пример состояния, когда два воркера уже считают задачи: видно время старта и длину очереди; поле done = 2000-01-01 означает, что расчет еще не завершен
  • У каждого воркера при запуске открывается свой файл лога, а логирование ответов нейронок, как и раньше, ведется в общий файл nn_requests.log, который дополнительно режется на порции по 15 МБ.
Список лог-файлов

Continue Reading

Related Articles