Les Grilles informatiques

Partie 2: middleware

Stéphane Genaud

Middleware pour les grilles

Les Grilles sont construites sur une base logicielle de type Middleware (ou intergiciel), i.e. interface entre les OS et les applications.

Les intergiciels pour Grilles permettent de déployer une large classe d'applications distribuées (≠ applications dédiées comme SETI@Home) et proposent un modèle de programmation.

Quelques projets caractéristiques :

Middleware pour les grilles

Les intergiciels pour grilles fournissent souvent des fonctionnalités supplémentaires: des services répondant aux besoins des tuilisateurs de grilles.

Identification

OGSA

OGSA

A base de Web service. Un web service :

OGSA propose d'utiliser les recommandations existantes du W3C : XML, SOAP, WSDL, UDDI, ....

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

Exemple de Service

Ex. requete

DIET

DIET est une plate-forme hiérarchique développée à l'INRIA. Elle est orientée Application Service Provider (ASP) et son modèle de programmation est Grid-RPC. Elle permet à des clients de soumettre une requête prise en charge par un serveur de la plate-forme.

Cet intergiciel peut être rangé dans la catégorie des Network Enabled Servers (NES). (Ninf, Netsolve, ...)

Problématiques:

DIET

DIET archi

ProActive

ProActive est un projet INRIA, Nice.
ProActive Logo Objectifs: développer une librarie permettant le développement d'applications sur Grille.

Caractéristiques:

ProActive

Idée forte: accès transparent aux objets pour le programmeur.
ProActive iobjects

ProActive - objets

Les objets actifs implémentent les accès à distance de manière transparente.

active objects

  ClasseC {
   ...
   public float calcul(...);
   ...
  }
  ...
  A.calcul(); // calcul peut être 
              // exécuté à distance

ProActive - objets - création

Création d'un objet actif avec ProActive.newactive().

  Classe a;
  Object[] params = new Object[] { new Integer (26), "astring" };
  try {
    a = (Classe) ProActive.newActive("example.Classe", params);
  } catch (ActiveObjectCreationException e) {
    e.printStackTrace();
  }

L'appel à une méthode de a provoque la copie par valeur des paramètres et la requête est mise dans la file d'attente de a.

Ici, a est créé dans la JVM d'origine (locale).

ProActive - objets - création

Création d'un objet actif distant.

  a = (Classe) ProActive.newActive("example.Classe", 
                    params, "rmi://pluto.inria.fr/aNode");

  //ou 

  Node node = NodeFactory.getNode("rmi://pluto.inria.fr/aNode");
  a = (Classe) ProActive.newActive("example.Classe", params, node);

Note: on peut "rendre actif" un objet ordinaire après sa création avec turnActive().

    Classe a = new Classe (26, "astring");
     ....
    a = (Classe) ProActive.turnActive(a,node);


Placement des objets actifs sur un Node, élément d'un VirtualNode. Un descripteur de déploiement donne :

ProActive - déploiement

Créé un noeud appelé Dispatcher qui sera placé dans la JVM jvm1.

<ProActiveDescriptor 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="DescriptorSchema.xsd">
<componentDefinition>
  <virtualNodesDefinition>
    <virtualNode name="Dispatcher"/>    
  </virtualNodesDefinition>
<componentDefinition/>
<deployment>
    <mapping>
      <map virtualNode="Dispatcher">
      <jvmSet>
         <vmName value="jvm1"/>
      </jvmSet>
      </map>
    </mapping>
    <jvm name="jvm1"> 
      <creation>
        <processReference refid="jvmProcess"/> (décrit dans la partie infrastructure)
        </creation>
    </jvm>    
</deployment>
</ProActiveDescriptor>	

ProActive - déploiement

Extrait de code typique:

ProActiveDescriptor pad = ProActive.getProactiveDescriptor(String xmlFile);

//--------- Returns a ProActiveDescriptor object from the xml file
VirtualNode dispatcher = pad.getVirtualNode("Dispatcher");

//-------- Returns the VirtualNode Dispatcher described in the xml file as a java object 
dispatcher.activate();

// -------- Activates the VirtualNode
Node node = dispatcher.getNode();

Un VirtualNode peut regrouper plusieurs JVM.

Une JVM peut héberger, un ou plusieurs Nodes.
Dans le cas d'un cluster, on associe généralement n JVM avec nNodes.

Le détail des possibilités de configuration: [ html ].

ProActive - groupes

Les méthodes les plus utilisées pour la gestion de groupe sont fournies par la classe ProActiveGroup. Ces groupes sont typés (éléments de même classe ou plus abstraits).

Par exemple, pour la création d'un groupe:

  Classe ag = (Classe) ProActiveGroup.newGroup("Classe", params[], 
                   {rmi://globus1.inria.fr/Node1,
                    rmi://globus2.inria.fr/Node2});

ProActive - groupes

Les groupes permettent de déclencher des appels de méthode en parallèle.

Soit la classe C:

  class C {
     R calcul(P p) { ... }  
     ...
  }

On peut former un groupe G d'objets actifs de type C, et invoquer la méthode calcul() sur chaque élément du groupe (map).

  C groupeDeC  = (G) ProActiveGroup.newGroup("C",params,nodes);
  P p; 
  R r = groupeDeC.calcul( p );

Autant d'appels asynchrones calcul() sont déclenchés qu'il n'y a d'éléments dans groupeDeC.

ProActive - communications collectives

Les groupes permettent les communications collectives.

  C groupeDeC  = (G) ProActiveGroup.newGroup("C",{o1,o2,o3},nodes);
  R r = groupeDeC.calcul( p );

  r.uneMethodeDeR();

Les 3 appels à uneMethodeDeR() seront effectués au fur et à mesure que r se remplit.

On peut exprimer une synchronisation totale:

ProActive.waitForAll(r);
ou parrtielle:
R tmp = ProActive.getOne( r );
tmp.uneMethodeDeR();

ProActive - synchros

static void waitAll(java.lang.Object o)            attend que tous les résultats soient arrivés.
static java.lang.Object waitAndGetOne(java.lang.Object o)           Waits for one future is arrived and get it.
static java.lang.Object waitAndGetOneThenRemoveIt(java.lang.Object o)            attend l'arrivée d'un résultat et retourne ce résultat.
static java.lang.Object waitAndGetTheNth(java.lang.Object o, int n)           Waits for the N-th future is arrived and get it.
static void waitN(java.lang.Object o, int n)           Waits n futures are arrived.
static void waitOne(java.lang.Object o)           Waits for (at least) one future is arrived.
static int waitOneAndGetIndex(java.lang.Object o)           Waits that at least one member is arrived and returns its index.
static void waitTheNth(java.lang.Object o, int n)           Waitd for the N-th future in the list is arrived.

ProActive - communications collectives

Les groupes permettent les communications collectives.

Quand un groupe est passé en argument d'une méthode appliquée sur groupe, le paramètre est diffusé à tous les objets actifs du groupe.

  G g = (G) ProActiveGroup.newGroup("G",params,nodes);
  
  Data mydata  = (Data) ProActiveGroup.newGroup("Data",{data1,data2,data3},nodes);

  g.calcul(mydata); // chaque élem. de g recoit mydata en entier

Au lieu

  G g = (G) ProActiveGroup.newGroup("G",params,nodes);
  Data mydata  = (Data) ProActiveGroup.newGroup("Data",{data1,data2,data3},nodes);
  
  ProActiveGroup.setScatterGroup( mydata );
  g.calcul( mydata ); // chaque élem. de g recoit un objet de mydata