Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014

Post on 26-Jan-2017

3,637 views 3 download

transcript

#IaaC

Realtime Web avec Akka, Kafka, Spark et Mesos

@hayssams Hayssam Saleh

@jpbunaz Jean-Philippe Bunaz

#IaaC

Sommaire To

mca

t To

mca

t

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Mesos

Marathon Zookeeper

Server 1 Server 2 Leader

#IaaC

Pourquoi Akka

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka

Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

#IaaC

Kompass • Annuaire d’entreprise

• Moteur de recherche

• Afficher les informations

• Disponible dans 70 pays

• … @jpbunaz

#IaaC

Objectifs

Quelles entreprises sont vues

Nombre de visiteurs

Mise en place d’un plan de taggage

@jpbunaz

#IaaC

Challenge

Un tag par prestataire

Changer les règles

Informations en session

Intercepter les requêtes sur le serveur

@jpbunaz

#IaaC

Utilisation d’une Valve

APACHE

TOMCAT

WEB APP

SESSION

VALVE

RESPONSE

REQUEST

?

PARAM

LOG

REQUEST

RESPONSE

REQUEST

RESPONSE

@jpbunaz

#IaaC

Impacts

Mon log peut être

long

Différent type de log

Perturbe mon application

La valve doit être non bloquante

@jpbunaz

#IaaC

Valve non-bloquante

APACHE

TOMCAT

WEB APP

SESSION

VALVE

?

PARAM

REQUEST

ACTOR

LOG MAILBOX

REQUEST REQUEST

@jpbunaz

#IaaC

Acteur : Vue d’avion TASK

2 TASK

1

TASK 4

TASK 4

Tâches indépendantes qui communiquent entre elles de manière asynchrone via des

messages TASK

3

TASK 5

@jpbunaz

#IaaC

Création d’un Message

case class MonMessage(param1: String, param2: String, param3: String, param4: String)

@jpbunaz

#IaaC

Création d’un Acteur

class MonActeur() extends Actor { def receive = { case MonMessage(param1: String, param2: String, param3: String, param4: String) => // Code de logging case }

}

@jpbunaz

#IaaC

Envoi du message à l’acteur

// Initialisation de l’acteur val monActeur = actorSystem.actorOf(Props[MyActeur]) // Initialisation du message val monMessage = MonMessage("value1", "value2", "value3", "value4") // Envoi aynchrone du message à l’acteur monActeur ! monMessage // Code exécution avant traitement du message ExecuterLaSuiteDansLaFoulée()

@jpbunaz

#IaaC

Acteur : Points de vigilance

N’expose pas son état interne

class UglyActeur() extends Actor { var variableCanAccess = null

def receive = { case String => // My acteur code… }

}

@jpbunaz

#IaaC

Acteur : Points de vigilance

Les messages doivent être immuables case class UglyMessage(

var param1: String, var param2: String)

@jpbunaz

#IaaC

Acteur : Points de vigilance

TASK

Working…

@jpbunaz

• L’acteur ne traite qu’un seul message à la fois • Les messages sont mis en attente dans une boite aux

lettres

#IaaC

Maitriser le nombre d’acteurs

Nombre d’Acteur !!!

Un message à la fois !!!

Utiliser un router

@jpbunaz

#IaaC

Routeur • Maîtriser le nombre d’Acteur • Différents types de routage (RoundRobin, Random …)

• Configuration externalisée dans un fichier de propriétés

@jpbunaz

#IaaC

Créer un routeur

val monRouteur = actorSystem.actorOf( FromConfig.props(routeProps = Props[MonActeur]) , name = "monRouteur"

)

@jpbunaz

#IaaC

Configurer un routeur

Akka.actor.deployment {

/monRouteur { router = round-robin-pool nr-of-instances = 5

} }

@jpbunaz

#IaaC

Conclusion sur les Acteurs • Simple à mettre en oeuvre

• Contrôle sur les ressources en adéquation avec la charge

• Gestion multithread transparente, pas de lock, de synchronized

• Naturellement asynchrone @jpbunaz

#IaaC

Objectifs

Spark Streaming

Spark Classic

Kafka

Mesos

⇒ Scale Up / Scale Out

@hayssams

#IaaC

Pourquoi Kafka ?

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

@hayssams

#IaaC

Avant les messages groups

U2E3 U1E3 U2E2 U1E2 U2E1

•  Solution traditionnelle : Un seul consommateur pour toute la file

U1E1 U2E3 U1E3 U2E2 U1E2 U2E1

U1E1

@hayssams

#IaaC

Avec Kafka : partitionnement par clef

U2E3 U2E2 U2E1

U1E3 U1E2 U1E1 U2E3 U2E2 U2E1 U1E3 U1E2 U1E1

Cluster Kafka

P1R1 P2R1

P1R2 P2R2

Pro

Cons

Cons

Avec JMSGroupID

•  Un local manager (SPOF) plusieurs remote

•  Requiert un serveur de backup

@hayssams

Avec Kafka

•  Support natif du partitionnement

•  Réplication des messages

•  Tolérance au pannes

#IaaC

Pourquoi Spark Streaming

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

@hayssams

#IaaC

•  Récupération du Tuple(request, response, session, url)

•  val tuples = kafka.initStream(context, "requests », 2 seconds)"•  Validation des règles

•  rdd = tuples.filter( t => RulesHandler.match(t))"•  Transformation du tuple en document JSON

•  rdd2 = rdd.map( t => toDocument)"•  Injection dans ES

•  rdd2.foreachRDD(doc => es.insert doc)"•  Identification des relations

•  rdd3 = rdd.flatMap(_.toRelations)!•  rdd3.foreachRDD(rel => neo4j.insert rel)"=> Statistiques d’accès en temps réel

Traitement continu des accès utilisateurs

@hayssams

#IaaC

Avec Spark: API unique pour la batch et le streaming

Flux continu provevant de réseau

2s 2s 2s 2s 2s 2s 2s t t +16

•  Découpage du flux en un paquet de données (RDD) toutes les 2 secondes

•  Un RDD est une collection de données

RDD RDD RDD RDD RDD RDD RDD •  Chaque paquet est traité comme un comme

un RDD soumis au batch Spark classique

Out Out Out Out D

Out D

Out

Out

•  Spark exécute les opérations sur le RDD comme dans un batch classique et renvoie le résultat en retour.

Spark •  Exécution de microbatchs

@hayssams

#IaaC

Avec Spark: Tolérance aux pannes au coût minimum

val tuples = kafka.initStream(context,"requests », 2 seconds"

!

rdd = tuples.filter( t => RulesHandler.match(t))"

"

rdd2 = rdd.map( t => toDocument)"

"

rdd2.foreachRDD(doc => es.insert doc) // via Kafka"

!

rdd3 = rdd.flatMap(_.toRelations)!

!

rdd3.foreachRDD(rel => neo4j.insert rel) // via Kafka

KafkaInputDStream

FilteredDStream

MappedDStream

ForEachDStream

MappedDStream

ForEachDStream

•  Le code ci-dessus ne génère aucun calcul, juste un graphe d’objets

•  Le Scheduler Spark va soumettre le graphe d’objets aux workers pour exécution

•  J En cas de panne, il suffit juste de soumettre à nouveau le graphe d’objets à un autre worker.

•  Pas besoin de réplication des résultats ou d’upstream backup

@hayssams

#IaaC

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

Pourquoi Spark Classic

@hayssams

#IaaC

Notification des clients rdd= Sc.readFromXMLFile(…)"

rdd.persist!

val updatedRDD = rdd.filter(product => product.existsInMapWithDifferentHash)"

val newRDD = rdd.filter(product => !product.existInMap)"

"

val updateNotifications = updatedRDD.map(_.executeStrategies)"

"

val newNotifications = newRDD.map(_.executeStrategies)"

"

updateNotifications.union(newNotifications).foreachRDD(_.notifyClient)"

"

RDD

Action

@hayssams

#IaaC

Avec Spark : Une riche librairie d’opérations d1

d2

d3

d1

d2

d3

d1

d2

d3

d2

d3

d1

d2

d3

d1

d2

d3

d1

d2

d3

map filter union groupByKey reduceByKey

reduce collect count take first foreach …

•  Avec en plus

•  J Contrôle sur le partitionnement

•  J broadcast

•  J accumulateurs

•  J Les chaînage d’actions ne requiert pas d’écriture intermédiaire sur disque

@hayssams

#IaaC

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

Pourquoi Apache Zookeeper

@hayssams

#IaaC

Pourquoi Zookeeper • Election de leader pour la tolérance au pannes

Maitre

Esclave

Esclave Esclave

Maitre de secours Esclave et maitre de secours

Esclave et maitre de secours

Esclave et maitre de secours

Esclave et maitre de secours

Election de leader

Avec Zookeeper Tout noeud est un master potentiel

@hayssams

#IaaC

Pourquoi Zookeeper • Centralisation de la configuration

/

services

master

nodes

es

node1

node2

node1

Zookeeper

Server 1 Server 2 Leader

Service

Service

1. E

nreg

istr

emen

t de

s se

rvic

es

Client

2. Récupération de la localisation des workers

4. sollicitation du service

3. Sélection du worker

@hayssams

#IaaC

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Zookeeper

Server 1 Server 2 Leader

Pourquoi Mesos Marathon

@hayssams

#IaaC

Avant Mesos Démultiplication nombre de VMs •  €€€ Cluster Tomcat : Frontend facing app

•  € Cluster Kafka : Middleware de messages

•  €€ Cluster Spark

•  €€€ Cluster ElasticSearch

•  TTT : Compléxité de configuration

•  Apache Mesos et Marathon à la rescousse

•  Voir l’ensemble des VMs comme une seule machine sur laquelle tournent plusieurs JVMs

@hayssams

#IaaC

Avant Mesos Démultiplication nombre de VMs D

ev.

Int.

PréP

rod.

Prod

. •  Requiert d’exécuter un OS en

entier pour obtenir une isolation des ressources et de la sécurité

•  Temps de démarrage assez long (5 à 10 minutes par VM)

•  Plus d’OS => encore plus de systèmes à administrer

•  Coût de licence des VMs

•  Allocation statique => Sous utilisation de la CPU

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

VM

@hayssams

#IaaC

Avec Linux cgroups

OS Hôte

OS Guest OS Guest OS Guest

App1 App2 App3

OS Hôte

App1 App2 App3 •  Isolation

•  CPU

•  Mémoire

•  I/O

•  Réseau

VM Linux cgroups

@hayssams

#IaaC

Avec Mesos

Serveur

Serveur

Serveur

Serveur

80 CPU, 640Go

App

App

App

App

App

App

App

App

App

•  J Partage des ressources

•  J Tolérant aux pannes

•  Pour les applications longue durée (MOM / AS)

•  Si vous n’avez jamais cherché à savoir sur quel cœur s’exécute votre tâche alors vous n’avez probablement pas besoin de savoir non plus sur quel serveur.

•  IaaC : Infrastructure as a (Single) Computer

•  Faire fonctionner les différents environnements (dev / Int/ Preprod / Prod) sur la même infrastructure

•  Y compris les jobs Jenkins

@hayssams

#IaaC

Architecture Mesos

Mesos Master

Mesos Worker Mesos Worker

MonAppScheduler

MonAppExecutor MonAppExecutor

2CPUs, 20Go

Tâche

•  Pour s’exécuter sur Mesos une application doit implémenter :

•  Un scheduler

•  Un Executor

@hayssams

#IaaC

Mesos

Tom

cat

Tom

cat

Fron

t fa

cing

App

Fron

t fa

cing

App

Akka Akka

Akka Akka

Stream Processing (Spark Streaming)

Realtime Views (ElasticSearch)

All Data (Spark)

Precompute Views

Batch Views

Query

(Tomcat, K

ibana, …)

New

Data Stream

Kafka

Speed Layer

Batch Layer Serving Layer

Product Updates

Marathon Zookeeper

Server 1 Server 2 Leader

Marathon

@hayssams

#IaaC

Pourquoi Marathon

• Eviter d’avoir à développer un Executor et un Scheduler pour les applications « longue durée »

• Marathon permet via une API REST de configurer des instances applicatives au dessus de Mesos en indiquant la commande à lancer

@hayssams

#IaaC

Exemple de commande Marathon

POST /v2/apps HTTP/1.1""{" "id": "TomcatApp"," "cmd": "/path/bin/catalina.sh run $PORT"," "mem": 1024," "cpus": 2.0," "instances": 3," "constraints": ["""]"}"" •  Marathon utilisé pour lancer

•  Kafka

•  ElasticSearch

•  Tomcat

•  Scale up/down par simple appel REST avec une nouvelle configuration

Régulation de charge et découverte

GET /apps/MonApp/tasks Hot haproxy.cfg reload

@hayssams

["hostname", "UNIQUE", ""],!["hostname", ”like", ”front{1,2}"]

@YourTwitterHandle #DVXFR14{session hashtag} #IaaC

#IaaC

Conclusion • Neal Real time Analytics

•  Batch Analytics

• Middleware de messages

•  Partage dynamique de ressources

Spark Streaming

Spark Classic

Mesos

Marathon

Kafka

Un seul framework

IaaC

Partionnement automatique

@hayssams

@YourTwitterHandle #DVXFR14{session hashtag} #IaaC