5. #IaaC
Avant les messages groups
U2E3 U1E3 U2E2 U1E2 U2E1
• Solution traditionnelle : Un seul consommateur pour toute la file
U1E1U2E3 U1E3 U2E2 U1E2 U2E1
U1E1
@hayssams
6. #IaaC
Avec Kafka : partitionnement par clef
U2E3 U2E2 U2E1
U1E3 U1E2 U1E1
U2E3 U2E2 U2E1U1E3 U1E2 U1E1
Cluster Kafka
P1R1 P2R1
P1R2 P2R2
Pr
o
Con
s
Con
s
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
8. #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
9. #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
10. #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
KafkaInputDStrea
m
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
• 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
12. #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
13. #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
• Contrôle sur le partitionnement
• broadcast
• accumulateurs
• Les chaînage d’actions ne requiert pas d’écriture intermédiaire sur disque
@hayssams
15. #IaaC
Pourquoi Zookeeper
•Election de leader pour la tolérance au pannes
Maitre
EsclaveEsclaveEsclave
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
16. #IaaC
Pourquoi Zookeeper
•Centralisation de la configuration
/
services
…
master
nodes
es
node1
node2
node1
Zookeeper
Server 1 Server 2Leader
Service
Service
1.Enregistrementdesservices
Client
2. Récupération de la localisation des workers
4. sollicitation du service
3. Sélection du worker
@hayssams
18. #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
19. #IaaC
Avant Mesos Démultiplication nombre de VMs
Dev.Int.PréProd.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
20. #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
21. #IaaC
Avec Mesos
Serveur Serveur ServeurServeur
80 CPU, 640Go
App App App App App App App AppApp
• Partage des ressources
• 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
22. #IaaC
Architecture Mesos
Mesos Master
Mesos Worker Mesos Worker
MonAppScheduler
MonAppExecutorMonAppExecutor
2CPUs, 20Go
Tâche
• Pour s’exécuter sur Mesos une application doit
implémenter :
• Un scheduler
• Un Executor
@hayssams
24. #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
25. #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}"]