Как ограничить потребление памяти для системы Akka.net?

У нас есть служба Windows, использующая Akka.net для обработки сообщений. В частности, у нас есть 10 идентичных частных очередей MSMQ и 10 участников-координаторов. Мы назначили каждому актеру обработку одной очереди и отправку сообщений о результатах 10 дочерним рабочим актерам (используя циклический маршрутизатор) для вставки в базу данных. По мере увеличения количества сообщений в приватной очереди дочерние акторы не успевают за ними. Потребление памяти растет так же быстро, как и количество отправляемых сообщений. У нас есть две проблемы:

  1. Как ограничить прирост памяти? Можем ли мы контролировать почтовый ящик дочернего актера, чтобы убедиться, что мы не перегружаем его.

  2. 1 актер-координатор создает 10 актеров-работников, так что всего у нас есть 100 актеров-детей. Это верно?


person Hai    schedule 29.04.2016    source источник


Ответы (1)


Я думаю, что проблема здесь не в потреблении памяти, а в самом подходе к рабочему процессу.

Из того, что вы говорите, я могу предположить, что вы извлекаете сообщения из MSMQ, немедленно пересылаете их рабочим, а затем извлекаете дополнительные данные, не дожидаясь, пока рабочие фактически закончат свою работу. Это традиционная проблема с потоком данных, основанным на проталкивании, без прикрепленного механизма обратного давления.

Самый простой способ решить эту проблему - изменить поток данных на модель на основе извлечения - в этом случае действующий координатор не будет пытаться извлекать данные из MSMQ, если только один из рабочих не уведомил его о том, что они закончили свою работу и ждут больше данных (в этом случае вам не нужно будет размещать их также за маршрутизатором). Уведомление может быть выражено как сообщение, отправляемое работником, когда он заканчивает обработку текущего сообщения. Недостатком этой модели является то, что у вас будут бездействующие работники, ожидающие выбора сообщений MSMQ.

Более продвинутые концепции включают модель, управляемую спросом (противодавление), в которой может использоваться буферизация сообщений, поэтому вы можете предварительно выбрать некоторое количество данных, а затем пополнить их во время их обработки. Кроме того, таким образом ни один рабочий не будет простаивать, ожидая, пока координатор выберет следующее сообщение из очереди. Подробнее об идее концепции противодавления можно прочитать здесь.

PS: Как только выйдет модуль Akka.Streams, вы получите встроенные механизмы, которые работают со встроенными принципами обратного давления.

person Bartosz Sypytkowski    schedule 30.04.2016