JUG Montpellier : session sur Google Application Engine

Comme vous savez, Oxiane Méditerranée sponsorise le JUG Montpellier et donc il est intéressant pour moi de faire un retour sur la dernière session du JUG Montpellier sur Google Application Engine présentée la semaine dernière.

Cette session a été présentée par Martin Delemotte, co fondateur de Kazelys et créateur du site http://www.vadequa.com.
« Vadequa est un site de rencontre entre particuliers et entreprises. »
C’est un site web du type Meetic Affinity entre particuliers et entreprises pour connaître le degré d’adéquation d’un candidat à une entreprise.

Le gros intérêt pour le sujet du jour est que ce site a été créé sur la plate-forme GAE avec plus d’un an de développement.

 

Ce que je retiens de cette soirée,

  • un certain nombre de bonnes pratiques sont à mettre en place s’il l’on ne veut pas se casser les dents,
  • une explication claire mais forcément rapide des grands composants de la plate-forme,
  • la phrase de Martin qui restera sûrement à la postérité « Chaque seconde, une machine meurt dans le Cloud« , et nous allons voir que ce n’est pas sans incidents …

Un petit rappel sur GAE :  Google Application Engine est une PAAS (Plate-forme As A Service) visant à être scalable.
ou dit autrement un service d’hébergement d’applications web dans les nuages visant avant tout à répondre à de nombreux clients simultanés sans dégradation de performance.

 

Cette plate-forme possède un certain nombre de contraintes notamment pour assurer cette scalabilité.

  • sur les threads, les API Java, les accès file systèm et les accès réseau,
  • des requête de 30s maximum, avec 1 seule écriture par seconde et par entité est garantie (la réalité est plutôt de l’ordre de 10 écritures par seconde),
  • les caractéristiques des instances sont inconnues, mais c’est vrai ce n’est justement pas notre problème.

 

Pour assurer la persistance de ses données, GAE s’appuie sur un datastore qui est implémentée par une BigTable Google, du pur NOSQL.
Une BigTable peut être vue comme une hashtable géante distribuée contenant des entités java.
Elle ne comporte pas de schéma.

Les données peuvent être répliquées sur plusieurs DataCenters.

 

Il y a 2 grands types de réplications :

  • Master slave Datastore

Le client communique uniquement avec l’instance Master sauf si celle-ci crash.
Dans ce cas, l’instance slave devient Master et une nouvelle instance slave est utilisée.
Ce mode de réplication devrait être abandonnée à terme par Google pour des problèmes sur la disponibilité et la latence des données.

  • High Replication Datastore

Le client écrit en synchrone sur 3 DataCenter simultanément.
Ce mode de réplication permet d’avoir une haute disponibilité et fiabilité des données.
Mais il coûte plus cher que l’option maître / esclave.

Plus d’infos sur http://code.google.com/intl/fr/appengine/docs/python/datastore/hr.

En tout cas cette problématique de réplication me rappel très fortement les tests que j’ai effectué sur la haute disponibilité des données avec Oracle Database en mode Dataguard ou en mode RAC.

 

Pour accéder au datastore, il est possible d’utiliser JDO ou JPA possible mais avec quelques spécificités … et souhaitable d’utiliser par exemple Objectify, qui est un framework permettant de simplifier la persistance de données et leurs manipulations dans Google App Engine, il rajoute une couche d’abstraction facilitant énormément les différentes interactions (par rapport à l’API bas niveau Google App Engine/J).

Il est possible de faire directement des requêtes GQL mais attention pas de join, de filtre, de like, …

 

Pour les transactions, il n’est pas possible de faire des transactions entre entités sauf au sein d’un Entity Group.
Un Entity Group est une entité hiérarchisée localisées sur le même noeud d’un datastore (très important dans le cas du High Replication Datastore).
Ce qui amène ici à des points essentiels dans l’utilisation de Google App Engine, c’est qu’il faut penser à son modèle pour qu’il soit scalable dès la conception et notamment à ses notions d’Entity Group.

Un petit exercice donné par Martin : soit une entité Candidature, doit-elle être dans le même Entity Group que l’entité Candidat ou que l’entité Entreprise ou que l’entité racine ?
Quelques secondes de réflexion …
La première réponse est la bonne, en effet le nombre de candidatures va être directement lié au nombre de candidats donc pour pouvoir assurer la montée en charge, il faut les regrouper dans un même Entity Group.

 

La scalabilité est le but à atteindre et ceci se fait au détriment de la performance, par exemple le datastore est lent (25-100ms) pour un get, (50-160) pour un put.

Alors comment réduire le temps de réponse ?
En utilisant par exemple Memcache qui est un cache distribué (une seule instance) mais attention les données y sont volatiles et peuvent y être enlevées n’importe quand. Le rechargement de ces données doit donc être prévue.
Ce cache n’est bien sur pas transactionnel (sauf putIfUntouched de manière atomique, je vous laisse encore une fois voir pour les détails) ou d’utiliser le « cache » JVM par des données static mais attention il est très volatile car le changement d’instance est fréquente. De toute façon je déconseille toujours de mettre des données en static non maîtrisées si l’on veut éviter les fuites mémoires (dans GAE cela sera a priori peu probable).

D’autres techniques sont possibles : grouper en parallèle les requêtes au datastore, gérer par des tâches de fond en asynchrones, ou encore dé-normaliser en créant des entités intermédiaires et les re-synchroniser par des taskqueue
Exemple : candidature liés à 3 entités candidat, dossier, … et on ne va manipuler que ses entités intermédiaires.

 

Pour en revenir à la vraie vie, il faut savoir que le taux d’erreur quotidien est plus élevé que sur un serveur individuel, d’où la phrase « Chaque seconde, une machine meurt dans le Cloud » et son implication : le code doit prévoir les interruptions de services (taskqueue, memcache) … et là je vous laisse imaginer au cas pas cas les solutions …

Quelques mots sur le support et les prix :
Le support est réalisé par les équipes SRE (Site Reliability Enginneer) mais il faut compter 500$/mois pour un compte premium.
La version gratuite qui a fait débat il y a quelque temps lié au resserrement important sur les quotas. En effet avant, une application avec un trafic de 5 millions de pages pouvait être gratuite maintenant les quotas en gratuit suffisent juste pour une application avec un faible traffic.
Et donc on arrive à la formule payant à partir de 9$/mois min et plus en fonction des quotas. Pour tout savoir : http://www.google.com/enterprise/appengine/appengine_pricing.html

La Roadmap pour ce qui est du plus important : le SSL et le Like dans les requêtes (ouf).

Pour conclure, c’est une plate-forme scalable mais dès la conception / développement il faut avoir en tête les différentes contraintes.
Et à la question, malgré les difficultés rencontrées, est-ce que ta prochaine application sera réalisée avec GAE, Martin a répondu oui, d’autant qu’il sait maintenant comment éviter les quelques pièges de la plate-forme. Comme quoi l’expertise à un coût !!!

Emmanuel PAVAUX