Firebird Documentation Index → Livre Blanc Firebird en Entreprise → Facteurs influant l'extensibilité |
Différents facteurs doivent être pris en compte quand on prévoit d'étendre les capacités pour permettre plus de connexions concurrentes des utilisateurs.
La première chose à identifier est de savoir si l'on parle du nombre de connexions (le nombre maximum d'utilisateurs connectés au même moment au plus haut de la charge) ou de la taille maximum de la base des utilisateurs ?
Firebird peut être déployé avec différents “modèles”. Ce qui nous intéresse ici sont les deux modèles “serveur complet” , Superserveur et Classic. Ces deux modèles sont disponibles sous Windows, Linux et d'autres plate-formes. Bien que le moteur du serveur soit le même, quel que soit le modèle, le choix du modèle a une influence croissante au fur et à mesure que le nombre d'utilisateurs potentiels connectés augmente. Le matériel et le système d'exploitation jouent un rôle aussi.
Chaque Firebird Superserveur est limité en pratique à un maximum de 150 à 400 connexions concurrentes. Cela vient du fait que Superserveur et toutes ses connexions à toutes ses bases de données sont encapsulées dans un seul processus 32-bit. Un processus 32-bit ne peut adresser plus de 2 Gb de mémoire. Chaque connexion à une base crée un ou plusieurs threads pour gérer les requêtes de cette connexion; Superserveur utilise aussi des threads pour ces propres tâches de fond de collecte des données périmées et d'autre tâches en ligne.
Superserveur a aussi besoin de mémoire pour d'autres tâches, bien sûr.
Un cache de page configurable — un pour chaque base ayant une connexion active — est maintenu pour gérer les pages de base et d'index fréquemment utilisées en mémoire. Pour Superserveur, ce cache est partagé par toutes les connexions à la base en question. La taille du cache de page par défaut est de 2048 pages, donc, pour une base ayant une taille de page par défaut de 4Kb, 8 Mb de RAM doivent être disponibles pour un usage efficace de ce cache. (Si le a besoin d'être paginé dans la mémoire virtuelle, son utilité serait nulle!).
En général, les bases sont créées avec une taille de page de 8Kb et c'est un fréquent gâchis de ressources quand les développeurs et les DBA surdimensionnent la taille du cache, en pensant que “plus c'est mieux” (c'est ce que l'auteur appelle “le syndrome Lamborghini”: si vous roulez sur le périphérique parisien aux heures de pointe dans une Lamborghini, pensez-vous que vous irez plus vite que moi avec ma Mazda 121 ?).
Quelques fois cette mesure est prise pour améliorer le temps de réponse qui a été dégradé par une mauvaise gestion des transactions dans le code client et par une mauvaise gestion des connexions. C'est inutile. De tels problèmes n'ont rien à voir avec la taille du cache mais bien avec une mauvaise libération des ressources. Augmenter le cache ne fait qu'aggraver la situation.
Pensez à l'effet sur les ressources quand, par exemple, le cache pour une de page classique de 8Kb est porté à 20.000 pages. Cela représente 160 Mb qui doit être préservé en mémoire pour rendre le cache utile. Le serveur maintien des fichiers de verrous dans la RAM et cela grossi dynamiquement (jusqu'à un maximum configurable) quand plus de connexions sont créées. Firebird 1.5 va utiliser la RAM pour les opérations de tri si elle est disponible. C'est parfait pour les temps de réponse, mais beaucoup d'applications mal écrites maintiennent ouvert des ensembles de données triées comportant des centaines de lignes pendant de longues périodes.
Les serveurs de bases de données aiment la RAM. Plus il y en a de disponible pour le serveur, plus il est rapide. Toutefois, la barrière de 2 Go pénalise le Superserveur dans une environnement surpeuplé parce que chaque connexion Superserveur utilise environ 2 Mo de RAM pour instancier son processus et maintenir ces ressources. Donc avec 500 connexions Superserveur vous utilisez un gigaoctet, laissant en gros moins d'un gigaoctet de RAM totale adressable disponible pour que le serveur travaille, trie, gère les transactions, les verrous des tables, le stockage en mémoire et les nouvelles connexions.
Le “serveur” Classic n'est en fait pas un serveur de bases de données, mais un service en tâche de fond (ou, sous Linux, un daemon xinetd) qui écoute les demandes de connexion. Pour chaque connexion réussie, le service instancie un processus serveur Firebird qui est la propriété exclusive de cette connexion. Le résultat est que chaque connexion utilise plus de ressources, mais le nombre de connexions devient uniquement une question de RAM disponible sur la machine serveur. En plus des ~2Mb pour instancier la connexion, chacun maintient son propre cache de page. Toutes les connexions obtiennent le même cache de départ et, puisque que le cache n'est pas partagé, il peut (et doit) être plus petit. La taille recommandée est d'environ 2Mb (512 pages pour une taille de page de 4Kb) sur une machine dédiée de 4Gb, mais peut être beaucoup plus petite. Il est important de garder assez de RAM disponible pour que le gestionnaire de verrous puisse “grossir” lors des pics de connexions.
Une manière de lever les limitations de la RAM 32-bit est de compiler un Superserveur 64-bit. Un Superserveur 64-bit est possible sur les plate-formes POSIX où l'OS a un support stable pour le matériel 64-bit. Un Superserveur 64-bit Firebird 1.5.2 expérimental sur AMD64/Linux i64 a été livré il y a plus d'un an mais il a été déclaré instable. Une version 64-bit AMD64/Linux i64 existe dans les phases de test de Firebird 2.0. Sous Windows, il n'est pas encore possible de compiler un Superserveur 64-bit du fait de problèmes avec l'actuelle version de du compilateur de Microsoft Visual Studio 7 C++, l'environnement standard de compilation de Firebird 2 sous Windows. Des binaires privés des deux versions v.1.5.x et v.2.0 sur des compilateur non Microsoft fonctionnent de manière stable dans des environnements de production et l'équipe de développement a signalé son intention de réaliser une version 64-bit Windows pour Firebird 2.0.
Utiliser un middleware pour garder et gérer des ressources pré allouées pour garder un nombre fini de connexions prêtes pour des demandes de connexions est ce qui est appelé un poll de connexions. Il y a plusieures manières d'implémenter un poll de connexions et qui oblige à agir de la sorte quand on a une base d'utilisateurs qui augmente. Il ne serait pas réaliste de mettre en place un système extensible multi utilisateurs sans cela. Un pool de connexions peut être combiné avec une gestion des files d'attente si les ressources ne sont pas suffisantes pour gérer les pics de charge.
Les développeurs de ces middleware doivent prendre soin de surveiller les connexions et déconnexions, surtout pour les clients “stateless” comme les navigateurs web, pour éviter les manques de ressource. Le middleware doit éviter les flux récursifs qui pourraient monopoliser le pool et, pour des raisons d'architecture, interdire complètement les connexions croisées.
Essayer de faire fonctionner un serveur de base de données sur un système qui utilise aussi des services entrant en compétition avec lui, comme un serveur web, un serveur Exchange, un serveur de domaine, etc., risque de voir ces autres services voler les ressources (RAM et temps CPU) au serveur de base de données, empêchant le même le Superserveur d'utiliser les 2 Gb qu'il est capable de gérer ou limiter le nombre de connexions au serveur Classic, et ralentir les temps de réponses des bases de données.
L'incompatibilité de l'implémentation des threads de Superserveur avec l'implémentation Windows SMP doit être vue comme une “limite à l'extensibilité”. C'est à cause de la manière totalement arbitraire que Windows utilise pour passer l'intégralité de l'affinité d'un processus entre les processeurs qui résulte en un “effet de bascule”, par lequel les performances vont se dégrader continuellement aux heures de pointe tandis que le système attend que l'OS se décide à transférer toutes les resources du Superserveur actives en mémoire d'un processeur à l'autre quand il détecte que la charge d'utilisation des processeurs est inégale. Superserveur est configuré par défaut pour n'être lié qu'à un seul processeur pour éviter cela.
Avec Linux, la gestion multiprocesseurs ne crée pas cet effet de bascule avec les noyaux 2.6 et supérieurs, il a toutefois été rapporté avec certains noyaux 2.4 sur de l'ancien matériel SMP. Cependant, SMP n'apporte pas non plus de gains significatifs de performance pour Superserveur sous Linux.
Le support configurable pour différent niveaux de SMP, la gestion fine du multi-threading a été conçue pour le moteur Vulcan et deviendra une fonctionnalité de Firebird 3. Son efficacité sur les opérations en mémoire a été suffisamment démontrée pour que cela soit quelque chose de très intéressant pour le futur.
Dans le même temps, au vu de l'importance inhérente aux temps de réponses des E/S des disques sur les processus en cours de transaction, tout le bruit fait autour des possibilités de SMP peut être rapproché du syndrome Lamborghini. Dans un environnement approprié, Superserveur sur un système mono processeur est très efficace ! Classic — un seul processus par connexion — ne souffre pas d'inhibition avec SMP, même sous Windows. Avant Firebird 3, quand la distinction entre les deux modèles de ressources aura disparue, pour être remplacée par une gestion configurable des ressources, Classic est le meilleur choix pour un plan de monté en charge puisqu'il est capable de répondre à demande croissante de montée en charge par une simple augmentation des ressources du système.
Il a été rapporté quelques problème au niveau du noyau avec SMP sur certaines versions de Linux avec 8 CPUs et l'hyperthreading activé, qui n'apparaissent pas avec des systèmes 4X. Comme le support complet de l'affinité CPU sous Linux n'existe pas avant le noyau v.2.6, définir l'affinité CPU avec firebird.conf n'est pas supporté par Linux dans la version actuelle de Superserveur.
Un réseau TCP/IP avec les ressources adéquates en utilisant le modèle approprié de Firebird est parfaitement extensible. Un hôte Linux sans application entrant en compétition (y compris Xserver!) fonctionnant dessus va délivrer le maximum de performance à l'autre bout de l'échelle. Comme serveur de base de données, un hôte Windows souffre de charges inutiles inhérente au système d'exploitation qui ont un effet notable négatif sur les performances dans des conditions de forte charge.
Toutefois, il y a un autre “piège” lié au réseaux Windows. Le protocole natif de canaux de communication nommés de Windows (“NetBEUI”), que l'interface réseau de Firebird supporte pour des raisons historiques, a une limite absolue d'un maximum de 930 connexions pour tout serveur. Les canaux de communication nommés doivent être proscrits pour les environnements autre que des petits réseaux workgroup, car c'est un protocole très “bavard” et l'est de plus en plus en cas de croissance du réseau.
Soit dit en passant, les bases de données sous Windows devraient toujours être stockées sur des partitions NTFS qui, si elles sont suffisamment protégées, offrent de meilleures performances et sont moins exposées aux risques que FAT32. Les anciens disques durs qui ont été utilisés sur des systèmes fonctionnant auparavant avec NT 4.0 doivent être aussi considérés comme exposés, l'ancien NTFS n'apportant pas les garanties de protections qui ont été ensuite ajoutées dans les version actuelles.
La disponibilité et l'extensibilité de tout système logiciel peut être négativement affecté par une mauvaise conception de la base de données, des requêtes mal écrites, des flux de données inappropriés et, particulièrement, une mauvaise gestion des transactions.
L'architecture multi générationnelle assure une gestion des tâches optimiste robuste et excellente et une forte capacité de traitement. Une base de données performante est le résultat d'une conception attentive, une bonne normalisation, de bons index, et, du coté client, de requêtes bien écrites et une attention particulière portée à la gestion des transactions. Au contraire, une mauvaise conception de la base amène des requêtes inutilement complexes, des mauvais index qui peuvent bloquer les capacité de l'optimiseur à utiliser les bons plans de requête. Des requêtes lentes sont généralement le résultat de ces défauts.
MGA accumule des “données périmées”, sous la forme d'anciennes versions des enregistrements. Le moteur nettoie en ligne ces données périmées. Toutefois, il ne permet pas le nettoyage des données concernant des anciennes versions d'enregistrements qui “intéressent” encore des transactions actives. Les transactions qui restent intéressées longtemps maintiennent des versions anciennes des enregistrements qui peuvent être pertinentes pour des transactions commencées après, ce qui fait que l'on peut arriver à un niveau de données périmées difficilement gérable. Il est essentiel que les développeurs qui utilisent Firebird comprennent comment cela peut arriver et d'écrire des logiciels qui évitent cet état, en gardant un niveau raisonnable de données périmées afin que le sous système de nettoyage puisse le gérer.
Commit Retaining est une “fonctionnalité” de Firebird qui a été héritée de son ancêtre, InterBase. Cela a été implémenté pour conserver des ressources coté serveur et les laisser disponibles pour les utilisateurs utilisant les outils de développement rapide de Borland et le BDE, le cadre d'accès générique d'accès aux données qui a été créé pour permettre aux applications graphiques Windows de se connecter aux bases de données. Son but était de présenter un niveau uniforme pour le développement RAD, quelque soit la base de données fonctionnant à l'autre bout de la chaîne.
Autocommit—- un mécanisme coté client qui joue le rôle d'un Post au niveau instruction et d'un Commit au niveau transaction en une seule étape -— a été fournit pour permettre aux développeurs de ne pas ce soucier des transactions. Dans les composants RAD, Commit Retaining et Autocommit ont été liés. Cela convient très bien à des base de données bureautique comme dBase et Paradox (lesquels moteurs sont, de fait, le BDE!), qui n'ont pas de transactions.
Avec Firebird (et InterBase), Commit Retaining fait que les transactions restent intéressées indéfiniment. La collecte des données périmées cesse de fait avec les applications “standard” créées avec les outils Borland RAD et tout autre application qui utilise Commit Retaining. De tels systèmes connaissent des problèmes de dégradations progressives de performances qui ne peuvent être résolus sans un arrêt des bases afin de permettre à ces vieilles transaction de mourir.
Autocommit et Commit Retaining ne sont pas le seul apanage des outils Borland, bien sûr. Il sont utilisés par beaucoup d'interfaces d'accès aux données et Commit Retaining est disponible dans la norme SQL, donc il revient aux développeurs de bien comprendre le mécanisme et ses effets afin d'utiliser ces fonctionnalités avec une extrême prudence et un bon degré de contrôle.
Firebird Documentation Index → Livre Blanc Firebird en Entreprise → Facteurs influant l'extensibilité |