Une session présentée par Brian Calder.

Ironiquement, une coupure de courant en début de session provoque un retard de 10 minutes pendant que l’on redémarre les machines! Aurait-on évité ce problème en utilisant PowerPoint dans les nuages plutôt que sur un PC posé sur l’estrade?

Les sujets:

  • Haute disponibilité
  • Montée en charge
  • Gestion du cycle de vie

Agenda:

  1. Montée en charge des données
  2. Montée en charge du compute
  3. Mises à jour et montées de versions

Storage

Au départ on a du cache volatil (AppFabric Cache, memcached, …) et du stockage persistant Blobs Tables Queues Drives, plus SQL Azure.

  • Blobs: interface simplepour stocker des fichiers nommés
  • Tables: stockage structuré: entités + propriétés
  • Queues: délivrer des messages de façon fiable aux applications

Storage Account: 100 To de capacit��, jusqu’à quelques centaines de Mo/s, ou quelques milliers de requêtes par seconde. L’on peut également utiliser le Content Delivery Network pour cacher les contenus dans 18 centres dans le monde.

Les objets sont groupés dans des partitions et ces partitions sont réparties sur les serveurs. Les partitions sont surveillées afin d’être réorganisées automatiquement en fonction de la montée en charge. Des serveurs (“back end”) constituent un vaste système de fichiers distribué. Les partitions sont allouées à des serveurs, et l’on peut les déplacer sans copie de données. Quand un serveur devient surchargé, le système de surveillance peut réallouer des partitions à d’autres serveurs afin de répartir la charge. L’opération de transfert ne prend que quelques secondes. La décision de réallouer est faite après quelques minutes d’observation d’un pic.

Ce système de répartition est au coeur de la montée en charge Windows Azure.

Quelle PartitionKey est utilisée pour partitionner les données?

  • Blobs: le nom du blob, ce qui permet de répartir les blobs automatiquement
  • Messages: le nom de la Queue
  • Entités: c’est l’application qui définit la PartitionKey

Performances:

  • 500 transactions/s pour une Queue ou une partition de Table
  • pour un Blob: 30 Mo/s à 60 Mo/s en fonction de la taille du Blob.
  • Latence d’environ 100 ms pour de petites transactions.

Pour diminuer la latence, ajouter une couche de cache type AppFabric ou memcached pour redescendre à 10 ms.

Compute

On a des rôles Worker & Web et le modèle de service permet de définir les rôles, la topologie, le nombre d’instances, etc.

Le nombre d’instances permet évidemment de gérer la haute disponibilité: l’on multiplie les instances pour les rôles Web & Worker. L’on peut ajouter des instances en cours de route.

Une application typiquement va prendre une liste de tâches à accomplir, la diviser en morceaux et distribuer aux Workers. Dans ce cas, l’on va utiliser les Queues pour distribuer les messages.

Délivrance garantie: lorsqu’un Worker traite un message, le message devient invisible pendant un certain temps. Si le Worker finit de traiter le message, il le retire. Si le Worker échoue, le message ré-apparaît au bout d’un certain temps et pourra être traité par un autre Worker.

Par contre, dans ce cas un message peut potentiellement être consommé plusieurs fois. Il faut donc que les tâches soient idempotentes (répétables).

D’autre part, les messages ne sont pas forcément consommés dans l’ordre.

Pour mieux contrôler ce processus, l’on peut avoir un Job Manager qui envoie les messages, distribue la charge, surveille l’avancement du processus, etc. Par exemple, quand une tâche est constituée d’un message + un Blob, c’est le Job Manager qui peut gérer ces aspects.

Brian revient sur le cas de RiskMetrics, qui utilise un Job Manager répartissant des tâches sur 2.000 Worker Roles, et bientôt 10.000 Worker Roles.

Pour des traitements longs, l’on peut utiliser une table additionnelle pour suivre le progrès du traitement et le reprendre et cas d’interruption.

Cycle de vie

Mises à jour “en place” par roulement: pour mettre à jour un ensemble de rôles de façon contrôlée. L’on crée des Upgrade Domains dans lesquels on répartit uniformément les différents rôles. Cela permet de déployer des nouveaux binaires “par roulement” et donc maintenir la disponibilité du système, au lieu de déployer et éventuellement redémarrer tous les rôles en même temps.

Bien prendre le soin de tout versionner (protocoles, schémas, etc.) car l’on peut avoir deux versions tournant en parallèle. Par exemple, dans le cas de communication inter-rôles et d’une évolution du protocole de communication, l’on va d’abord déployer une version interédiaire comprenant l’ancienne et la nouvelle version du protocole afin que les noeuds puissent continuer à communiquer durant la mise à jour par roulement.

Dans le cas d’un changement de schéma d’une table Azure, on prévoit une propriété “version” dans chaque entité. Si l’on ajoute un propriété au schéma, l’on va déployer une version intermédiaire qui comprend le schéma V1 et V2 et utilise des valeurs par défaut pour la nouvelle propriété. Le client de la version originale utilise “IgnoreMissingProperties” pour ne pas être impacté par la nouvelle propriété. Une fois la version intermédiaire entièrement déployée, on passe sur la vraie mise à jour, qui comprend le schéma V2 et qui peut mettre à jour les entités avec les vraies valeurs.

Dans le cas de changement de PartitionKey/RowKey (plus invasif) l’on peut prévoir de passer par une nouvelle table.

DSC05613