2 BE-узла, оба - на Spring Boot.
BE1 - вполне стандартен и через Spring Data (JPA/Hibernate) сохраняет записи в конкретную таблицу (или множество таблиц) в Postgres.
Работает через ORM.
BE2 - своей БД не имеет, связывается с внешней (от 3ьей стороны) БД Оракл с доступом на чтение и забирает те данные, которые ему прикажет фронт. Но ORM здесь нет, есть Dynamic MyBatis (работа на уровне recordset), поскольку есть требование в рантайме формировать нужный SQL запрос динамически (динамическими являются не только параметры, но и таблицы к которым обращаются - этакий генератор запросов там внутри) а-ля select table1.attribute1, table2.attribute2, .... From table1, table2, .... WHERE param1, param2, ... (подозреваю что не используется prepared statement из-за такой универсальности генератора запросов). BE-узлы друг друга по РЕСТ не видят, FE видит оба BE-узла.
FE отправляет запрос в BE2, он конвертируется из JSON-вида в SQL-вид этим самым генератором, отправляется в Оракл, возвращается результат отдается опять фронту. Фронт получив эту пачку данных отдает ее на сохранение в BE1, где она успешно сохраняется. Пачка даных (страница) составляет по дефолту 100 записей, далее процесс повторяется с новым запросом но уже с заказом следующей пачки данных.
Все это время FE показывается прогресс-бар пользователю сколько он пачек по 100 записей успел перегнать из BE2 в BE1.
Второй этап - сохранение в BE1 - занимает чуть менее секунды на отработку пачки из 100 записей (вполне константен) если судить по веб-консоли запроса. В оптимизации пока не нуждается.
Первый этап - выборка из BE2 - по замерам сильно зависит от выбираемых параметров фильтрации в генераторе запросов (это логично, поскольку зависит от того идексируемые ли атрибуты запрашиваются в параметрах фильтрации или неиндексируемые) растягивается от полсекунды до 7-8 секунд на пачку, но однако намного сильнее зависит от того какой суммарный объем записей нужно перегнать из BE2 в BE1 (от необходимого числа итераций по 100 записей).
По замерам - в минуту успевает перегнать 1500 записей (те 15 пачек по 100), усреднённое это 25 записей в сек (это суммарно оба этапа).
Если объемы данных большие (скажем 5 млн записей) - с учетом этой скорости - это 55 часов.
1) вопрос - не меняя архитектуры, есть ли способы ускорить второй этап?
- Вижу только такой - провести исследование на предмет оптимального размера пачки (скажем не 100, а 500 или 1000 записей за страницу) с целью снижения числа итераций.
- Потенциально еще - переделать как-то генератор запросов в сторону prepared statements, пожертвовав универсальностью (при возможности). Что-то еще?
2) если архитектуру таки позволят менять в перспективе - какие тогда есть варианты?
Например убрать взаимодействие FE - BE2 и заставить эти итерации по сигналу от FE делегировать на BE1 полностью, чтобы FE лишь заказывал загрузку данных, а их накапливание делалось в BE1, но тогда FE не сможет показывать прогресс по пачкам по ходу загрузки автоматом (только если не будет специально запрашивать этот прогресс с BE1).
Интересуют именно программные варианты к оптимизации (а не наращивание железа/добавление узлов).
Поделитесь своим опытом или идеями, пожалуйста. Заранее спасибо.
Если объемы данных большие (скажем 5 млн записей) - с учетом этой скорости - это 55 часов.... Привет. Каких результатов хотите добиться? Может от этого пойти? Какая цель оптимизации?
Вы пытаетесь в базе сделать поиск. Поэтому она тормозит. Поэтому берите поисковый движок и делайте поиск там где для него всё и делается. А фронт в перегонке данных никак не должен участвовать. Отчет о прогрессе делается элементарно записью текущего состояния операции в какое-нибудь хранилище, за которым клиент приходит раз в секунду.
Делать параллельно сразу несколько запросов к be2 не пробовали? Чтобы в каждом параллельном запросе приходила одна из пачек.
Про фронт понял, вполне доходчиво. А насчёт солр и иже с ними пока не думали. В любом случае этот подход потребует много времени и определенного плана. Спс за идею.
Несколько Аякс запросов? Или с фронта один а на бе2 несколько потоков? Можно да, но думаю это упрется в конечном итоге в количество сессий выделяемых из пула для сторонней бд. А учитывая то что такую процедуру могут запрашивать несколько пользователей одновременно мне кажется будет больше минусов чем плюсов.
Обсуждают сегодня