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

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

Embed Size (px)

DESCRIPTION

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

Citation preview

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

Akka в ЯндексJPoint 2014

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

@incubos

18 апреля 2014 г.

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

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

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

Предыстория

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

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

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

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

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

Содержание

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

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

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

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

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

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

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

Actor Model Actor

Actor

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

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

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

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

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

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

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

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

Реализации

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

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

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

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

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

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

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

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

Actor Model Akka

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

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

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

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

Actor Model Akka

Пути

Примерыakka://system/user/a/bakka.tcp://[email protected]:2552/user/a/b

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

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

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

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

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

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

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

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

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

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

Actor Model Akka

HOCON

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

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

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

Actor Model Akka

Диспетчеры

DispatcherPinnedDispatcherBalancingDispatcherCallingThreadDispatcher

наfork-join-executorthread-pool-executor

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

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

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

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

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

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

Actor Model Akka

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

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

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

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

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

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

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

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

Actor Model Akka

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

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

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

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

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

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

Actor Model Akka

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

1 Resume2 Restart3 Stop4 Escalate

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

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

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

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

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

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

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

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

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

Spray7

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

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

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

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

Конвейер

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Диагностика

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

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

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

Интересное

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

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

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

Специфика

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Проблемы Deadlocks

Deadlocks

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

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

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

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

Проблемы OOMs

OOMs

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

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

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

Проблемы Logging

Logging

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

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

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

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

Проблемы Dead Letters

Dead Letters

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

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

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

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

Проблемы Blocking

Blocking

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

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

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

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

Проблемы 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

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

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

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

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

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

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

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

Проблемы Akka

Akka

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

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

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

Проблемы Scala

Scala

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

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

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

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

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

Рассмотрели

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

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

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

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

В итоге

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

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

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

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

Ссылки«Потоковая обработка данных с помощью моделиакторов (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

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

Вопросы?

Вопросы?

http://incubos.org/contacts/@[email protected]

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

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

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