77
Scala и Akka Степан Каменцев Распределенная обработка миллионов документов на

DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Embed Size (px)

Citation preview

Page 1: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Scala и AkkaСтепан Каменцев

Распределенная обработка миллионов документов на

Page 2: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

План

1. Анализ текстовых коллекций2. Коротко об Akka3. Шаблон Distributed Workers4. Примеры реализации

Page 3: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Что мы делаем?

Page 4: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

В начале был хаос!

Page 5: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

структурируем

тегируем

собираем статистику

реализуем поиск

представляем инструменты для

анализа

Page 6: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Как мы это делаем?

Page 7: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 8: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 9: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 10: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 11: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 12: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 13: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 14: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Мотивация перехода на Akka

Page 15: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 16: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

type Receive = PartialFunction[Any, Unit]

trait Actor {

def receive: Receive = ???

...

}

Page 17: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class TimeActor extends Actor {

def receive = {

case "Который час?" =>

sender ! System.currentTimeMillis()

}

}

Page 18: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object SomeApp extends App {

val system = ActorSystem("someSystem")

val path = "akka.tcp://sys@host:2552/user/time"

val timeActor = system.actorSelection(path)

timeActor ? "Который час?" onSuccess {

case time => println(time)

}

}

Page 20: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Distributed workers

Page 21: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Распределенные рабы

Page 22: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 23: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Требования к системе

1. Динамическое добавление рабочих узлов2. Динамическое добавление клиентов3. Отсутствие дополнительных настроек4. Возможность использовать тысячи узлов5. При падении сети, мастера, рабочего

узла данные не должны теряться

Page 24: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 25: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 26: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object WorkerToMaster { case object RegisterWorker}

object MasterToWorker { case object WorkerRegistered}

Page 27: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Worker(master: ActorRef) extends Actor {

import context.dispatcher

context.system.scheduler.scheduleOnce(0.seconds, self, RegisterWorker)

def receive = registration

def registration: Receive = { case RegisterWorker => context.setReceiveTimeout(5.seconds) context.become(waitForRegistration) master ! RegisterWorker } }

Page 28: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Worker(master: ActorRef) extends Actor {

import context.dispatcher

... ...

def waitForRegistration: Receive = { case WorkerRegistered => context.setReceiveTimeout(Duration.Undefined) context.become(idle) case ReceiveTimeout => master ! RegisterWorker } }

Page 29: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Master extends Actor { private object clients {...} private object workers { val workerToStatus = mutable.Map.empty[ActorRef, WorkerStatus] } def receive = { case RegisterWorker => val worker = sender() worker ! WorkerRegistered if (clients.isTaskAvailable) { worker ! TasksIsReady } workers.workerToStatus(worker) = Idle}}

Page 30: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 31: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 32: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 33: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 34: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 35: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Ну, граждане алкоголики, хулиганы, тунеядцы... Кто хочет сегодня поработать?

Page 36: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 37: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Песчаный карьер - два человека. Я!

Page 38: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 39: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Worker(master: ActorRef) extends Actor { private def taskExecutorPropsFor(task: Task) = Props( task match { case _: MystemTask => classOf[MystemExecutor] case _: NgramTask => classOf[NgramExecutor] // ... }) def idle: Receive = { case task: Task => context.become(working) val taskExecutor = context.actorOf(taskExecutorPropsFor(task)) taskExecutor ! task currentExecutor = Some(taskExecutor)}}

Page 40: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 41: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 42: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 43: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 44: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 45: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 46: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Отказоустойчивость

Page 47: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Worker(master: ActorRef) extends Actor {

private var currentExecutor: Option[ActorRef] = None private def interrupt() = currentExecutor.foreach { ref => ref ! PoisonPill currentExecutor = None master ! TaskFailed }

override def supervisorStrategy = OneForOneStrategy() { //... case _: Exception => interrupt() context.become(idle) Restart}}

Page 48: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

class Master extends Actor { override def preStart() { context.system.eventStream.subscribe( self, classOf[OnDisassociated]) } def receive = { case OnDisassociated(localAddress, remoteAddress, true) => for (cl <- clients.all if cl.path.address == remoteAddress) clients.release(cl) for (wr <- workers.all if wr.path.address == remoteAddress) workers.release(wr) } }

Page 49: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 50: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 51: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 52: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 53: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 55: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Примеры реализации

Page 56: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Распределенноепостроение словаря

Page 57: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Функции этапа

1. Токенизация и лемматизация2. Выделение устоявшихся словосочетаний3. Статистика (сколько раз, в каких

документах и т.д.)

Page 58: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object DictionaryClient {

case class DictionaryTask( chunkIdx: Int, databaseConfig: DBConfig ) extends Task

case class DictionaryResult( chunkIdx: Int, lemmas: Map[String, Int], dictionaryBits: java.util.BitSet, lemmasCount: Map[Int, Int], lemmasDocCount: Map[Int, Int] )}

Page 59: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 60: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Распределенноепостроение пространства

Page 61: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Функции этапа

1. Построение матрицы лемм и документов2. Сингулярное разложение (Singular Vector

Decomposition)3. Проекция документов на пространство

Page 62: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 63: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 64: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 65: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object SVDClient {

case class SVDTask(chunkIdx: Int, databaseConfig: DBConfig) extends Task

case class SVDResult(chunkIdx: Int, // chunk U * S array data: Array[Byte])}

Page 66: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 67: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object ProjectClient {

case class ProjectTask(chunkIdx: Int, databaseConfig: DBConfig) extends Task

case object ProjectResult

}

Page 68: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 70: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Кластеризация и тегирование

Page 71: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

1. Выделение групп (кластеров) документов2. Тегирование документов и кластеров3. Построение графов лемм

Page 72: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object CBCClient {

case class CBCTask(delta: Double, mergeThresh: Double, committeeThresh: Double, residueThresh: Double, databaseConfig: DBConfig) extends Task

case object CBCResult(centroids: Array[Array[Double]], quality: Array[Double]) }

Page 73: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 74: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

object KeywordsClient {

case class KeywordsTask(chunkIdx: Int, databaseConfig: DBConfig) extends Task

case object KeywordsResult

}

Page 75: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen
Page 77: DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Степан Каменцев, Naumen

Вопросы?

email: [email protected]: stepan.kamentsev