dmlogv
@dmlogv
Универсальный человек

Как распараллелить вычислительно Java-приложение на несколько машин?

Дано:
Некое вычислительное (не веб!) приложение на голом Java SE 8, расходующее в процессе работы около 500 Гб RAM и солидную часть ресурсов Intel Xeon E5-2*** и имеющее примерно такую, прости Господи, структуру:
«Структура» до
lnuo1ezfqxr6dxlsugeebwqfweg.png

Т. е. один могучий jar-ник запускается на Linux-сервере, тащит к себе комплект данных из БД, которые подвергает неким арифметическим экзекуциям (из которых часть параллелится совсем никак, часть — очень хорошо и сейчас разбита по Thread), и результат отправляется назад в базу.

Само собой, с этим веществом имеются некоторые проблемы:
  1. Слабая отказоустойчивость (что упало, то запускаем заново)
  2. Нулевая масштабируемость (варианты «накинуть памяти/процов» скоро перестанут срабатывать)
  3. Мониторинг только по логам либо — при дебаге — по запущенному VisualVM
  4. Управление только через параметры командной строки jar-ника и pkill


Хотелось бы завернуть это в некий сервер приложений, для управления контроля, балансировки, заодно распределив нагрузку параллельного этапа вычислений на n машин (где n > 1). В моих туманных представлениях новая абстрактная структура приложений должна выглядеть так:
«Структура» после
5lr9eonmg1_jx7qbzv-yb0vsgqm.png

где несчетное количество Slave — отдельные вычислительные машины, которым Master раздает данные (под вопросом. Вероятно, рабы сами могут их затягивать), распределяет нагрузку (если какая-то из машин уже досчитала, ей выдается еще что-нибудь), управляет отказоустойчивостью (один из хостов вышел покурить — перебрасываем его задание на более работающий), агрегирует данные из уже рассчитанных результатов и сбрасывает их в БД.

Но! Но оперативный гуглёж показал, что типичные серверы Java-приложений навроде Wildfly, GlassFish, WebSphere, WebLogic используются именно для обслуживания потребностей веб-приложений, а для числодробилок нужны монстры в стиле Hadoop, Ignite. Да? Или нет?

Что бы в таком случае применили вы?
  • Вопрос задан
  • 723 просмотра
Пригласить эксперта
Ответы на вопрос 3
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
Я бы как раз использовал Spark или Ignite, чтобы не изобретать велосипед.
Ответ написан
Комментировать
jamakasi666
@jamakasi666 Куратор тега Java
Просто IT'шник.
Я конечно не сталкивался на практике но много читал про решения подобных задач и вот пара мыслей:
1) Если все лежит в БД то почему бы не начинать параллелить именно с нее. Скажем в БД (возможно отдельной) метить кто забрал себе данные, дальше ноды цепляются к БД, берут пачку данных и метят что они уже в работе, т.е. нода 2 не возьмет данные которые уже на ноде 1. Это из простых решений в лоб.
2) Все последующие это реализациия в библиотеках, gridgain , штатный RMI, Apache Ignite, Apache River.
Ответ написан
Комментировать
@sandello
Как вариант — использовать AKKA. Оно есть и для скалы, и для Java. Там довольно просто "подключить несколько машин". Но собственно распараллеливание, перевод приложение на другую концепцию (асинхронный обмен сообщениями вместо прямого вызова) — это придется голову поломать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы