Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Никита Цуканов «Параллелизм и распределённые вычисления на акторах с Akka.NET»

Никита Цуканов «Параллелизм и распределённые вычисления на акторах с Akka.NET»

В современном мире уже нельзя писать код, который работает на одном компьютере на одном процессорном ядре и имеет монопольный доступ к данным. В своих приложениях мы обычно используем многопоточность для распараллеливания операций по ядрам и нескольким процессорам на сервере, а для взаимодействия между несколькими серверами различного рода RPC и REST протоколы. При этом использование данных инструментов влечёт за собой ряд трудноразрешимых проблем. Так, при написании многопоточного кода весьма проблематично безопасно и корректно организовать конкуррентный доступ к данным из разных потоков, избежать взаимных блокировок и ситуаций, когда по каким-то причинам два потока обращаются к одним и тем же данным, хотя этого при разработке системы не предполагалось. Классические же сценарии сетевого взаимодействия сильно страдают от того, что они либо не «прозрачны» при использовании и требуют дополнительной логики для преобразования запросов и ответов, либо скрывают за мнимой прозрачностью возможные подводные камни при сетевых ошибках или недоступности той стороны.
Главным же ограничением в использовании этих технологий является то, что для их внедрения необходимо существенным образом изменять имеющийся код. Вы не можете быстро «потушить» проблему, просто залив её дополнительными вычислительными мощностями, уходят часы, дни, недели на доработки кода. Акторная модель призвана избавить разработчика от мыслей о том, в каком потоке и на каком сервере выполняется код. Замена синхронных вызовов на обрабатываемые по одному синхронные сообщения позволяет писать код, одинаково хорошо работающий как в одном потоке, так и на сервере с несколькими процессорами, а механизм обеспечения сетевой прозрачности позволяет не видеть разницы между актором, запущенным локально и удалённо.
Доклад рассчитан на неподготовленного слушателя, ранее не имевшего дело с акторами, и является улучшенной и дополненной версией доклада с питерского DotNext. Речь пойдёт непосредственно об акторной модели и её реализации в Akka.NET, особенностях юнит-тестирования, акторах с сохраняемым состоянием, а так же об интеграции всей этой машинерии с имеющимся приложением и ASP.NET.

DotNetRu

August 11, 2016
Tweet

More Decks by DotNetRu

Other Decks in Programming

Transcript

  1. 2 1994 1995 1996 1997 1998 1999 2000 2001 2002

    2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 0 500 1000 1500 2000 2500 3000 3500 4000 0 10 20 30 40 50 60 70 1 1 1 1 1 1 1 1 1 2 2 4 4 8 8 16 16 32 32 64 200 300 400 500 1000 1800 2530 3200 3600 2200 2930 3000 3200 3330 3330 3150 3200 3150 3150 3150 Тактовая частота и количество ядер по годам Частота (МГц) Ядра
  2. 3

  3. 5

  4. 14 Это — единица организации программного кода Что такое Актор?

    ООП Поведение Состояние Синхронные* вызовы Акторы Поведение Состояние Асинхронные сообщения
  5. 15 Это — единица организации программного кода Что такое Актор?

    ООП Поведение Состояние Синхронные* вызовы Акторы Поведение Состояние Асинхронные сообщения Не нужно думать о: - разделяемом состоянии - видимости состояния - потоках, блокировках, конкурентных коллекциях, и т. п.
  6. 16 Thread Pool Actor 1 Actor 1 Actor 1 Actor

    1 Actor 2 Actor 2 Actor2 Actor2 Actor 3 Actor 3 Actor 4 Actor 4 Actor4 Actor4 Actor1 Actor1 Actor3 Actor3 Actor4 Actor4 Actor2 Actor2 Actor1 Actor1 Actor3 Actor3 Actor2 Actor2 Time • Акторы работают в фиксированном пуле потоков, равномерно распределяя нагрузку между ядрами, нет лишних переключений контекста. • Есть возможность управлять тем, где и как будет выполняться актор.
  7. 17 Актор можно использовать как... • поток • экземпляр объекта/компонента

    • колбек/подписчик • синглетон или сервис (например, слой работы с бд) • маршрутизатор, балансировщик, пул • сервис вне текущего процесса • конечный автомат
  8. 18 Модель акторов используют: • Erlang • Facebook WhatsApp (Erlang)

    • RabbitMQ (Erlang) • CouchDB (Erlang) • LinkedIn.com (JVM Akka) • Walmart.com (JVM Akka) • Blizzard (JVM Akka)
  9. 19 Анатомия актора ActorRef ActorRef ActorRef ActorRef Актор Актор Состояние

    Состояние Надзор Надзор Дочерние акторы Дочерние акторы Почтовый ящик Поведение Поведение Транспорт
  10. 21 public class GreetingActor : ReceiveActor { public class Greet

    { public string Who { get; private set; } public Greet(string who) { Who = who; } } public GreetingActor() { Receive<Greet>(greet => Console.WriteLine(greet.Who)); } }
  11. 23 var system = ActorSystem.Create("my-system"); var actorRef = system.ActorOf(Props.Create<GreetingActor>() .WithRouter(new

    RoundRobinPool(10)), "my-actor"); actorRef.Tell(new GreetingActor.Greet("World"));
  12. 24 var system = ActorSystem.Create("my-system"); var actorRef = system.ActorOf(Props.Create<GreetingActor>() .WithDeploy(new

    Deploy(new RemoteScope( Address.Parse("akka.tcp://[email protected]:6001")))), "my-actor"); actorRef.Tell(new GreetingActor.Greet("World"));
  13. 33

  14. 34

  15. 51 protected override SupervisorStrategy SupervisorStrategy() { return new OneForOneStrategy(5, new

    TimeSpan(0, 1, 0), e => e is ArithmeticException ? Directive.Resume : e is IOException ? Directive.Restart : Directive.Escalate); }
  16. 55 События Запросы Команды CQRS (Command/Query Request Separation) Потребитель (UI,

    слой API, etc) Доменная модель Модель для чтения База для чтения База для записи и работы доменной модели
  17. 68 Akka.Routing По контролю времени жизни: - Pool - Group

    По логике маршрутизации • RandomRouter • SmallestMailboxRouter • BroadcastRouter • RoundRobinRouter • ConsistentHashRouter • ScatterGatherFirstCompletedRouter • TailChoppingRouter
  18. 69 RoundRobinRouter 1 2 1 2 3 3 4 4

    Router Routee1 Routee2 Routee3
  19. 70 BroadcastRouter 1 2 1 2 1 2 1 2

    Router Routee2 Routee3 Routee1 Шлёт всем Шлёт всем
  20. 71 Routee1 Routee2 Routee3 ? ? ? ? Sender !

    Шлём всем, получаем первый ответ, отправляем запрашивающему (Task.WaitAny) Шлём всем, получаем первый ответ, отправляем запрашивающему (Task.WaitAny) ScatterGatherFirstComple tedRouter Router
  21. 80 Routee1 Routee2 Routee3 ? ? Sender ! Шлёт случайному,

    если не получает ответа, шлёт следующему Шлёт случайному, если не получает ответа, шлёт следующему TailChoppingRouter Router ? Routee1 Routee2 !
  22. 81 ConsistentHashRouter Z Y Z Y X A X A

    Router Routee1 Routee2 Routee3 Одинаковый «индекс хэша» Одинаковый «индекс хэша» «индекс хэша» привязан к актору «индекс хэша» привязан к актору