Archives par mot-clé : PostgreSQL

Plug-in PHP requêtes asynchrones PostgreSQL pour Jelix/jDb

Je mets à disposition au téléchargement ce plug-in jDb (Jelix) écrit en PHP qui est un driver PostgreSQL permettant les requêtes asynchrones avec la base de données (http://xv4y NULL.radioclub NULL.asia/ftp/JELIX_JDB_PGSQL_ASY NULL.zip).

Logo QScope.org (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/08/logo_qscope_b NULL.png)Dans le cadre de mon projet de statistiques en ligne QScope.org (http://www NULL.qscope NULL.org/), je me retrouve à faire des calculs assez intensifs sur la base de données PostgreSQL, en particulier pour calculer le temps d’opération et les nombres réels de QSO/heure en pointe. Sur les gros logs d’expéditions DX ou pour les logs étalés sur plusieurs mois, les requêtes sur la base de données peuvent se chiffrer en milliards de lignes… et jusque 10 minutes de temps d’exécution.

Logo Postgresql (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/09/Postgresqlelephant NULL.png)Si les performances de PostgreSQL sont très bonnes et qu’il gère admirablement bien les connexions multiples, il ne permet pas l’exécution parallèle des requêtes. Cette fonctionnalité est encore une exclusivité des bases de données commerciales comme Oracle, Sybase ou MS SQL Server. Cela veut dire qu’une grosse requête ne pourra être répartie sur plusieurs micro-processeurs (ou coeurs) d’un serveur. La solution pour gagner du temps c’est alors de lancer plusieurs requêtes en parallèle pour réduire le temps d’exécution et profiter au mieux des ressource du serveur. PHP étant nativement un langage interprété mono-thread, ceci n’est pas intuitif à mettre en place. Il dispose toutefois dans son pilote PostgreSQL de commandes permettant de lancer les requêtes de manière asynchrone et de récupérer les résultats ensuite. En ouvrant plusieurs connexions simultanées cela ouvre la voie à une forme de traitement parallèle.

Logo Jelix (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/09/logo_jelix NULL.png)Si vous utilisez le framework PHP Jelix (http://jelix NULL.org/), ce plugin est simple d’utilisation puisqu’il reprend le pilote jDb PostgreSQL d’origine en lui ajoutant 3 fonctions pour gérer les requêtes asynchrones. Dans l’archive ZIP (http://xv4y NULL.radioclub NULL.asia/ftp/JELIX_JDB_PGSQL_ASY NULL.zip), se trouve un Readme en français et en anglais qui vous donne l’API et les exemples pour utiliser ce plugin.

QScope avec K9W et TO2TT

Logo QScope.org (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/08/logo_qscope_b NULL.png)En ce moment j’ai peu de temps pour le blog. Mes diverses activités professionnelles prennent la première place, avec entre autres un projet d’ouverture de restaurant qui redevient d’actualité. Ensuite j’ai été pas mal sollicité sur QScope (http://www NULL.qscope NULL.org/), d’abord par des nouvelles statistiques suggérées par les utilisateurs, ensuite par les bogues à corriger puis finalement par des revues et bulletins DX qui souhaitent avoir plus de détails afin de publier un article complet sur le projet.

La bonne nouvelle c’est que les organisateurs de deux grosses Expéditions à Wake Island (K9W) (http://www NULL.wake2013 NULL.org/) et à Mayotte (TO2TT) (http://www NULL.i2ysb NULL.com/idt/) ont annoncé leur volonté d’utiliser QScope en interne pour l’organisation de leurs opérations. Les statistiques produites leur permettront d’avoir jour par jour toutes les informations pour mieux répartir les tours d’opérateurs et la répartition des activités par bandes et modes dans le temps. Le but étant de maximiser le nombre de QSOs afin de mieux “rentabiliser” le coût de ces organisations. Le nombre de QSOs pour de telles DXpeditions en fin d’opération s’élève vite à 100.000, et ces utilisateurs utiliseront les statistiques les plus coûteuses en terme de temps machine!

J’ai donc du passer du temps afin de “préparer l’avenir”. En effet, si maintenant l’application compte 600 utilisateurs enregistrés et plus de 3 millions de lignes de log téléchargées, l’effervescence des premiers jours s’est calmé en moyenne il y a 10 utilisateurs “actifs” par jour qui produisent des statistiques et 1,8 millions de lignes de log dans la base de données (les utilisateurs effacent souvent leur logs après avoir produit les statistiques). La base de données principale fait 250 Mo, et les index occupent autant. Quand on tient compte de la RAM du serveur occupée par le système, le SGBDR lui-même et les différents shared buffers, on se rend compte qu’on se rapproche vite de la capacité maximale disponible de 1 Go actuelle sur le serveur. Rapidement, au lieu de lire les données dans la mémoire cache rapide, c’est sur le disque dur très lent que le SGBDR ira chercher ses informations à traiter. Les temps de calcul seront multiplié par 10 au moins…

Deux solutions à cela : augmenter la RAM du serveur ou mieux répartir les données. La première solution est la plus rapide à mettre en oeuvre, le problème c’est que chez le fournisseur que j’ai choisi c’est aussi la plus coûteuse. Les prix sont très attractif pour l’entrée de gamme, mais ensuite on grimpe très vite. L’autre solution est donc beaucoup plus intéressante sur le long terme. La réponse que je souhaitais mettre en place s’appliquait en trois phases :

  1. Mettre en place le mécanisme de Paritionnement de Tables de PostgreSQL. Simple à mettre en place en théorie, même si entièrement manuel contrairement aux SGBDR commerciaux comme Oracle ou Sybase, il permet de diminuer la taille de chaque table à charger en RAM et la taille des index. Je pensais donc répartir mes utilisateurs sur 27 tables (les 26 lettres de l’alphabet plus un “fourre-tout”) en fonction de la première lettre de leur indicatif. Après quelques tâtonnements (une maquette avec 2 utilisateurs est bien plus facile qu’une base de production avec 600 comptes) tout fonctionnait parfaitement. Les tables les plus grosses faisaient 40 Mo et les index avaient bien diminué en taille. Le “hic” c’est que les performances étaient pires qu’avant!!! Le problème venait de la fonction choisie pour répartir les utilisateurs sur les différentes tables. Celle-ci était coûteuse en temps machine et la pénalité se paye à chaque requête. J’ai donc du faire marche arrière… Le partitionnement reste intéressant, mais pour une répartition plus légère à calculer (simple comparaison) comme celle sur une date.
  2. Donner la possibilité d’attribuer à chaque utilisateur une base de données différente. Là, le travail se résumait à pas mal de réécriture du code existant pour permettre de se connecter sur différentes base de données “à la volée”. Rien d’insurmontable surtout que j’avais envisagé la chose assez tôt. En pratique ça me permet d’isoler facilement les “gros” utilisateurs comme les DXpeditions. Ils feront leurs calculs gourmands sur une base de taille plus petite que la base principale, diminuant les temps de traitement. La compartimentation au niveau du serveur aidera aussi les utilisateurs de la base principale à être moins impactés puisque ce seront deux emplacements mémoire et deux emplacements disques différent qui seront consultés, limitant les phénomènes de “lock“.
  3. Permettre d’utiliser plusieurs petits serveurs plutôt qu’un gros. Techniquement la solution est la même que la précédente, sauf que cette fois-ci au lieu d’interroger une autre base de données du même serveur je vais la chercher sur une autre machine. Cela est très intéressant car en répartissant les utilisateurs sur plusieurs bases on évite que celles-ci grossissent de trop et deviennent trop lourdes à gérer. Du point de vue financier, c’est aussi le plus intéressant car en doublant le coût, on double réellement la capacité (CPU, RAM et disque) alors que dans la grille tarifaire du fournisseur, doubler le prix payé pour le serveur ne faisait que doubler la RAM. Le contrecoup c’est que ça fait deux systèmes à gérer et donc plus de temps à passer. Toutefois, si les deux systèmes sont identiques et disposent de bonnes procédures automatisées, cette maintenance reste limitée.

Comme vous le voyez, je suis assez satisfait du temps passé sur QScope car cela me permettra de répondre plus facilement à l’augmentation de la demande qui va venir avec la saison des concours et des DXpeditions. L’échec de la mise en place du paritionnement n’est que partiel, et dans la réalité le serveur se comporte mieux que je ne l’avais craint. En effet, en plus de la RAM physique de 1 Go qui est allouée, 4 Go de disque SSD très rapide sont vus par le système comme de la RAM et permettent de diminuer les temps de réponse du disque tant qu’on reste dans des limites acceptables.