Upload
vadim-tsesko
View
1.197
Download
1
Embed Size (px)
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://[email protected]: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/@[email protected]
Вадим Цесько (Яндекс) 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