Фреймворк Akka и его использование в Яндексе

Preview:

DESCRIPTION

Доклад с JPoint 2014 (http://javapoint.ru). Краткое содержание: * Actor Model на примере Akka * Происхождение * Концепции и API * Примеры кода * Примеры систем в Яндекс * Конвейерная обработка данных * Реактивные иерархические системы * Опыт разработки и эксплуатации * Подводные камни * Проблемы и некоторые решения * Дополнительные тулы

Citation preview

Akka в ЯндексJPoint 2014

Вадим Цеськоhttp://incubos.org

@incubos

18 апреля 2014 г.

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 1 / 55

Введение Предыстория

Предыстория

2 года назадСм. доклад «Потоковая обработка данных с помощьюмодели акторов (Actor Model)» на ADD-3a

ahttp://addconf.ru/talk.sdf/add/add_3/talks/12823

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 2 / 55

Введение Содержание

Содержание

Actor Model на примере AkkaПроисхождениеКонцепции и APIПримеры кода

Примеры систем в ЯндексКонвейерная обработка данныхРеактивные иерархические системы

Опыт разработки и эксплуатацииПодводные камниПроблемы и некоторые решенияДополнительные тулы

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 3 / 55

Actor Model Происхождение

Происхождение

Carl Hewitt1, Peter Bishop and Richard Steiger. AUniversal Modular Actor Formalism for ArtificialIntelligence. 1973.Gul Agha. Actors: A Model of ConcurrentComputation in Distributed Systems. 1986.Изначально для описания параллельныхвычисленийПозднее в качестве основы для многочисленныхреализаций

1http://letitcrash.com/post/20964174345/carl-hewitt-explains-the-essence-of-the-actor

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 4 / 55

Actor Model Actor

Actor

Всё это акторФункционируют параллельноАсинхронно обмениваются сообщениямиПри обработке сообщения актор может

отправить конечное число сообщений другим акторамсоздать конечное число новых акторовназначить поведение для обработки следующегосообщения

Порядок доставки сообщений не специфицированАкторы имеют «адреса»

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 5 / 55

Actor Model Concurrency vs Parallelism

Concurrency vs Parallelism

Actor Model не про Parallelism, а про Concurrency2

ConcurrencyСпособность выполняться параллельно.

ParallelismДействительно параллельное выполнение.

2Rob Pike. Concurrency is not Parallelism:https://player.vimeo.com/video/49718712

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 6 / 55

Actor Model Реализации

Реализации

Языки3 с «родной» поддержкой: Erlang, Scala, ...Библиотеки для языков: Scala, Java, F#, ...

Будем рассматриватьAkka (Scala API).

3http://en.wikipedia.org/wiki/Actor_modelВадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 7 / 55

Actor Model Akka

О проекте

Jonas Boner:Java ChampionTerracotta JVM clustering, JRockit JVM,AspectWerkz AOP, Eclipse AspectJ

Ресурсы:http://akka.io/docs/http://letitcrash.com/

Код:https://github.com/akka/akkaApache V2 license

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 8 / 55

Actor Model Akka

Производительность

ВниманиеСинтетические тесты ,

Erlang R14B04 vs Akka 2.0-SNAPSHOT4:1M mps vs 2.1M mps

Akka 2.05:50M mps48-core, 128 GB, ForkJoinPool

4http://letitcrash.com/post/14783691760/akka-vs-erlang5http://letitcrash.com/post/20397701710/

50-million-messages-per-second-on-a-single-machineВадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 9 / 55

Actor Model Akka

Особенности реализации

300 байт на акторАктор: состояние, поведение, почтовый ящик,список детей, стратегия супервизораМножество акторов на множестве нитейНет гарантированной доставки, семантикаat-most-once, порядок сохраняетсяСообщения обрабатываются строго по порядкуИерархия: создаваемые акторы — дети,родитель — супервизорАктор скрыт за переносимой ActorRefПодход «Let it crash»

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 10 / 55

Actor Model Akka

Пути

Примерыakka://system/user/a/bakka.tcp://system@server.yandex.ru:2552/user/a/b

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 11 / 55

Actor Model Akka

Конструирование ссылок

Создание акторов: ActorRefProvider.actorOfПоиск акторов:ActorRefProvider.actorSelectionКаждый актор знает себя, родителя и детей

Можно делать так:1 context.actorSelection("../brother") ! msg2 context.actorSelection("/user/service") ! msg3 context.actorSelection("../*") ! msg

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 12 / 55

Actor Model Akka

Определение актора

1 class Partitioner(partitionStorage: ActorRef) extends Actor {2

3 def receive = {4 case PartitionFeed(partner, offers) =>5 partition(partner, offers)6 case msg =>7 log.error("Unsupported message received: {}", msg)8 }9

10 def partition(partner: Partner, offers: Traversable[Offer]) {11 ...12

13 partitionStorage ! UpdatePartitions(partner, partitioning)14 }15 }

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 13 / 55

Actor Model Akka

Создание актора

1 val system = ActorSystem("sharder")2

3 val partitionStorage = ...4

5 val partitioner =6 system.actorOf(7 FromConfig.props(8 Props[Partitioner](new Partitioner(partitionStorage))9 .withDispatcher("dispatcher.cpu")),

10 "partitioner")

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 14 / 55

Actor Model Akka

Конфигурация диспетчера

Конфигурация в HOCON6:1 dispatchers.cpu {2 type = Dispatcher3 executor = "fork-join-executor"4

5 fork-join-executor {6 parallelism-min = 47 parallelism-factor = 1.08 }9 }

6Human-Optimized Config Object Notation:https://github.com/typesafehub/config

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 15 / 55

Actor Model Akka

HOCON

Независимая самоценная библиотека:Чистая Java без зависимостейПоддерживает Java properties и JSON supersetMerge и include из файлов, URL, classpathМощная поддержка вложенностиПоддержка duration (10 seconds) и size (512K)Конвертация типов

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 16 / 55

Actor Model Akka

Диспетчеры

DispatcherPinnedDispatcherBalancingDispatcherCallingThreadDispatcher

наfork-join-executorthread-pool-executor

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 17 / 55

Actor Model Akka

Почтовые ящики

UnboundedMailboxBoundedMailboxUnboundedPriorityMailboxBoundedPriorityMailbox

1 trait MessageQueue {2 def enqueue(receiver: ActorRef, handle: Envelope): Unit3 def dequeue(): Envelope4 def numberOfMessages: Int5 def hasMessages: Boolean6 def cleanUp(owner: ActorRef, deadLetters: MessageQueue): Unit7 }

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 18 / 55

Actor Model Akka

Пулы акторов

1 akka.actor.deployment {2 /partitioner {3 router = smallest-mailbox-pool4 nr-of-instances = 45 }6 }

1 akka.actor.deployment {2 /unifier {3 router = round-robin-pool4 resizer {5 lower-bound = 26 upper-bound = 167 }8 }9 }

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 19 / 55

Actor Model Akka

Типы роутеров

Реализации Pool и Group:RoundRobinRandomSmallestMailboxBroadcastScatterGatherFirstCompletedСамописные

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 20 / 55

Actor Model Akka

Конфигурирование из кода

1 val shardActorPaths: immutable.Seq[String] = ...2

3 val shard = system.actorOf(4 RoundRobinGroup(shardActorPaths).props(),5 "shard")

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 21 / 55

Actor Model Akka

Удалённые акторы

1 akka {2 actor {3 provider = "akka.remote.RemoteActorRefProvider"4 }5

6 remote {7 enabled-transports = ["akka.remote.netty.tcp"]8

9 netty.tcp {10 hostname = "server.yandex.ru"11 port = 255312 }13 }14 }

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 22 / 55

Actor Model Akka

Тестирование акторов

Модульное тестирование с TestActorRefИнтеграционное тестирование с ProbeПроверки с сопоставлением по шаблону

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 23 / 55

Actor Model Akka

Пример теста

1 val probe = TestProbe()2 val burstScaler = TestActorRef(new BurstScaler(probe.ref))3

4 before {5 burstScaler.underlyingActor.sent =6 burstScaler.underlyingActor.sent.empty7 }8

9 "A BurstScaler" should {10 "always forward the first message" in {11 probe.within(1 second) {12 burstScaler ! 113 probe.expectMsg(1)14 }15 }16 }

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 24 / 55

Actor Model Akka

СупервизорРешение при сбое:

1 Resume2 Restart3 Stop4 Escalate

Принятое решение (1-3) действует рекурсивноФункция Exception ⇒ DirectiveTerminated, preStart, preRestart, postStop,postRestartOneForOneStrategy и AllForOneStrategyОграничение количества перезапусков

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 25 / 55

Actor Model Akka

Супервизор по умолчанию

1 final val defaultDecider: Decider = {2 case _: ActorInitializationException => Stop3 case _: ActorKilledException => Stop4 case _: DeathPactException => Stop5 case _: Exception => Restart6 }7

8 final val defaultStrategy: SupervisorStrategy =9 OneForOneStrategy()(defaultDecider)

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 26 / 55

Системы Классификация

Классификация

Конвейерная индексацияЯндекс.{Авто, Недвижимость, Работа}etc.

Иерархическая обработка пользовательскихзапросов

Spray7

Маршрутизация и обработка кликов и показовМатчинг объявлений на подпискиetc.

7http://spray.ioВадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 27 / 55

Системы Конвейер

Конвейер

МасштабируемостьУстойчивость к сбоямОграниченные очередиBack pressureВыделенные диспетчерыДетерминированноепотребление памятиГрафики размеров очередейДекомпозиция стадийМасштабирование пуламиЗагрузка CPU 100%

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 28 / 55

Системы Конвейер

Яндекс.Авто: Архитектура

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 29 / 55

Системы Конвейер

Яндекс.Авто: Гиперконвейер

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 30 / 55

Системы Конвейер

Яндекс.Авто: Цифры

4 ДЦ, 4 машины для индексации, 60 машиндля поиска (общие для разных сервисов)Больше 2М объявленийВремя в конвейере — до 5 минПринудительная переиндексация — каждые15 минОбъём поискового индекса — больше 2 ГБScala — 8 KLOC, Java — 210 KLOC

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 31 / 55

Системы Конвейер

Инструментированные очередиMetrics8 + Graphite:

8http://metrics.codahale.com/Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 32 / 55

Системы Конвейер

Диагностика

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 33 / 55

Системы Конвейер

Интересное

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 34 / 55

Системы Конвейер

Специфика

Для прореживания потока задач:BurstScalerInstrumentedUnboundedSkipClonesMailboxInstrumentedSkippingBoundedMailbox

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 35 / 55

Системы Конвейер

Горизонтальное масштабирование (1)

Планировали масштабировать индексацию так:Добавляем машины-indexer’ыИспользуем RoundRobin- или Random-пул

Не работаетОдна из машин патологически тупит — сильнотормозит весь конвейер

AdaptiveBalancerИзмеряем время пропихивания данных и штрафуем нанекоторое время втупливающие ноды

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 36 / 55

Системы Конвейер

Горизонтальное масштабирование (2)Обновление данных на поисковых машинах:

Несколько ДЦ + ненадёжная сеть

ЭволюцияBroadcastPoolZeroMQ (EPGM, TCP)JGroups (Multicast + Relay)

Akka-based Spanning TreeДоставляем хотя бы одной ноде в каждом ДЦНода распространяет данные внутри ДЦВсё на akka-remote + ZooKeeperТюнинг и патчинг akka-remote

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 37 / 55

Системы Иерархическая обработка

Иерархическая обработка

МасштабируемостьВысокая доступностьЕстественные подсистемыЧасто динамическаятопологияActor per requestRequest-reply

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 38 / 55

Системы Иерархическая обработка

Иерархические системы

Внутренние сервисыИерархия акторов для каждого активногопользователя/подписки/визита/запросаДинамическая выгрузка/подгрузка сущностейРаспределение пользователей на бакеты (и ноды)через ZooKeeper + Curator9 (Consistent Hashing10)

9http://curator.apache.org10http://en.wikipedia.org/wiki/Consistent_hashingВадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 39 / 55

Системы Иерархическая обработка

Компонент сервиса уведомлений

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 40 / 55

Системы Иерархическая обработка

О чём нужно думать

НаблюдаемостьЛоггированиеАгрегатные графикиМониторинги

Поведение при перегрузкеДетектирование перегрузкиОграничение ресурсовПревентивный rejectВосстановление после перегрузкиВыравнивание нагрузки

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 41 / 55

Проблемы Deadlocks

Deadlocks

Ограниченные ресурсы:ОчередиДиспетчерыПулы нитей (в т. ч. в akka-remote)Косвенная синхронизация между акторами

Типы:ЛокальныеРаспределённые

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 42 / 55

Проблемы OOMs

OOMs

Возможные причины:Перегрузка + неограниченные очередиЛогические утечки памяти (в т. ч. череззамыкания, см. ActorContext.sender)

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 43 / 55

Проблемы Logging

Logging

ActorLoggingSlf4jLogger (Logback) vs akka.loglevelПерегрузка EventBusOOM

РешениеИспользовать slf4j-api напрямуюОбёртки для наполнения MDC спецификой Akka

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 44 / 55

Проблемы Dead Letters

Dead Letters

ВниманиеВ любой непонятной ситуации сообщение пойдёт вDeadLetter

РекомендацияПодписываться на DeadLetter, логгировать,вылавливать и мониторить «интересные» сообщения

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 45 / 55

Проблемы Blocking

Blocking

Актор на время обработки сообщения берёт ниткуиз диспетчераThread starvation при блокировании в актореОсобенно «интересные» результаты наdefault-dispatcher

РекомендацияЗапускайте блокирующихся акторов на собственномвыделенном диспетчере

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 46 / 55

Проблемы Akka и JMM

Akka и JMM

Happens beforeMessage send happens before receiveActor receive happens before previous receive

Следствия:Не нужно защищать состояние актораВозможны гонки на изменяемых сообщенияхИспользуйте неизменяемые структуры данных11

11Chris Okasaki. Purely Functional Data Structures. 1999.http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 47 / 55

Проблемы Наблюдаемось

Наблюдаемось

Статическая топологияНикаких проблем

Динамическая топологияПока только с привлечением мозга

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 48 / 55

Проблемы Akka

Akka

Бинарная несовместимость на пустом местеAPI иногда колбасит (диспетчеры и очереди)До многих вещей не дотянуться — приходитсякопипастить и патчить

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 49 / 55

Проблемы Scala

Scala

spray-routing (shapeless) крепкий орешек дляIDEAClosures (call-by-name, laziness) — утечки памяти,гонки и гейзенбаги

Незащищённое состояние актораВ т. ч. sender()

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 50 / 55

Заключение Рассмотрели

Рассмотрели

Actor Model в реализации AkkaКонвейерные и иерархические системы на AkkaНекоторые проблемы и решения

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 51 / 55

Заключение В итоге

В итоге

Прошли путь от Akka 1.x до 2.3.x1.5 года в productionМножество граблей, но жить можноИсключительно простой и выразительныйформализмУдобно проектировать, разрабатывать итестировать

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 52 / 55

Заключение Ссылки

Ссылки«Потоковая обработка данных с помощью моделиакторов (Actor Model)» на ADD-312

Typesafe Activator13

Principles of Reactive Programming14Книги:

Jamie Allen. Effective Akka. 2013Derek Wyatt. Akka Concurrency. 2013Series: The Neophyte’s Guide to Scala15

EAI Patterns Series16

12http://addconf.ru/talk.sdf/add/add_3/talks/1282313http://typesafe.com/activator14https://class.coursera.org/reactive-001/class15http://letitcrash.com/post/64667109914/

series-the-neophytes-guide-to-scala16http://letitcrash.com/post/59190266995/

eai-patterns-series-by-vaughnvernonВадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 53 / 55

Вопросы?

Вопросы?

http://incubos.org/contacts/@incubosvadim.tsesko@gmail.com

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 54 / 55

Alan Kay on OOP, 1967

Alan Kay on OOP, 1967

I thought of objects being like biological cells and/orindividual computers on a network, only able tocommunicate with messages (so messaging came at thevery beginning – it took a while to see how to domessaging in a programming language efficiently enoughto be useful).OOP to me means only messaging, local retention andprotection and hiding of state-process, and extremelate-binding of all things. It can be done in Smalltalk andin LISP. There are possibly other systems in which this ispossible, but I’m not aware of them.

Вадим Цесько (Яндекс) Akka в Яндекс 18 апреля 2014 г. 55 / 55

Recommended