Optimisation de TileCache

Posté le 16 février 2008 par Guillaume Sueur

TileCache est un logiciel qui permet de créer un cache local d’une ressource WMS locale ou distante (du point de vue d’un serveur), afin d’en optimiser l’accès. Il est d’une simplicité déconcertante et d’une efficacité redoutable. Si l’installation et la mise en route sont faciles, il faut quand-même faire quelques réglages pour obtenir des performances optimales. Je vous propose donc un petit résumé de ces étapes, inspiré d’un tutoriel en anglais et de mon expérience personnelle.

  1. L’installation

Simplissime ! Récupérez une archive des sources sur le site de tilecache (http://www.tilecache.org/), et décompressez-la dans un répertoire publié sur le web (/tilecache dans ce qui suit).

Autorisez l’exécution des cgi pour ce répertoire :

<Directory /usr/local/apache2/htdocs/tilecache>
AddHandler cgi-script .cgi
Options +ExecCGI
</Directory>

Editez le fichier tilecache.cfg et spécifiez un répertoire de stockage des dalles, par exemple :

base=/usr/local/apache2/htdocs/tileFolder

(NB : ce répertoire doit exister et être accessible en écriture à l’utilisateur apache).

Vous pouvez déjà tester en chargeant la page http://nom_du_serveur/tilecache/. Vous devriez voir apparaître une interface OpenLayers avec une carte du monde. Vérifiez le contenu de votre répertoire de stockage, vous devriez y voir un sous-répertoire « basic », nom de la couche WMS chargée par défaut, contenant des sous-répertoires numérotés.

Arrivé là, vous êtes déjà en train de mettre en cache les couches WMS que vous exploitez. Le reste n’est donc plus qu’une question d’optimisation.

  1. La configuration des ressources WMS.

Vous avez sans doute d’autres données à exploiter que les données proposées par défaut. Pour cela, il faut rajouter ces entrées dans le fichier tilecache.cfg, en commençant par le nom de la ressource (layername) entre crochets. A noter que le nom que vous donnez à la ressource est complètement libre, mais que c’est lui que vous devrez utiliser lors des appels à TileCache, depuis OpenLayers par exemple. Voici un exemple complet de configuration d’une ressource :

[geosignal]
type=WMS
url=http://www.geosignal.org/cgi-bin/wmsmap
bbox=-50000,1200000,1400000,2700000
extent_type=loose
extension=png
layers=RASTER4000K,RASTER1000K,RASTER500K,RASTER250K,\
RASTER100K,RASTER50K,RASTER25K,RASTER5K
resolutions=2116.666666667,1058.333333333,529.166666667,\
264.583333333,132.291666667,66.145833333,26.458333333,\
13.229166668,6.614583334,2.645833334,1.322916667
levels=11
srs=EPSG:27572

La pluplart des paramètres sont facilement compréhensibles. Après la bbox cependant, on trouve un extent_type=loose. Il sert à autoriser la création de dalles en dehors de la bbox. Pratique pour éviter les dalles roses dans OpenLayers, quand l’étendue de la carte est plus grande que celle de votre ressource. L’omettre pour forcer les requêtes à se situer dans la bbox. Quant aux résolutions, c’est une manière d’exprimer les échelles. On peut les calculer assez facilement (hmmm…) : les dalles par défaut font 256×256 px. Si les images issues du serveur WMS sont en 96 dpi, chaque dalle fera donc (256/96) = 2,666666667 pouces, soit 2,666666667 x 2.54 = 6,773333333 cm. Au 100000e, cela représente donc 6773,333333 mètres, ce qui ramène à (6773,333333/256) = 26,458333333 m/pixel. La résolution pour le 100000e est donc de 26,45833333, et on peut alors facilement calculer les autres par simple péréquation.

Une autre option peut s’avérer utile, c’est metaTile=true. Elle permet d’envoyer des requêtes sur de larges extents, qui sont ensuite redécoupées en 256 x 256. C’est pratique à plus d’un titre. D’une part c’est souvent plus rapide de faire une requête que 25 (la metaTile fait 5 x 5 dalles de base par défaut), même si l’image est plus grosse. D’autre part ça diminue le problème du chevauchement des labels entre dalles contigües, puisque cet effet de bord n’apparaît plus désormais qu’en frontières des grandes tuiles, donc 5 fois moins souvent (20 faces externes au lieu de 100). Elle nécessite cependant l’installation (si ce n’est pas déjà le cas) de la librairie Image de Python (http://www.pythonware.com/products/pil/) qui fait le travail de découpe. Malheureusement, elle ne gère pas les PNG entrelacés, et cette option ne pourra donc pas fonctionner si la ressource WMS diffuse ses images dans ce format. Pour MapServer, il faut ajouter un FORMATOPTION « INTERLACE=OFF » dans la définition de l’outputformat PNG.

  1. Optimisation 1, utiliser mod_python.

TileCache est un programme en python, configuré par défaut pour être exécuté en mode cgi, c’est-à-dire qu’Apache charge à chaque requête l’exécutable python qui traite le fichier tilecache.cgi. C’est un peu lent. Il vaut mieux charger python dans Apache avec mod_python (à activer dans la liste des modules du httpd.conf, ou à compiler et installer directement) car le fichier est alors directement interprété par l’extension python d’Apache, résidente en mémoire.

Donc ajoutez à votre fichier httpd.conf :

LoadModule python_module modules/mod_python.so

Pas de tilecache.py dans votre répertoire tilecache ? Il suffit en fait de renommer le fichier tilecache.cgi en .py . Il faut par contre aussi adapter votre httpd.conf. La configuration du répertoire tilecache devient :

<Directory /usr/local/apache2/htdocs/tilecache>
AddHandler python-program .py
PythonHandler TileCache.Service
PythonOption TileCacheConfig /usr/local/apache2/htdocs/tilecache/tilecache.cfg
</Directory>

Petite précaution : maintenant que python et tilecache.py sont résidents en mémoire, il vous faudra redémarrer Apache à chaque modification du fichier de configuration de TileCache, qui est devenu une sorte de prolongement d’Apache… Il vaut donc mieux avoir bien configuré toutes ses ressources avant cette étape.

Comparez à présent le fonctionnement de votre TileCache, les performances devraient être sensiblement supérieures.

  1. Optimisation 2, pré-remplir le cache.

L’intérêt de cette étape dépend du nombre d’échelles de vos données WMS, ainsi que de leur utilisation. Inutile de pré-générer la France au 5000e si peu d’utilisateurs s’en servent. Mais il est souvent agréable d’avoir les 2-3 premiers niveaux pré-générés. Pour ce faire, utilisez le petit programme tilecache_seed.py ainsi :

python tilecache_seed.py ‘url_du_serveur_WMS’ nom_de_la_ressource niveau_de_depart niveau_de_fin

ce qui donne pour notre ressource définie plus haut :

python tilecache_seed.py ‘http://www.geosignal.org/cgi-bin/wmsmap’ geosignal 0 2

Cela générera toutes les dalles pour les niveaux 0,1 et 2 de la ressource « geosignal », soit les trois premières résolutions décrites dans le fichier tilecache.cfg. Il faut bien veiller à utliser le même nom de ressource que dans le tilecache.cfg.

Une fois la pré-génération réalisée, l’affichage sur ces premiers niveaux devrait être beaucoup plus fluide.

  1. Optimisation 3, forcer le cache client.

Vous remarquerez toutefois qu’en revenant sur un niveau de zoom déjà consulté, les images sont le plus souvent rechargées depuis le serveur. Dommage puisqu’elles sont déjà dans le cache client. Mais celui-ci (le navigateur) ne sait pas qu’elles sont encore valides. Il faut donc l’aider à le savoir. Pour ce faire, il faut utiliser le module Apache mod_expires. Il n’est pas chargé par défaut, mais peut l’être facilement en dé-commentant ou ajoutant un LoadModule mod_expires dans le httpd.conf si vous avez un version packagée. Par contre, si vous avez compilé Apache vous-même, il faudra le recompiler avec les options –enable-headers –enable-expires. Oui, j’aurais pu le dire avant… Mais Apache est votre ami, lors d’une réinstallation, le make install n’écrase que les exécutables et préserve le fichier de configuration, les modules et le contenu de cgi-bin. Donc tout va bien.

Une fois l’installation réalisée, il faut régler la durée de mise en cache dans la configuration Apache du répertoire tilecache. Rééditez donc à nouveau le httpd.conf et ajoutez dans la section Directory concernant tilecache :

ExpiresActive on
ExpiresDefault « access plus 6 months »

La durée de mise en cache peut se régler finement. Voir la documentation du module Expires pour cela. Tout dépend de la durée de vie des données sources. Si elles sont soumises à une mise à jour quotidienne, on pourra se contenter d’un ExpiresDefault « access plus 6 hours » . A noter que ceci n’a aucune incidence sur le contenu du cache serveur. Donc si les données sont mises à jour quotidiennement, il faut également purger le cache serveur tous les jours !

A l’issue de cette dernière étape, comment dire, après quelques allers-retours entre niveaux de zooms différents, l’affichage devient quasi-instantané !

  1. Optimisation 4, simuler plusieurs serveurs.

La plupart des navigateurs n’effectuent pas plus de deux requêtes simultanées sur un même serveur, mais peuvent par contre en effectuer beaucoup plus vers plusieurs serveurs. En déclarant auprès de votre hébergeur de nouveaux noms de domaines (data1.myserveur.com, data2.myserveur.com, data3.myserveur.com…) pointant tous vers la même IP, les navigateurs pourront alors charger les dalles beaucoup plus vite, pour peu que l’application web que vous utilisez prenne en charge ce genre de requête. Avec OpenLayers il suffit de déclarer non plus une URL, mais un tableau d’URL :

wms_sigma = new OpenLayers.Layer.WMS( "TIGER",
["http://sigma4.openplans.org/tilecache-1.3/tilecache.py?",
"http://sigma3.openplans.org/tilecache-1.3/tilecache.py?",
"http://sigma2.openplans.org/tilecache-1.3/tilecache.py?",
"http://sigma1.openplans.org/tilecache-1.3/tilecache.py?"],
{layers: 'sigma' }, {numZoomLevels: 17});

Si avec tout ça vous allez encore moins vite que GoogleMaps, il ne vous reste plus qu’à acheter un serveur avec 36 Go de RAM et charger votre cache directement dedans. Car TileCache en est également capable !

Version PDF.

Mots-clefs : , , , ,

28 commentaires sur “Optimisation de TileCache”

  1. pierre dit :

    merci pour toutes ces infos bien utiles.

  2. admin dit :

    pas de quoi. L’essentiel est dans le README de tilecache, mais mettre tout ça dans un contexte plus opérationnel me semblait utile.

  3. Ludovic dit :

    Merci pour ce super article !

  4. admin dit :

    Pas de quoi, si ça aide, c’est tant mieux !

  5. [...] qui seront exploitées nativement dans une application de webmapping n’est plus à démontrer. Dans le cadre du Google Summer of Code 2008, Klokan Petr Pridal vient d’ajouter un nouveau [...]

  6. djudjou dit :

    super article

  7. admin dit :

    Merci Julien ! C’est juste la traduction/collection de quelques trucs trouvés ça et là. A noter que pour les meilleures performances, on peut publier le cache sur le web et utiliser un TileCache layer dans OpenLayers. Ceci permet d’attaquer directement les tuiles, sans passer par le chargement du processus Tilecache.py. Mais le cache doit alors être complet (enfin, on peut aussi gérer le 404, mais c’est un autre sujet) !

  8. hc dit :

    merci.
    mais ca marche a moitié. Dans mon client openLayer j’ai:
    1/ La couche  » var wms = new OpenLayers.Layer.WMS( « cache metacarta », « tilecache/tilecache.py? », {layers: ‘basic’, format: ‘image/png’ } ); » qui fonctionne bien.
    2/ La couche « var geosignal= new OpenLayers.Layer.WMS(« cache geosignal WMS », « tilecache/tilecache.py? », {layers:’geosignal’, format: ‘image/png’}); » qui ne me rend que du rose.

    J’ai bien mis dans mon fichier tilecache.cfg ta conf telle que citée.
    une idee ? comment on debug tilecache ?
    merci.

  9. admin dit :

    Bonjour,
    Les tuiles roses c’est souvent dû à une incohérence entre la grille du client (OL) et du serveur (TC). Il faut donc vérifier que les MaxExtent correspondent bien, et aussi que les résolutions sont identiques. Pour débugger, rien de mieux que Firebug.

  10. nicolas dit :

    Bonjour,

    heu, ma question va sans doute paraitre un peu bête mais ces lignes :

    AddHandler cgi-script .cgi
    Options +ExecCGI

    on les notes dans quel fichier ? httpd.conf ?

    merci d’avance

  11. admin dit :

    oui, dans le httpd.conf ou un autre fichier de configuration apache spécifique à l’accès tilecache.

  12. Arno dit :

    Bonjour,

    Je tente de mettre en application TileCache car mon appli sous OL pêche vraiment sur le chargement des tuiles de mes WMS.

    Qu’entendez par:
     »Il faut donc vérifier que les MaxExtent correspondent bien »

    ?

    Merci
    Arno

  13. Guillaume dit :

    TileCache comme OpenLayers calcule une grille pour déterminer les tuiles. Si on veut qu’elles s’affichent, il faut que leurs coordonnées correspondent, et donc que les bbox et résolutions correspondent bien.

  14. Arno dit :

    Mon problème est que je n’obtiens que des tuiles roses…
    Et je n’arrive pas à savoir d’où vient mon problème…

    J’ai suivi de nombreuses sources mais sans succès.

    Un idée? Je suis sous linux…Serveur apache
    Arno

  15. Guillaume dit :

    regarde avec firebug s’il n’y a pas un message particulier accompagnant la tuile rose…

  16. Arno dit :

    Il me parle de « tilecache.cgi »

    avec « tilecache.cgi?LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&BBOX=-90,-90,0,0&WIDTH=256&HEIGHT=256″

    mais je vois pas trop…

    Mon tilecache.cgi
    est

    #!usr/bin/vpython/bin/python

    from TileCache import Service, cgiHandler, cfgfiles

    if __name__ == ‘__main__’:
    svc = Service.load(*cfgfiles)
    cgiHandler(svc)

    J’ai modifié le chemin pour retrouver l’environnement de Python mais je ne suis pas persuadé des résultats de la manoeuvre

    :-/

  17. Guillaume dit :

    essaie de placer l’url de la tuile directement dans le navigateur. Si rien n’est renvoyé, vérifie la configuration du serveur WMS vers lequel pointe tilecache. Ton erreur semble indiquer qu’il ne renvoie rien.

  18. Arno dit :

    J’ai pris le ZIP de TileCache, je l’ai installé sur mon serveur.
    Je n’ai touché à rien d’autres et apparaissent ces tuiles roses…

    Il est partout écrit « ultra simple »…Il y a certainement quelque chose qui n’est pas indiqué car je ne comprend pas ce qui est simple. Sur les forums, le constat semble être le même.

    J’aurais tant aimé l’optimisé, que je suis arrêté à l’installation.
    :-/

  19. Guillaume dit :

    Simple oui, magique non. Il faut d’abord mettre en place le serveur WMS et vérifier qu’il fonctionne. Ensuite tu places TileCache entre OpenLayers et ton serveur WMS. Hier lors d’une installation j’ai eu des tuiles roses. L’ouverture de leur url dans une nouvelle fenêtre et leur modification pour qu’elles pointent directement sur mapserv m’a permis d’obtenir un message d’erreur issu de MapServer, qui était mal configuré. J’ai alors pu corriger.

  20. Etienne dit :

    Quelqu’un sait comment forcer le cache client sur Windows avec IIS?

    Merci

  21. admin dit :

    Que veux-tu dire exactement ? Obliger Windows à recharger des tuiles ? Gérer le mode expiration ?

  22. Etienne dit :

    Je parle du point: Optimisation 3, forcer le cache client. Quand je retourne sur un zoom déjà visité mon browser download de nouveaux les tuiles… Cet article parle d’utiliser le module Apache mod_expires pour régler ce problème… quel serait l’équivalent avec IIS?

    Merci

  23. Djay dit :

    Salut Guillaume, pourquoi ne pas ajouter aussi compression gzip pour les tuiles ?

    Je me demande pourquoi tu ne le mentionnes pas, perso je l’active pour TC.

    Merci de me répondre,

  24. Guillaume dit :

    Pour trois raisons :
    1. c’est de la pure optimisation apache
    2. ça ne sert à rien pour les png
    3. il n’y a pas de 3

  25. Thibault dit :

    Bonjour et merci pour ces infos vitales… J’ai une petite question à la c… Mon hébergeur me déconseille fortement le mod_python en production. A près avoir lu l’article, vous imaginez ma tête.
    Alors est-il possible de simuler plusieurs serveurs sans activer ce module ?
    Merci.

  26. admin dit :

    Tiens, il est rigolo votre hébergeur. Que ce ne soit pas facile à gérer sur du mutualisé, oui, car il faut relancer le serveur quand on vient de modifier le code. Mais sinon c’est très robuste.
    Mais sinon, c’est complètement indépendant des DNS. Crééz autant de sous-domaines que vous souhaitez, tous pointant vers votre accès cgi ou wsgi.

  27. nikos dit :

    Bonjour,

    Je suis également bloqué rapidement après l’installation. Lorsque j’essaie l’exemple de base, j’obtiens également des tuiles roses.
    Avec Firebug, j’obtiens ce message lorsque je survole une dalle :

    tilecache.cgi/?LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&BBOX=-90,-90,0,0&WIDTH=256&HEIGHT=256%22%3E.

    Vous conseillez de mettre directement l’URL dans le navigateur mais j’ai du mal à comprendre le fonctionnement cgi. Que faut-il que je mette dans le navigateur ?

    PS : j’ai déjà une appli Postgis/Mapserver/Ol et j’arrive à afficher des couches grâce au protocole WMS mais de manière extremement lente

Laisser une réponse