Tags:
create new tag
, view all tags

Introduction

eXist (http://exist.sourceforge.net) est une base de données XML native, Open Source et entièrement écrite en Java. Elle possède plusieurs fonctionnalités :

  • indexage automatique des noeuds
  • requètes XQuery (working draft 1.0 compliant)
  • recherche en mode texte
  • gestion des utilisateurs (droits d'accès...)

eXist peut être utilisé de plusieurs manières :

  • comme une application java indépendante (serveur eXist en stand-alone)
  • intégré à une application java existante
  • comme une application Web (avec Tomcat par exemple)

Organisation des données

Une boîte noire...

eXist doit être configuré pour pointer vers un répertoire où sont stockées les données XML. Un tel répertoire contient les fichiers : collections.dbx, dom.dbx, elements.dbx, symbols.dbx et words.dbx. Ces fichiers se comportent comme une boîte noire, i.e. que l'on ne va jamais agir directement dessus pour ajouter des fichiers XML à la base. Je n'ai pas trouvé comment sont structurés ces fichiers mais il est clair que tout est fait pour optimisé la recherche dans la base. Les indexations mises en oeuvre sont les suivantes :

  • indexation structurelle (relations parents/enfants...) pour les noeuds de type élément et attribut
  • indexation textuelle pour les noeuds de type text et valeur d'attribut

Une organisation hiérarchique

Une base de données eXist est composée de fichiers XML organisés en "collections" hiérarchiques (une collection peut être comparée à un répertoire). Une collection peut contenir des fichiers XML et d'autres collections. La collection racine est /db et ne peut être modifiée. Pour le reste c'est à l'administrateur de créer l'arborescence voulue. eXist propose une interface très intuitive pour naviguer dans les collections, consulter les fichiers XML et en ajouter de nouveaux.

Communiquer avec le serveur eXist

Lorsque je parle de serveur eXist je parle à la fois du serveur en mode stand-alone et de l'application Web eXist. Dans le deuxième cas les requètes sont en fait envoyées au servlet engine (Tomcat...) qui les relayera aux servlet de l'application Web eXist.

Il y a trois moyens d'accéder à eXist :

  1. REST (accès HTTP)
  2. XML-RPC (accès HTTP)
  3. SOAP (accès HTTP)

Nous pouvons remarquer que dans les trois cas le protocole de transfert est HTTP.

Avec REST nous pouvons effectuer les opérations courantes sur la base (ajout de fichiers, requètes XQuery...), mais pas de gestion des utilisateurs pour des raisons de sécurité. En effet REST s'appuie sur un HTTP GET qui passe en clair dans l'URL de la requète. Avec XML-RPC et SOAP toutes les opérations sur la base sont possibles et sécurisées. En effet ces deux protocoles s'appuient sur un HTTP POST.

Je vais maintenant parler de ces différents accès pour les deux déploiements possibles (serveur stand-alone et en application Web).

Mode stand-alone

Dans ce mode un serveur eXist stand-alone tourne et écoute sur deux ports : 8081 pour accueillir les requètes HTTP REST et 8088 pour les requètes HTTP XML-RPC.

Pour communiquer via l'interface REST un navigateur suffit. L'URL

http://localhost:8088/db?_query=//Resources

va par exemple interroger le serveur eXist sur son interface REST pour lui demander tous les éléments "Resources" présents dans sa base. La classe java utilisée est org.exist.http.RESTServer.

Pour communiquer via l'interface XML-RPC il est possible d'utiliser le client Java fourni. Ce dernier possède une interface graphique et permet d'effectuer toutes les opérations possibles sur la base. Il s'appuie sur l'API Java XML:DB pour effectuer ces opérations et dois être je pense l'outil privilégié pour accéder à la base en mode standalone.

L'interface SOAP n'est pas disponible dans ce mode.

Mode application Web

Dans ce mode eXist est encapsulé dans un servlet engine et fournit ses services grâce à des servlet. C'est donc via un navigateur que toutes les requètes seront effectuées.

Pour communiquer via l'interface REST il faut entrer une URL du type :

http://localhost:8080/exist/servlet/db/resources?_query=//Resources

localhost:8080 adresse le servlet engine, /exist adresse l'application Web eXist, /servlet est mappé sur le servlet accueillant les requètes REST et /db/resources?_query=//Resources est l'argument pour ce servlet.

Cette URL va en fait faire la même chose que celle destinée à interroger le serveur eXist standalone sur son interface REST.

Pour communiquer via l'interface XML-RPC, l'URL d'accès est :

http://localhost:8080/exist/xmlrpc

/xmlrpc est mappé sur le servlet eXist accueillant les requètes XML-RPC. On peut très bien imaginer accéder à ce servlet pour effectuer des opérations sur la base en se servant du client java dont j'ai parlé plus haut.

Pour communiquer via l'interface SOAP, l'URL d'accès est :

http://localhost:8080/services

/services est mappé sur le servlet AXIS prenant en charge l'interface SOAP. Deux services Web sont disponibles : /services/Query et /services/Admin chacun implémenté par un servlet. Pour récupérer le WSDL du service Web Query, il suffit de taper l'URL :

http://localhost/exist/services/Query?WSDL

Tests de performance

Avec la base Carnivore

Conditions

  • serveur eXist standalone pointant vers les données de Carnivore (cacheSize = 48Mo)
  • client java en ligne de commande pour effectuer les requètes

Pour ce test j'ai fait pointer le serveur eXist vers les données de Carnivore qui contient plus de 11300 enregistrements de ressources, dont 11079 de type TabularSkyService. Ce test est donc représentatif d'une situation réelle d'utilisation du registry. Les requètes sont faites dans l'environnement de la collection contenant seulement les ressources TabularSkyService. A noter que ces ressources utilisent l'ancien format UCD.

Utiliser le client java en ligne de commande permet de rediriger la sortie standard vers /dev/null et ainsi de mesurer seulement le temps pris par eXist pour répondre à la requète. Un tel test ne serait pas possible avec l'interface graphique car cette dernière formate le résultat XML et cela fausse les mesures de temps.

Résultats

Test 1 : récupération de toutes les ressources

//vr:Resource

  • durée : 1min46s
  • mémoire : 40Mo
  • proc : 100%

Notes :

Test 2 : récupération d'une ressource ayant un certain identifiant

//vr:Resource[vr:identifier/text()='ivo://CDS/VizieR/J/A+AS/123/575/levels3']

Le but est de mettre en avant le travail de recherche dans la base plutot que la quantité d'information voulue.

  • durée : 6s
  • mémoire : 25Mo
  • proc : 100%

Notes : bien plus rapide que le fait de récupérer toutes les ressources ! On s'apperçoit que la recherche est très efficace : 6s pour tester le champ "identifier" des 11000 ressources.

Test 3 : récupération des ressources ayant au moins une colonne possédant un certain UCD

//vr:Resource[vs:table/vs:column/vs:ucd/text()='PHOT_DIFF_MAG']

  • durée : 15s
  • mémoire : 65Mo
  • proc : 100%

Notes : la mémoire utilisée augmente avec la profondeur de recherche.

Test 4 : récupération des ressources ayant au moins une colonne possédant un UCD ou un autre

//vr:Resource[vs:table/vs:column/vs:ucd/text()="PHOT_DIFF_MAG" or vs:table/vs:column/vs:ucd/text()="PHOT_JHN_B-V"]

  • durée : 30s
  • mémoire : 70Mo
  • proc : 100%

Notes : le temps de recherche double si l'on rajoute une condition sur les UCD (deux test au lieu d'un)

Test 5 : récupération des ressources vérifiant une condition complexe au niveau des UCD

Nous allons maintenant utiliser une condition plus complexe au niveau des UCD, du type : "je recherche toutes les ressources possédant soit un couple d'UCD, soit un autre couple d'UCD".

  • durée :
  • mémoire :
  • proc :

Notes :

Avec une base perso

Conditions

J'ai créé un fichier XML contenant les 11079 ressources TabularSkyService de VizieR, avec les UCD au format UCD1+. Ceci est fait grâce à un programme java requétant la base Carnivore, extrayant les ressources TSS, transformant les UCD en UCD1+ grâce au Service Web de VizieR (je me sers du DOM pour agir sur les noeuds XML de la ressource) et écrivant la ressource modifiée dans un fichier au format UTF-8.

Puis j'ai introduit ce fichier dans une base eXist pour pouvoir faire des tests de performance. Les conditions sont les mêmes que pour les tests précédents avec les données de Carnivore.

Résultats

Test 1 : récupération de toutes les ressources

//vr:Resource

  • durée : 1min35s
  • mémoire : 40Mo
  • proc : 100%

Notes :

Test 2 : récupération d'une ressource ayant un certain identifiant

//vr:Resource[vr:identifier/text()='ivo://CDS/VizieR/J/A+AS/123/575/levels3']

Le but est de mettre en avant le travail de recherche dans la base plutot que la quantité d'information voulue.

  • durée : 4s
  • mémoire : 15Mo
  • proc : 70%

Notes : bien plus rapide que le fait de récupérer toutes les ressources ! On s'apperçoit que la recherche est très efficace : 4s pour tester le champ "identifier" des 11000 ressources.

Test 3 : récupération des ressources ayant au moins une colonne possédant un certain UCD

//vr:Resource[vs:table/vs:column/vs:ucd/text()='phot.mag;arith.diff']

  • durée : 10s
  • mémoire : 15Mo
  • proc : 100%

Notes :

Test 4 : récupération des ressources ayant au moins une colonne possédant un UCD ou un autre

//vr:Resource[vs:table/vs:column/vs:ucd/text()="phot.mag;arith.diff" or vs:table/vs:column/vs:ucd/text()="phot.color;em.opt.B;em.opt.V"]

  • durée : 35s
  • mémoire : 120Mo
  • proc : 100%

Notes : le temps de recherche double si l'on rajoute une condition sur les UCD (deux test au lieu d'un)

Test 5 : récupération des ressources vérifiant une condition complexe au niveau des UCD

Nous allons maintenant utiliser une condition plus complexe au niveau des UCD : "je recherche toutes les ressources ayant une description de position (soit en coordonnées équatoriales soit en coordonnées galactiques) et une mesure de flux à une fréquence constante pour toutes les sources".

//vr:Resource
   [
   (
    (vs:table/vs:column/vs:ucd/text()="pos.eq.ra" and vs:table/vs:column/vs:ucd/text()="pos.eq.dec")
    or
    (vs:table/vs:column/vs:ucd/text()="pos.galactic.lon" and vs:table/vs:column/vs:ucd/text()="pos.galactic.lat")
    or
    (vs:table/vs:column/vs:ucd/text()="pos.galactic.lon;meta.main" and vs:table/vs:column/vs:ucd/text()="pos.galactic.lat;meta.main")
   )
   and
   (
    ((vs:table/vs:column/vs:ucd/text()="phot.flux")
     or
     (vs:table/vs:column/vs:ucd/text()="phot.fluxDens")
    )
    and
    (
     (vs:table/vs:column/vs:ucd/text()="em.freq")
    )
   )
   ]

  • durée : 54s
  • mémoire : 240Mo
  • proc : 100%

Notes : 54 ressources ont été trouvées.

Test 6 : récupération des ressources vérifiant une condition complexe au niveau des UCD

Nous allons maintenant utiliser une autre condition complexe au niveau des UCD : "je recherche toutes les ressources ayant une description de position (soit en coordonnées équatoriales soit en coordonnées galactiques) et une mesure de flux à une fréquence variable pour les différentes sources".

//vr:Resource
   [
   (
    (vs:table/vs:column/vs:ucd/text()="pos.eq.ra" and vs:table/vs:column/vs:ucd/text()="pos.eq.dec")
    or
    (vs:table/vs:column/vs:ucd/text()="pos.galactic.lon" and vs:table/vs:column/vs:ucd/text()="pos.galactic.lat")
    or
    (vs:table/vs:column/vs:ucd/text()="pos.galactic.lon;meta.main" and vs:table/vs:column/vs:ucd/text()="pos.galactic.lat;meta.main")
   )
   and
   (
    (vs:table/vs:column/vs:ucd/text()="phot.flux;em.radio%")
    or
    (vs:table/vs:column/vs:ucd/text()="phot.fluxDens;em.radio%")
   )
   ]

  • durée : 59s
  • mémoire : 240Mo
  • proc : 100%

Notes : aucune ressource n'a été trouvée.

Comparaison

Il n'y a pas de différences notables. Il faut noter que la structure XML des ressources Carnivore est un peu plus compliquée (les ressources au sens VO sont encapsulées dans une structure registry - voir section Carnivore).

-- BriceGassmann - 16 Jun 2005

Topic revision: r8 - 2005-06-16 - BriceGassmann
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback