Plateforme BigData (Cloudera) sur un Cloud: automatisation avec Cloudify

Le Big Data est un sujet incontournable chez FastConnect: pour élargir son business, il est maintenant critique d’élargir son champ de vision à l’aide des données externes et les données non-structurées et sous-exploitées.
Hadoop et son écosystème répond à ces challenges, et cette plateforme Big Data devient de plus en plus mature grâce aux différents éditeurs comme Cloudera, HortonWorks, MapR ou Pivotal.

Mais la mise en œuvre de cette plateforme constitue aussi un challenge:

  • Pour répondre à des problèmes complexes, la communauté a développé plusieurs outils indépendants: Sqoop, Flume, HBase, HDFS, etc.
    La multiplicité de ces outils rend le déploiement plus complexe.
  • Pour traiter des volumes conséquents, le déploiement de la plateforme doit se faire sur plusieurs nœuds. De plus, on veut pouvoir augmenter ou réduire le nombre de nœuds de manière élastique en fonction du besoin.
  • Avec un grand nombre de nœuds, on est sujet à plus de risque de pannes, ce qui nécessite une attention particulière sur la HA (High Avaibility / Haute Disponibilité)

L’article présent traite de l’automatisation à l’aide de Cloudify du déploiement et de la configuration sur un Cloud d’une telle plateforme, basée sur la distribution Cloudera de Hadoop.

Besoins

une plateforme BigData configurée

Nous souhaitons effectuer des traitements sur un gros volume de données et obtenir par exemple des statistiques sur un fait, ou encore faire des prédictions. Oui on souhaite faire du “BigData”, et il nous faut une plateforme adéquate déployée et configurée. Une solution serait de se servir de la plateforme pré-installée que propose Cloudera sous forme d’une machine virtuelle “All-in-One”

Oui mais… j’ai vraiment beaucoup de données!!

Ça se corse un peu! Le volume est énorme, tout stocké sur une seule machine ne me permettra pas de bénéficier de la réduction du temps de traitement que nous offre la faculté de distribution du traitement. On voit là une limite du mode StandAlone (All-in-One): il nous faut une plateforme en architecture “distribuée, et donc plusieurs machines qui servirons de DataNode / TaskTracker (Nœud de stockage de données et de traitement ).

Je n’ai pas assez de budget..

Oui c’est vrai, il faut du budget pour s’offrir une plateforme comportant plusieurs serveurs. Pourquoi ne pas se tourner vers le Cloud? En effet, avec la particularité IaaS du Cloud Computing, il est désormais possible d’obtenir de l’infrastructure (machines virtuelle en l’occurrence) et de payer en fonction de la durée d’utilisation. Ainsi plus besoin d’une plateforme de serveurs physiques, car il est possible de louer des machines virtuelle (VMs) à l’heure chez un fournisseur ( Amazon EC2 par exemple ) ce qui ne nécessite pas forcement un gros budget au départ ;)

Oups… j’ai fait une erreur lors de la configuration: trop longue et répétitive :|

Le fait de louer des VMs pour un certain temps et de les détruite après, entraîne la réinstallation et la reconfiguration de la plateforme chaque fois que le besoin se pose. Cette opération est longue et répétitive quand elle est effectuée manuellement. Aussi, les risques d’erreurs de configuration sont grands. Automatiser le processus permet d’être sûr d’avoir les mêmes configurations d’un déploiement à l’autre, et de gagner considérablement en temps.

Cloudify est un outil qui permet d’effectuer une telle tâche: nous n’avons plus qu’à décrire les procédures d’installation et de configuration de la plateforme, et d’exécuter le tout quand bon nous semble avec une seule ligne de commande: install-application cloudera

Nous pourrons aussi jouir des autres fonctionnalités de Cloudify telles que:

  • Multi-cloud : le prototype hébergé chez un fournisseur public (Amazon EC2 par exemple) pourra être migré facilement sur l’infrastructure interne (Openstack, ou bare metal par exemple)
  • Custom Command : pour automatiser des tâches d’administrations sur l’ensemble des nœuds
  • Gestion du cycle de vie de l’application: pour la gestion de crash (fail over)
  • Élasticité: possibilité d’ajouter à chaud des nœuds DataNode+TaskTracker en cas de besoin
  • Monitoring: avoir une vue d’ensemble du cluster, en connaître la charge et ainsi anticiper l’ajout de nouveaux nœuds

L’application cloudify-cloudera

Cloudify-cloudera est le nom que nous avons donné à l’application Cloudify qui permet de faire tout ce qui a été cité plus haut. Le Cloud utilisé ici est Amazon EC2 (mais Cloudify est Multi-Cloud: cela fonctionne aussi bien sur OpenStack, sur un environnement de développement avec VirtualBox, ou même un datacenter traditionnel [sans virtualisation]).

Les recettes dans leur état actuel permettent d’obtenir une plateforme BigData composée d’un Cloudera Manager et d’une distribution Hadoop repartie sur deux types de noeuds : Master et Slave. Un service de base de données MySQL est aussi disponible en cas de besoin. En plus de la distribution Cloudera, nos recettes sont capables de déployer un MongoDB en mode Sharding afin d’y effectuer du MapReduce.

archi cluster cloudera on demand

Nous nous servons de Cloudera Manager (CM) pour configurer les composantes de la plateforme. CM expose une API REST pour permettre son pilotage programmatiquement, dans notre cas, par des scripts Groovy exécutés par Cloudify.

Les Briques (noeuds) et services installés

L’application installe quatre principaux middlewares :

  • Cloudera Manager
  • Cloudera distribution of Hadoop
  • La base de données MySQL : optionnelle
  • La base de données MongoDB: Sous forme de cluster (mode sharding).

L’installation et l’implémentation de ces services se font sur des instances de machines, appelées nœuds du cluster.

Les services Cloudera supportés sont:

ZOOKEEPER, HDFS, MAPREDUCE, OOZIE, HIVE, HBASE, SQOOP, FLUME, HUE

Le concept de Hadoop veut lui-même que l’on dispose principalement de deux entités ou types de rôle : le maître (Master) (NameNode, JobTracker) et l’esclave (Slave) (DataNode, TaskTracker). Le service MongoDB étant déployé en mode sharding, il est nécessaire pour son architecture de lui fournir aussi deux types d’instances : master et slave. MySQL quant à lui sera déployé sur une instance de machine propre à elle.
Si nous récapitulons, nous pouvons dire que notre système sera composé principalement de quatre types de noeuds (service Cloudify).

Cloudera Manager : (code : cdh4-manager)

Représente une instance de Cloudera Manager. Ceci permet d’administrer l’ensemble du cluster via une interface Web.

Master CDH : (Code : cdh4-master)

Nœud sur lequel seront installés les composantes NameNode, JobTracker, et tout autre service ou composante de service Cloudera qui implémente une division Master/ Slave, à l’instar de MongoDB (partie Master).

Slave CDH : (Code : cdh4-slave)

Nœud sur lequel seront installés les composantes DataNode, TaskTracker, et tout autre service ou composante de service Cloudera qui implémente une division Master/ Slave, à l’instar de MongoDB (partie Slave).

MySQL : (Code : mysql-cdh4) sur lequel sera installé le middleware MySQL.

web-ui-cloudify

Opérations annexes et/ou d’administrations

Backup / Restauration HDFS

Une problématique assez fréquente est la sauvegarde des données potentiellement résultantes des traitements effectués à la fin de l’utilisation du cluster, de façon à les réimporter une prochaine fois pour continuer les traitements.

Deux custom commands ont été développées et implémentées aux noeuds de type cdh4-master pour cet usage. La commande backup prend en paramètre le nom du répertoire à sauvegarder sur Amazon s3 ; la commande de restauration prend en paramètre le nom de la sauvegarde à restaurer.
Il est à noter que le nom de fichier à persister sur S3 est généré de façon intelligente selon un pattern « hdfs-backup-yyy-mm-dd~hh.mm.ss » ce qui permet de s’y retrouver très rapidement lorsqu’on cherche à restaurer une sauvegarde précise.
L’invocation de ces commandes via le Shell Cloudify se fait de la façon suivante :

Invoke cdh4-master s3HdfsBackup /test
// Sauvegarde un répertoire HDFS /test dans un repertoire « hdfs-backup-yyy-mm-dd~hh.mm.ss »

Invoke cdh4-master s3HdfsRestore /hdfsBackups/hdfs-backup-yyy-mm-dd~hh.mm.ss /test
 // Restaure le contenu du répertoire s3 hdfs-backup-yyy-mm-dd~hh.mm.ss dans un répertoire /test du HDFS

Une autre façon de faire est d’exploiter le montage des EBS d’Amazon dans Cloudify: on aurai pu démonter les EBS en cas de destruction du Cluster, pour les re-monter lorsqu’on a besoin à nouveau du Cluster. Ce mécanisme est d’ailleurs nécessaire pour ne pas perdre les données en cas de crash d’une VM.

Mongo sharding

Possibilité offerte via custom commands d’activer le sharding sur des bases de données et collections MongoDB.

Conclusion

Au terme de cet article, nous avons présenté quelques besoins qui se posent concernant la gestion d’une plateforme BigData et les solutions que nous y avons apportées, se résumant en l’automatisation du déploiement et de la configuration. Le déploiement opéré par Cloudify est multi-cloud, c’est-à-dire que le prototype développé sur Amazon (pour des raisons de budget) pourra être migré facilement sur votre plateforme Openstack interne. De plus nous bénéficions des fonctionnalités d’auto-réparation offerte par Cloudify (remplacement et reconfiguration des composants en panne).

L’utilisation de l’application développée est aisée. Le projet n’est pas clos, nous continuons d’y ajouter des fonctionnalités et améliorations. Quelques évolutions à venir :

  • Possibilité d’utiliser des EBS comme support de stockage: ce qui rassurerait l’utilisateur quant à la sauvegarde de ses données
  • Custom command pour ajout / suppression de services cloudera
  • Combiner Puppet / Cloudera: Puppet permettra de gagner en temps et en performance pour tout ce qui est installation et déploiement, tandis que Cloudify gérera les dépendances entre les services et la configuration du cluster une fois le tout installé.
  • Custom command pour importer / exporter des Job Oozie au format XML,

On démontre ici une fois de plus, la puissance de l’association BigData + Cloud, ainsi que les nombreuses possibilités que nous offre l’outil Cloudify.

Mule Summit Automne 2013

Bonjour,

FastConnect et MuleSoft ont le plaisir de vous inviter ainsi que les membres de votre équipe, au Mule Summit, évènement annuel clé dans le domaine de l’intégration, qui aura lieu à Paris le 16 Octobre 2013.

Cet évènement va réunir les clients de MuleSoft, la communauté et les équipes techniques ainsi que les dirigeants de MuleSoft pour une journée d’échange autour de l’offre MuleSoft, à travers des présentations sur les nouveaux produits, les roadmaps et des tables rondes.

Cette journée vous permettra de :

  • Découvrir comment mieux vous préparer pour le New Enterprise
  • Apprendre les meilleures techniques d’intégration des utilisateurs expert en Mule et des architectes expérimentés
  • Avoir une visibilité sur la roadmap de MuleSoft et influencer l’orientation du produit
  • Rencontrer les experts MuleSoft et de l’industrie, y compris le fondateur de MuleSoft, Ross Mason

Je vous invite à consulter le site internet de notre partenaire MuleSoft pour plus d’information et le programme de cette journée :
http://mulesummitparis.eventbrite.com

Voici les détails pratiques à retenir :
Mule Summit Paris
Date: 16 Octobre 2012
Horaires: 8h30 – 18h30
Lieu: Les Salons de l’Aéroclub de France, 6 rue Galilée, 75016 Paris (métro Boissière – ligne 6)

Si d’autres collaborateurs souhaitent participer à cet évènement, n’hésitez pas à nous envoyer leurs noms et coordonnées le plus tôt possible, pour un enregistrement sans frais.

Cordialement,

L’équipe Mule
contact@fastconnect.fr

Formation BigData – Hadoop – module Développeur

Bonjour,

Le BigData n’est plus réservé aux géants du Web, c’est maintenant l’affaire de tous.
On estime que 80% des données d’une entreprise sont non-structurées et inexploitées… et le volume augmente de plus en plus rapidement. De plus, les infrastructures modernes nous permettent de conserver de plus en plus de données à moindre coût : rien n’est à jeter, tout peut être utile.

FastConnect a le plaisir de vous présenter sa nouvelle formation BigData Hadoop orientée Développeurs.
Ce module de 3 jours, alternant cours théoriques et pratiques, vous offre une introduction sur les enjeux du BigData, ainsi qu’une mise en pratique avec la technologie Hadoop. (télécharger le programme de la formation)

L’objectif de cette formation est de démystifier Hadoop, savoir utiliser les outils principaux autour de son écosystème et traiter les données de diverses manières, dont le Machine Learning, afin de présenter les résultats de manière graphique.
Une prise en charge par votre OPCA est possible (numéro d’agrément 11921636592).

La prochaine session aura lieu du 17 au 19 septembre dans notre centre de formation d’Issy les Moulineaux, au prix réduit de 1 700€ HT par participant au lieu de 1 900€.

Les places sont limitées, si cette formation vous intéresse, n’hésitez pas à nous contacter.

Cordialement,

L’équipe FastConnect Training
+33 (0)1 45 07 81 65
training@fastconnect.fr

BreizhCamp 2013, FastConnect était là !

Comme je l’avais annoncé précédemment, nous étions présents les 13 et 14 juin au BreizhCamp 2013, LA conférence de l’Ouest :)

Il faut avouer que cette année la concurrence est rude :). Et oui, après avoir vu notre beau stand de l’édition 2012 (nous étions le seul sponsor à avoir un stand :)), tous les autres sponsors ont sorti leur artillerie lourde cette année.

Mais grâce à nos démos de MuleStudio, JRules et de notre portail de déploiement “votre custom PaaS dans votre Cloud” (basé sur Cloudify, entre autres, et développé par le Centre d’Expertise Cloud — contactez nous si vous voulez voir une démo :)), qui a été le point d’orgue de la 1ère journée (tout s’est très bien déroulé — à l’exception du petit effet démo avec PowerPoint qui s’est figé :(), nous n’avons pas peur de dire qu’il y avait du monde à notre stand :)

La 2ème journée a été tout aussi intense avec les démos en continu (et après le CI, nous avons mis en place le Continous Demo :)) et un très bon moment de détente avec beaucoup de participants à notre jeu FastDraw, dessinez c’est gagné, version geek où il y avait de nombreux lots à gagner :)

Bref, ce fut une expérience enrichissante… et un événement très bien organisé ! Merci à l’équipe organisatrice du BreizhCamp !

Et je tiens également à remercier l’équipe FastConnect Rennes, en particulier Matthieu, Antoine, Yoann et Violaine, pour leur implication et préparation. Bien entendu, les démos ne seraient pas aussi intéressantes sans les experts du CE Cloud : spécial dédicace donc à Gauvain, Mathias, Noureddine (et j’en oublie d’autres… et je m’en excuse). Et pour finir, un grand merci à Laure, notre chargée de recrutement préférée, qui s’est aventurée en terre bretonne pour l’occasion et qui m’a appris un nouveau mot : kakémono :)

20130614_132814 IMG_1452 IMG_1455 IMG_1464 IMG_1469

Gatling – Test de charge et cloudification

Dans le cadre du développement de l’application FastContest et de son déploiement dans le cloud d’Amazon avec Cloudify, nous avons souhaité effectuer des tests de charge automatisés afin :

  • d’évaluer la charge maximale que notre application pouvait soutenir
  • de dimensionner les machines du Cloud sur lesquelles nous déployons
  • de mettre en exergue les faiblesses de notre application
  • de jouer des scénarios définis automatiquement avec plusieurs centaines de joueurs concourants et ainsi de vérifier la bonne intégrité des données à l’issue

Nous avons choisi d’utiliser Gatling, un outil de test de charge open-source, qui permet d’écrire les scénarios de test sous forme de codes élégants et concis.

Arborescence de Gatling

Le dossier d’installation de Gatling est organisé selon l’arborescence suivante :

  • /results : Contient les résultats des benchs sous format web
  • /bin : Contient les scripts permettant de lancer Gatling
  • /target : Contient les fichiers issus de la compilation de nos scénarios + cache
  • /conf : Contient les fichiers de configuration (niveau de log…)
  • /user-files : Contient les fichiers .scala de définition des scénarios
  • /lib : jar de gatling

Des scénarios implémentés en Scala

À la différence de JMeter qui dispose d’une interface graphique pour la définition des scénarios de simulation et de ses paramètres, Gatling propose une API écrite en Scala. Contre-intuitivement, il est assez élégant et aisé de définir des scénarios en Scala plutôt que via une interface graphique, surtout qu’il n’est pas nécessaire d’être un ninja en Scala pour réaliser ses premiers scénarios. Gatling propose une multitude de fonctionnalités dont les basiques seront présentées plus loin.
La documentation complète est disponible à ce lien.
Les scénarios sont placés dans le dossier /user-files/simulations. Voici, typiquement, un scénario implémenté en Scala :

val scn = scenario("User play")
  .feed(myCustomFeeder)
  .exec(
     http("register")
      .post("/user/register")
      .param("email", "${email}")
      .param("password", "${password}")
      .param("pseudo", "${pseudo}")
      .headers(headers_1)
      .check(status.is(200)))
  .pause(0 milliseconds, 100 milliseconds)
  .repeat(10) {
    feed(csv("question_answer.csv").circular)
      .exec(
        http("answer")
         .post("/response")
         .param("questionId", "${questionId}")
         .param("answerId", "${answerId}")
         .headers(headers_1))
      .pause(0,5)
  }

Dans ce cas, Gatling va effectuer une requête post /user/register avec les paramètres email et password (défini dans un fichier séparé), et vérifiera que la réponse a bien un status 200. Enfin, après une pause de 0 à 100 ms, Gatling effectue 10 requêtes /response avec une pause de 0 à 5 sec entre chaque. Les paramètres sont fournis par un “feeder” qui permet de factoriser des variables au sein d’un fichier CSV par exemple (pour plus d’infos, suivez le lien)
Pour apprendre à écrire un scénario avec Gatling, il y a le tutorial officiel.

Exécution de bench

Pour lancer un scénario il suffit d’exécuter le script gatling.sh ou .bat selon l’environnement qui se trouve dans le dossier /bin. Gatling va compiler automatiquement les classes Scala puis vous demande de choisir le scénario à exécuter. À l’issue de la simulation, un rapport web est généré automatiquement à partir du fichier de log. Il contient toutes les métriques mises en forme de façon graphique grâce à la librairie Javascript HighChart.

Un exemple de rapport :

Cloudification

Afin d’effectuer des tests de charges proches des conditions réelles nous avons cloudifié Gatling en automatisant son installation et son exécution sur les VM d’Amazon.
Grâce à Cloudify, nous pouvons désormais lancer les tests de charge à partir d’Internet et sur autant de machine que nous voulons. Les recipes sont relativement simples puisqu’il s’agit essentiellement de télécharger et de dézipper le dossier d’installation de Gatling. Les scénarios sont uploadés avec la recipe, ils doivent donc être déplacés dans le répertoire /simulation de Gatling.
L’exécution du bench s’effectue grâce à une custom command “executeBench” dont le premier paramètre est le nom du scenario à exécuter et le second, le nom que l’on donne à cette simulation. La custom command lance alors le test de charge pour toutes les instances de Gatling sur chaque VM. Les rapports sont donc générés individuellement sur chaque VM.

Pour obtenir un rapport unique, on pourrait scripter la récupération de tous les résultats générés, leur fusion et la regénération d’un nouveau rapport global.
Le rapport est ensuite poussé sur S3 soit automatiquement, soit via une custom command (pushResult).

À travers ce use-case de Cloudify, nous montrons, une fois encore, sa simplicité et sa commodité d’utilisation en automatisant complètement la chaîne : déploiement, installation et exécution de tests de charge à partir du Cloud Amazon EC2.

Conclusion

L’un des avantages le plus important de Gatling est sans conteste sa capacité à générer des rapports graphiques de qualité à l’issue de chaque simulation. De cette façon, le testeur a immédiatement accès aux résultats de manière visuelle, sans post-traitement supplémentaire.
De plus, l’écriture des scénarios de test de façon fonctionnelle en Scala peut faciliter la lisibilité du test. Surtout grâce aux feeders qui permettent de factoriser les paramètres dans des fichiers à part.

Enfin, le lancement des tests via des simples commandes de script rend sa cloudification aisée.

Créer rapidement un prototype d’application HTML5 pour téléphones portable avec Sencha Touch.

Sencha Touch est un framework Javascript. Il dispose d’une bibliothèque riche pour mettre en place rapidement une application HTML5 orienté Single Page Application.

Nous avons utilisé Sencha Touch pour développer rapidement notre jeux de quizz pour le Devoxx France 2013. Il s’agissait d’expérimenter ce framework dans le cadre d’un développement court et au budget limité. Sencha répond à cette problématique en produisant des applications HTML5 utilisables sur une grande majorité des téléphones du marché sans développement spécifique pour chaque plateforme (mis à part un design spécifique pour les tablettes).

FastContestSenchaTouch

Points positifs :

Points négatifs :

  • fort couplage (l’application créée ne pourra se défaire de Sencha)
  • documentation pas très à jour
  • forte dépendance à webkit ( = ne supporte pas Firefox, Opera, IE ainsi que de nombreux autres navigateurs)

Installer Sencha

Pour développer une application HTML5 en utilisant Sencha, il est nécessaire de télécharger l’API Sencha Touch ainsi que l’application Sencha Cmd. Le premier permet à l’application de fonctionner tandis que le second permet de créer l’archétype de l’application et de fabriquer le paquet que l’on mettra en production (ne copier que les bibliothèques Sencha effectivement utilisées, minification du Javascript, …)

API Sencha

  1. Télécharger Sencha Touch (http://www.sencha.com/products/touch/download/)
  2. Dézipper et placer dans un serveur Apache (pour éviter les problèmes de Cross Domain, sinon lancer un navigateur en désactivant la sécurité pour tester votre application en développement).

Sencha Cmd

  1. Télécharger Sencha Cmd (http://www.sencha.com/products/sencha-cmd/download)
  2. Installer (répertoire par défaut : ~/bin/Sencha)

Créer une application de type HelloWorld

Plutôt que de présenter l’application utilisée lors du Devoxx, on commencera par mettre au point une simple application.

Pour générer l’archétype de l’application, il faut créer un dossier portant le nom de l’application (ex : myapp) et lancer la commande idoine :

~\Desktop\blog\touch-2.1.1mkdir myapp
~\Desktop\blog\touch-2.1.1cd myapp
~\Desktop\blog\touch-2.1.1\myappsencha generate app myapp ../myapp

Maintenant le dossier “myapp” contient un projet Sencha. Quelques explications sur les ressources créés :

  • le fichier app.js est le point d’entrée de l’application
  • le dossier app contient les différentes classes javascript du projet,
  • le dossier ressources contient les éléments externes (icones, libs…)
  • le dossier touch contient un sous-ensemble de l’API

Développer

Nous vous proposons maintenant de créer une application Sencha. Plutôt que de vous donner le code de notre jeux de quizz, nous allons créer une application plus simple qui permet de lister des pizzas et de voir leurs ingrédients.

Sencha repose sur un framework MVC et il propose des classes que l’on peut étendre : Ext.data.Model, Ext.dataview.List, Ext.Panel, …

Nous allons débuter par décrire le modèle de donnée : ici nos pizzas et leurs ingrédients. Une relation « One to Many » relient les pizzas à leurs ingrédients, sachant qu’un ingrédient ne peut se trouver plus d ‘une fois dans une pizza.

myapp/app/model/ingredient.js

Ext.define('myapp.model.Ingredient', {
  extend: 'Ext.data.Model',
  config: {
    fields: [
     {name: 'name'}
    ]
  }
});

myapp/app/model/pizza.js

Ext.define('myapp.model.Pizza', {
  extend: 'Ext.data.Model',
  uses: ['myapp.model.Ingredient'],
  config: {
    fields: [
      {name: 'name'}
    ],
    hasMany: {
      model: 'myapp.model.Ingredient',
      name: 'ingredients'
    }
  }
});

Nous allons maintenant implémenter un store de pizzas. Un store permet de gérer les données, de lire ou de sauvegarder depuis une source locale (json, xml) ou distante (ajax, jsonp, …). Dans notre cas, on lira des données directement écrites dans le code.

myapp/app/store/menu.js

Ext.define('myapp.store.Menu', {
  extend: 'Ext.data.Store',
  requires: ['myapp.model.Pizza'],
  config: {
    model: 'myapp.model.Pizza',
    storeId: 'Menu',
    autoLoad: true,
    data: [
      {
        name: 'marguerita',
        ingredients:[
          {name: 'Tomato'},
          {name: 'Cheese'},
          {name: 'Olives'}
        ]
      }
    ]
  }
});

Les vues de l’application sont la liste des pizzas et une fenêtre qui s’ouvre lors de la sélection d’une pizza pour afficher les ingrédients

myapp/app/view/MenuList.js

Ext.define('myapp.view.MenuList', {
  extend: 'Ext.dataview.List',
  requires: ['myapp.store.Menu'],
  origin: 'menu', //custom identifier for the controller pizzaiolo
  config: {
    store: 'Menu',
    itemTpl: [
      '<div{name}</div'
    ]
  }
});

myapp/app/view/ingredientsListOverlay.js

Ext.define('myapp.view.IngredientsListOverlay', {
  extend: 'Ext.Panel',
  alias: 'widget.ingredientsListOverlay',
  config: {
    centered: true,
    height: 200,
    width: 200,
    modal: true,
    items: [
      {html: '<h3Ingredients</h3',styleHtmlContent: true}
    ]
  }
});

Nous allons maintenant implémenter un contrôleur qui gèrera l’affichage de la liste d’ingrédients quand une pizza est sélectionnée.

myapp/app/controller/pizzaiolo.js

Ext.define('myapp.controller.Pizzaiolo', {
  extend: 'Ext.app.Controller',
  requires: ['myapp.view.IngredientsListOverlay'],
  config: {
    control: {
      'list[origin=menu]': {
        itemtap: 'displayIngredients'
      }
    }
  },
  displayIngredients: function(list, index, target, record, e, eOpts){
    var menu = new myapp.store.Menu();
    overlay = Ext.widget('ingredientsListOverlay');
    Ext.Viewport.add(overlay);
    menu.getAt(index).ingredients().each(
      function(ingredient){
        overlay.insert(overlay.getItems().length,{html: ingredient.get("name")});
      }
    );
  }
});

Enfin, on modifie app.js pour qu’il charge le store et affiche la première vue (la liste de pizzas) au démarrage.

var menu = new myapp.store.Menu();
Ext.Viewport.add(Ext.create('myapp.view.MenuList'));

Mise en production d’une application dans le Cloud: gestion du déploiement par Cloudify

Le déploiement dans le Cloud possède quelques difficultés propres dont nous allons discuter dans cet article. Nous aborderons en particulier l’automatisation des déploiements qui permet de gagner en agilité mais aussi de diminuer sa facture pour un environnement qui ne fonctionne pas en 24×7.

Dans cet article nous expliquons comment l’outil devops Cloudify nous a permis d’automatiser le déploiement de notre application et de tous les middlewares dont il dépend. Il nous a permis aussi d’automatiser certaines tâches d’administration telles que les backups de la base de données. De plus, Cloudify offre des fonctionnalités de monitoring, d’auto-réparation et d’auto-scaling qui permettent d’adapter notre application dynamiquement.

Contexte

Devoxx France, le salon de développeurs qui se tenait une fois de plus à Paris cette année 2013, a compté parmi ses sponsors FastConnect. Dans une optique d’animation de notre stand, nous avons développé une application mobile nommée Fastcontest, un quiz en ligne avec des cadeaux pour les gagnants.

Pour sa réalisation, nous avons mis en œuvre plusieurs des technologies dont nous avons l’expertise au sein du pôle Cloud de FastConnect : Java, Spring, HTML5, méthodologie Scrum, bases NoSQL, Cloudify, etc. Le déploiement en production a été effectué grâce à Cloudify sur Amazon EC2 (le choix d’un cloud publique s’imposait du fait de la faible qualité de l’accès Internet dans nos locaux…) Le quiz, en plus d’offrir une activité ludique sur notre stand, nous a permis de montrer notre savoir faire, en particulier dans le domaine du Cloud Computing.

FastContestArchitecture

Cloudi-quoi?

Cloudify ! C’est une solution open source permettant de fabriquer son custom PaaS (une PaaS factory) éditée par GigaSpaces Technologies.
Cet outil permet d’effectuer un ensemble de tâches relatives au déploiement d’une application sur un cloud et à la gestion du cycle de vie de cette dernière. Il permet notamment :

  • l’automatisation du déploiement via des recettes (recipes)
  • une portabilité sur plusieurs cloud (EC2, OpenStack, Azure, etc. ou un data center “classique”) via la configuration d’un driver
  • la gestion des dépendances entre les différentes composantes de l’application
  • du monitoring
  • la gestion du failover et de l’élasticité
  • des tâches d’administration (via des custom commands)

Toutes ces routines sont décrites dans différents scripts/recettes (recipes). Dans le cadre de notre application, nous utilisons majoritairement le langage de programmation Groovy, mais nous nous servons aussi quelques fois de scripts Bash.

Le principal outil entre le développeur et le cloud où il déploie est le shell Cloudify. Il existe aussi une interface Web très ergonomique qui permet notamment de visualiser toutes les recettes, l’état des déploiements, les alertes et les métriques remontées par le monitoring applicatif.

Mais on ne saurait parler de scripts sans toutefois parler de tests et de debug ! Mais comment faire ? Faut-il utiliser le cloud d’Amazon chaque fois que nous voulons tester nos scripts ? Même en phase de développement et compte tenu de son coût ? Ce sont là des questions que nous nous sommes posées lors de cette phase du projet. Nous évoquerons la solution adoptée un peu plus bas dans l’article.

FastContest : les différentes briques

Revenons à notre mouton: notre application de Quiz. Elle est composée de trois tiers :

  1. une base de données
  2. une API REST pour les fonctions du jeu
  3. un front HTML5

L’API REST

L’API REST étant un projet Web, nous avons eu besoin d’un serveur d’application, en occurrence Apache Tomcat. Pour la base de données, nous avons choisi MongoDB dont nous avons l’expertise (nous sommes partenaire 10gen).

Le frontEnt Sencha

Nous avons opté pour le framework Sencha Touch pour développer le frontend mobile de notre application. Du point de vu serveur, l’application mobile est un contenu statique, nous avons choisi de l’héberger dans un serveur Apache HTTP.

Soulignons au passage que les tests de performance ont été effectués avec Gatling, pour lequel nous avons aussi créé une recette Cloudify. Nous publierons un article dédié sur ce sujet…

Si nous faisons un résumé des briques constitutives de notre application de quiz, nous recensons les services (tiers) suivants :

  • Une base de données NoSQL : MongoDB
  • Un serveur d’application : Apache Tomcat
  • Un serveur Web : Apache HTTPD avec mod_proxy_balancer pour des problématique de load-balancing et de redirection.
  • Gatling

Les Recipes Cloudify (recettes)

À chaque service correspond une recette, qui décrit un certain nombre d’informations et/ou de configuration dudit service :

  • L’identité du service sur le cloud : nom, icône, template de machine à utiliser, …
  • Le cycle de vie : on peut greffer n’importe quel comportement à chaque évenement (install, start, stop, …) via un script Groovy, Shell ou MS-DOS
  • Les custom commands : permettant de définir des actions que nous pourrons effectuer sur chaque instance du service après son déploiement. Exemples pour un service Tomcat : update du war, archivage des logs, …
  • Monitoring applicatif : Cloudify permet de remonter n’importe quel métrique. On peut l’afficher dans l’interface Web ou l’utiliser pour configurer une alerte ou une règle d’auto-scaling.
  • détection de panne : en cas de panne, Cloudify peut relancer le service défaillant automatiquement.
  • élasticité : le nombre d’instances d’un service peut varier dans le temps, suite aux pannes, auto-réparation ou bien pour répondre à un burst. Cloudify permet de définir des règles d’auto-scaling.

Voici un extrait de notre recette Tomcat :

service {
  name "tomcat"
  icon "tomcat.gif"
  type "APP_SERVER"
  // ...

  lifecycle {
    install     "tomcat_install.groovy"
    postInstall "tomcat_postInstall.groovy"
    preStart    "tomcat_preStart.groovy"
    //...
  }

  customCommands ([
    "updateWarUrl" : { warUrl -
      context.attributes.thisService["warUrl"] = "${warUrl}"
      return true
    },
    "updateWarFile" : "updateWarFile.groovy"
  ])
  //...
}

Une application, au sens de Cloudify, est un ensemble de services (ou tiers) ayant des dépendances entre eux. Déployer une application signifie donc déployer tous ses services, dans un ordre convenable, et assurer l’injection des informations requises entre chaque couche.

Voici un extrait de la recette de notre application FastContest :

application {
  name "fastcontest"
  service {
    name = "mongod"
    compute {
      template "MONGO_TEMPLATE"
  }
}
service {
  name = "apacheLB"
  compute {
    template "APACHE_TEMPLATE"
  }
}
service {
  name = "tomcat"
  dependsOn = [ "mongod", "apacheLB" ]
  compute {
    template "TOMCAT_TEMPLATE"
  }
}
//...
}

Nous pouvons constater dans cet extrait que le service « tomcat » dépend des services « mongod » et « apacheLB ». En effet, tomcat a besoin des paramètres provenant du service mongod (adresse IP de la VM sur laquelle il est déployé par exemple) pour rendre l’application – ou du moins l’API REST – fonctionnelle ; et devra enregistrer son « end-point » auprès du service ApacheLB afin que ce dernier puisse mettre à jour sa configuration de load balancing.

Coder des recipes : les aspects à prendre en compte

Tout au long du projet, nous avons identifié quelques aspects primordiaux à prendre en compte dans les recettes Cloudify.

La clarté du code :

La première règle de programmation s’applique aussi aux scripts : faire simple. Le code doit être clair aussi bien dans sa forme que dans son fonctionnement (KISS).

Sonar est un outil d’analyse de qualité du code source. Il existe un plugin pour Groovy. Aussi nous avons mis tous nos scripts dans notre software factory afin de profiter de nos outils préférés.

Opérations à automatiser :

Il est nécessaire de recenser au préalable les différentes opérations à effectuer. Il s’agit notamment de lister les configurations nécessaires et de déterminer à quel moment du cycle de vie du service les appliquer : postInstall, start, postStart, ou bien en tant que custom command appelée depuis un autre service.

Un exemple. Dans notre cas le service Tomcat a besoin de communiquer le end-point (IP + context) de notre API REST au serveur HTTPD qui sert aussi de load-balancer. Il faut noter que le nombre d’instances de Tomcat – et de notre API REST – est variable et peut même changer dynamiquement si l’on a configuré des règles d’autoscaling.

Pour ce faire, nous avons créé une custom command nommée « addEndPoint » dans la recette d’ApacheLB, et cette commande est appelée par chaque instance de Tomcat lors de leur phase postStart.

Les custom commands sont une fonctionnalité très importantes de Cloudify. Elles permettent de coder des tâches d’administration (dump des logs, etc.) mais aussi de gérer des événements pour mettre à jour sa propre configuration. Ceci nous mène à un autre point : l’adaptation des services…

Adaptation des services à l’environnement

Nous entendons par là que les recettes doivent permettre aux différents services de prendre en compte les éventuels changement dans leur environnement et mettre à jour le service en conséquence. Ceci est particulier à la dynamicité d’un environnement Cloud où l’on peut être amené à gérer un changement d’adresse IP ou l’augmentation du nombre d’instances…
Cette notion d’adaptation en elle même est très large, et intègre d’autres notions telles que le « failover » et la « scalabilité ».

Fail-over

On désigne par là la capacité du système à se remettre d’une ou plusieurs pannes. Cloudify nous facilite la tâche : grâce aux détecteurs de fautes que nous définissons dans le script de description du service, Cloudify génére une alerte et il est capable de lancer des actions réparatrices : simple redémarrage du service, réinstallation ou ré-déploiement de la machine et du service.

Il est donc important d’écrire des recettes prenant en compte cet aspect, afin de d’assurer le meilleur comportement possible dans tous les cas (leak applicatif, bug Tomcat, crash d’une VM, etc.)

Scalabilité

Une fois de plus, Cloudify nous fournit un énorme coup de main dans cette problématique. Il permet de gérer l’élasticité d’un service de deux façons :

  • Manuellement : Si nous avons défini notre service en tant que « service élastique », alors nous avons la possibilité, via le shell Cloudify, d’augmenter ou de diminuer son nombre d’instances (le paramètre « maxAllowedInstances » nous protège contre une mauvaise manipulation).
  • Automatiquement : Cloudify permet, par l’intermédiaire de règles d’autoScaling, de définir une politique qui permettra de jouer dynamiquement avec le nombre d’instances du service. En général la politique d’autoscaling se fonde sur une des métriques applicative que l’on monitore.

Cette liste n’est pas exhaustive, et s’agrandira certainement avec l’expérience.

Déployer en environnement de Développement / Test

Tester notre application directement sur Amazon EC2 peut se révéler extrêmement couteux. Rappelons que par défaut, Amazon facture les machines à l’heure et que tout heure commencée est due. C’est pourquoi il faut éviter de déployer son application sur Amazon, de l’éteindre, de corriger une ligne et de recommencer. Ce qui est pourtant si facile quand on a tout automatisé…

Pour répondre à cette problématique, un expert Cloud de FastConnect, Mathias KLUBA, a développé un driver VirtualBox pour Cloudify. Grâce à ce driver, nous pouvons donc créer un cloud de VM VirtualBox sur notre machine de développeur et tester ainsi nos scripts Groovy en toute tranquillité. Vous trouverez un article sur ce driver : Driver VirtualBox pour Cloudify.

Pour information FastConnect est en train de construire un cloud interne OpenStack qui servira notamment lors de nos développements internes. Si vous avez besoin d’expertise sur OpenStack, contactez-nous ;-)

En production

Pour le passage en production, nous déployons sur le cloud d’Amazon EC2. Et là, on se dit « Vive Cloudify !! » car pas besoin de changer quoi que ce soit dans nos recettes, on remplace le driver VirtualBox par le driver Amazon EC2 et tout fonctionne.

Automatiser les déploiements et certaines actions d’administration

Pour pouvoir déployer sur l’environnement de Production de manière automatisée, en prenant les derniers packages à déployer, nous avons utilisé Jenkins.
Grâce à des scripts Groovy dans Jenkins, et l’API REST de Cloudify, nous avons pu déployer en 1 click sur Amazon (et détruire en 1 click). La procédure est la suivante :

  • Le matin, on exécute le job “Deploy” pour déployer l’application en 1 click
  • Le soir, on exécute le job “Undeploy” qui va:
    • Exécuter la “custom command” Dump du service MongoDB. Cette commande va faire un Dump de notre base, zipper et stocker dans S3.
    • Exécuter “uninstall-application” pour détruire l’application et les VMs utilisées.
  • Le lendemain, on exécute le job “Deploy” pour re-déployer l’application, ce qui va:
    • Exécuter “install-application” pour déployer l’application sur Amazon EC2.
    • Exécuter la “custom command” RestoreDump du service MongoDB. Cette commande télécharge le dernier dump depuis S3 pour le restaurer.

Pour des problématiques de supports, Jenkins exécute aussi régulièrement des “dump” de la base ainsi que des logs.

Dans notre cas le volume des données était faible, aussi un simple dump de MongoDB était très efficace. Un SnapShot de l’EBS aurait été plus intéressant si le volume avait été plus important.
L’opération de Dump n’était pas nécessaire tout au long de la journée puisque nous utilisions un ReplicatSet pour la résilience (et Cloudify est capable de re-démarrer les instances et les VMs après un crash)… Mais nous ne voulions prendre aucun risque :)

Conclusion

Au terme de cet article, nous avons mis en œuvre un bon nombre de technologies et d’outils relatifs au Cloud, et avons vu les différentes possibilités qu’ils offraient.
Nous constatons en particulier, que le déploiement d’une application sur un cloud et la gestion de son cycle de vie sont véritablement simplifiés grâce à Cloudify. Cependant, le mot « simplification » ne doit pas nous nous entraîner à la relâche ! En effet, les recipes étant le cœur de toute ces procédures automatisées, il ne faut pas négliger l’effort nécessaire pour produire des recettes de bonnes qualités.

Rendez vous au Devoxx France 2013

Si vous êtes un peu geek (ça doit être le cas, car vous êtes sur notre blog :)) et si vous surfez sur le web pendant votre temps de travail (?? :) ), vous savez certainement que le Devoxx France aura lieu le 27 mars prochain. Et comme pour la 1ère édition, FastConnect fait de nouveau parti des sponsors de cet événement.

Et une fois de plus, nos consultants se plient en 4 (ou en 2 .. ça dépend de l’agilité de chacun :)) pour vous préparer une petite surprise ici.

Donc rendez vous sur notre stand ou sur cette page à partir du 27 mars.

On vous attend ! Comment ? Vous n’y allez pas ? Oh .. vous allez nous manquer :(…. Mais rassurez-vous, vous pouvez toujours venir nous voir sur notre stand au BreizhCamp 2013, une conférence chez les bretons pour les bretons et les non bretons dont FastConnect est également sponsor.

A bientôt…