Как стать автором
Обновить

Комментарии 8

Все-таки хотелось бы задержаться на теории. Как связаны Task'и и Акторы? Почему Акторы делятся на 2 вида? На что отображаются такси и акторы: потоки, процессы, объекты a la Runnable? Предусмотрена ли персистентность всего вычислительного процесса? Сравните вашу модель вычислений с более известными: акторы Akka, сети Петри, Taverna workflow.
Задачи состоят из двух наборов данных. Первый это параметры вызова, включая ссылки на другие задачи если аргументы еще не известны координатору во время ее создания. Второй набор это дополнительные свойства задачи для сервера Taskurotta. Например — является ли она безопасной (нужно ли останавливать процесс в случае ошибки или можно ошибку передать координатору), время ее запуска (можно определить время запуска в будущем), дополнительные зависимости, таск лист (определяет уникальную очередь чтобы не все актеры данного типа ее схватили) и т.д. Как только задача готова для исполнения (пришло время старта и все параметры запуска известны), она помещается в очередь. Актер забирает задачу, выполняет и возвращает результат серверу. Актеры в отдельных JVM работают. В конфигурационном файле указывается их количество (количество потоков). Предусмотрена защита сервера от постоянной нагрузки если нет у него задач. Актеры снижают в этом случае интенсивность опроса в соответствии с заданными параметрами. Много тестовых процессов реализована в пакете recipes. Сейчас реализована модель опроса актерами сервера на предмет получения задач (как в SWF Амазона). Сервер явно держит соединения N секунд в случае отсутствия запрашиваемого типа задач в очереди. Есть возможность перейти от poll к push модели или вообще убрать транспорт и совместить актеров и логику серверов в одной JVM. Решение этих вопрос отодвинули. Пока нам более важен функционал и общая устойчивость системы для конкретных задач в реальных проектах. Задачи оптимизации тоже есть, но у нас есть железо на котором система хорошо масштабируется.

Персистентность заложена изначально. Мы намеренно поддерживаем несколько конфигураций развертывания чтобы держать внутреннюю архитектуру в тонусе. На данный момент это такие конфигурации сервера:
— все в памяти (для тестовых целей)
— сервера использует коллекции hazelcast для хранения данных и соответственно бэкапы на разных серверах (можно использовать там где памяти много и не большие требования к устойчивости)
— сервер использует hzelcast как кэш первого уровня а все данные всегда сбрасываются в mongodb. Чем больше памяти, тем шустрее система. Добавить другую БД не проблема. В основном у нас key-value потребности.
— тоже что и предыдущий вариант, но внутренний сервис процессов работает с БД oracle. Это сделано для наибольшей устойчивости. Когда клиент обращается к серверу с запросом создать процесс — мы синхронно пишем данные о нем в БД oracle и отдаем клиенту ответ когда все хорошо. Т.е. клиент уверен, что раз он запустил процесс, то он дойдет до конца рано или поздно. Упадет там монга со всеми данными, упадут ли сервера или все разом. мы должны восстановиться и в крайнем случае начать незавершенный процесс сначала.

Кроме того, можно любую конфигурацию запустить без транспорта. В этом случае в рамках JVM актеров будут работать серверные компонены, образовывать кластер, работать с БД и т.д.

Возвращаясь к вопросу — в конфигурациях с mongodb и mongodb+oracle мы имеем сохраненные данные по всем поставленным задачам и результатам их выполнения. Они доступны как в БД напрямую, так и через консоль. Их можно использовать как для анализа хода выполнения процесса, так и для регрессионного тестирования новых версий актеров по старым данным. Простой механизм запуска регрессионного тестирования в планах ближайших месяцев. Это актуальная для нас проблема.

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

Что касается сравнения. Сравнивать тяжело напрямую. Taskurotta позиционируется как координатор процессов высокого уровня, которая доведет процессы до конца несмотря на нестабильность окружающей среды (будет следить и перезапускать отдельные задачи или процессы целиком). На ней можно писать приложения с маленькими актерами, сильно их дробить. Но это не эффективно. Более правильная модель, когда Taskurotta поставит задачу актеру который запустит процесс выполнения на Akka, Vert-x или что-то начнет считаться на Hadoop. Из жизни — исполнители у нас проверяют ЭЦП, обращаются к внешним веб сервисам, занимаются транспортировкой файлов, т.е. они в основном взаимодействуют с внешними системами. Для себя мы выработали следующие критерии создания исполнителей (чтобы их не мельчить когда руки чешутся):
— Необходим больше чем одному процессу (желательно чтобы выполнял тяжелую работу).
— Необходимо горизонтальное распараллеливание выполнения задач.
— Взаимодействует с внешней средой (желательно чтобы была необходима политика повторений при сбое)

Что касается workflow систем. Тут процесс строится динамически способом близким к java стилю. И актеры легко масштабируются (особенно если делают тяжелую работу) — сколько надо, столько и поставил на сервера их. Taverna workflow не щупал. Когда-то работал с Bonita BPM. Сложилось мнение, что они тяготеют к тому чтобы вызывать по веб сервисам или иным способом внешние системы в соответствии с описанным процессом. Это приводит к деградации их производительности в случае если внешний сервис начинает работать медленно. Это минус чистого подхода пушить задачи на актеров. Если дать возможность актерам забирать задачи и спокойно выполнив регистрировать результат, то таких проблем нет. И в теории, можно написать координатора, который читает, например BPMN описание, имеет список исполнителей и раздает им задачи в соответствии с описанием.

По поводу деления актеров на два вида. По опыту создания распределенных процесов очень хочется концентрировать логику их управления в определенных местах. Это упрощает анализ и видение картины в целом когда система начинает сильно разрастаться. Это помогает держать Исполнителей настолько независимыми, на сколько это возможно. Иначе появляется соблазн вызвать одного исполнителя из другого и начать строить процесс через цепочки таких вызовов. Это не плохо, когда мы это делаем для увеличения производительности в vert.x например. Но на высоком уровне это мне кажется излишней гибкостью.
> Это не плохо, когда мы это делаем для увеличения производительности в vert.x например. Но на высоком уровне это мне кажется излишней гибкостью.

Тут подумалось, что это ограничение легко обходится. Можно строить систему из одних только координаторов в терминах Taskurotta. Тогда все актеры будут способны ставить задачи другим. Но мы сами не предполагаем использовать такой подход в разработке.

Данное ограничение можно вынести на уровень архитектурного надзора и договоренностей внутри команды.
Интересная библиотека, спасибо.

Присоединяюсь к вопросам заданным rfq в соседней ветке и дополняю своими:
— есть оценки производительности (пропускная способность очередей, накладные расходы на динамические прокси-объекты)
— не сталкивались ли вы с deadlock'ами в hazelcast (во второй версии была актуальная, но сложнодетектируемая проблема)
— какие части процесса сохраняются в БД (видел в проекте dbcp и spring-data-mongo)
— не планируете ли декларативную генерацию client proxy с кодогенерацией (чтобы не писать руками парные интерфейсы клиентов, использующих Promise)
— правильно ли я понимаю, что проект частично несовместим с java 7
По производительности сейчас система далеко не оптимальна. Например серилизация в JSON и обратно между актером и сервером. Актеры отдают результат на любой сервер, хотя правильней отдавать на тот, что владеет партицией в терминах hazelcast ибо все равно полученные данные будут отправлены на владельца. И т.д. Для нас сейчас важна масштабируемость и внутреняя модульность чтобы менять решения (например легко переехать с очередей hazelcast на rabbit если возникнет необходимость). Скорость измеряем в количестве задач в секунду. В это входит взять задачу с сервера, выполнить и отдать результат на сервер. Проводим тестирование различных конфигураций. Например конфигурация без БД а только hazelcast очень хорошо масштабируется. На моем ноутбуке 4 ядра i5 + SSD — 800 tps. А для сравнения на 32х ядерных серверах порядок примерно такой — на одном сервере 4-5 тысяч tps, а на 4х 12-14 тысяч tps. И то мы их недогрузили. Когда добавляем базу то сразу упираемся в ее возможности масштабирования. Например добавив одинокую монгу (без настроек и без node set) мы получим на тех-же серверах не более 900 tps. Оракл еще снизит скорость. Пока не проводили доскональный тюнинг и попытку выжать максимум. Железо еще не кончилось. Но полагаю что для двух серверов Taskurotta на двухъядерных процессорах в конфигурации с супер шустрыми и оптимизированными монгой и oracle будет не более 300 tps.

deadlock'и могут быть, да. Надо работать с ним аккуратно так как он выполняет все внутренние задачи асинхронно. В коде есть закомментаренный кусок приводящий к deadlock. С ним еще не разбирался досконально. Предположительно причина в том, что отдельный поток hazelcast использует спринг для инициализации компонент где есть синхронизация, а вызывая hazelcast в том месте мы сами находимся на стадии инициализации. Надо будет найти время для разбора. В обычной работе с deadlock не сталкивались.

В реально работающей системе у нас процесс сохраняется в oracle а все остальное в более шуструю но менее надежную монгу.

Планируем да, упростить процесс. Примерный набросок того как можно будет любой бин в существующей системе использовать как актер можно посмотреть тут: goo.gl/gW3ovI Ну и без спринга конечно будет. Спринг останется всегда производным существующих возможностей.

Что вы имеете ввиду? Работаем и запускаем на java 7. Из старого, в коде есть кусок для поддержки spring 2.5. Скоро его в отдельный проект переведем, как на пенсию.
уточнение

На моем ноутбуке 4 ядра i5 + SSD — 800 tps.

Это с монгой и без оракла.

А для сравнения на 32х ядерных серверах порядок примерно такой — на одном сервере 4-5 тысяч tps, а на 4х 12-14 тысяч tps.

Это чистый hazelcast — без монги и оракла.
Имел ввиду, что вы используете apache dbcp 1.4 для взаимодействия с oracle. Совсем недавно dbcp ещё не работал с java 7 (т. к. в 6 был JDBC4, а в 7 — JDBC4.1). issues.apache.org/jira/browse/DBCP-385

Обещают исправить в 2.0, но можно и самостоятельно пересобрать с патчем из jira.
Спасибо за информацию. Видимо мы не используем проблемные участки API и не сталкнулись с трудностями.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории