TIBCO EBX®
Documentation > Manuel de référence > Divers
Mode navigationDocumentation > Manuel de référence > Divers

Instructions relatives aux performances

Principales vérifications sur les performances

Bien qu'TIBCO EBX® soit conçu pour prendre en charge de grands volumes de données, plusieurs facteurs courants peuvent engendrer de faibles performances. Les points clé abordés dans cette section permettront de résoudre les éventuels problèmes de performance.

Extensions programmatiques coûteuses

Pour information, la table ci-dessous détaille les extensions programmatiques qui peuvent être implémentées.

Cas d'utilisation

Extensions programmatiques pouvant être impliquées

Validation

Accès table

Affichage du contenu EBX®

Mise à jour des données

Pour les grands volumes de données, les algorithmes lourds ont un impact important sur les performances. Par exemple, la complexité d'un algorithme de contrainte est O(n 2 ). Si la taille des données est 100, le coût résultant sera proportionnellement de 10 000 (produisant généralement un résultat immédiat). Cependant, si la taille des données est 10 000, le coût résultant sera proportionnellement de 10 000 000.

Une autre cause de baisse des performances est l'appel à des ressources externes. L'utilisation d'un cache local résout généralement ce type de problèmes.

Si l'un des cas d'utilisation ci-dessus mène à une baisse des performances, il est recommandé d'identifier le problème soit via l'analyse du code, soit en utilisant un outil de profiling Java.

Intégration de l'annuaire

L'authentification et la gestion des permissions font appel à l'annuaire des rôles et utilisateurs.

Si l'implémentation spécifique d'un annuaire est déployée et accède à un annuaire externe, il peut être utile de mettre en place un cache local. En particulier, une des méthodes les plus fréquemment appelées est Directory.isUserInRole.

Listes agrégées

Dans un modèle de données, lorsque la contrainte de cardinalité d'un élément maxOccurs est supérieure à 1 et qu'aucune osd:table n'est déclarée pour cet élément, elle est implémentée en tant que List Java. Ce type d'élément est appelé liste agrégée, par opposition à une table.

Il est important de prendre en compte qu'il n'existe aucune optimisation spécifique lors de l'accès aux listes agrégées en termes d'itérations, d'affichage utilisateur, etc. En dehors des questions de performance, les listes agrégées sont limitées en ce qui concerne les nombreuses fonctionnalités prises en charge par les tables. Voir introduction aux tables pour une liste de ces fonctionnalités.

Attention

Pour les raisons indiquées ci-dessus, les listes agrégées devraient être utilisées uniquement sur de petits volumes de données simples (une ou deux douzaines d'enregistrements), sans exigence spécifique concernant leur identification, résolution, permissions, etc. Pour des volumes de données plus importants (ou des fonctionnalités plus avancées), il est conseillé d'utiliser les déclarations osd:table.

Vérifications pour l'utilisation d'un espace de données

Les espaces de données disponibles en mode sémantique sont des outils précieux pour gérer les cycles de vie des données complexes. Bien que cette fonctionnalité apporte une grande flexibilité, elle implique aussi un coût supplémentaire, qui doit être pris en compte pour l'optimisation des processus métiers.

Cette section résume les problèmes de performance les plus courants qui peuvent apparaître dans le cas d'une utilisation intensive de plusieurs espaces de données contenant de grandes tables ; et de quelle façon les éviter.

Note

Parfois, l'utilisation d'espaces de données n'est pas strictement nécessaire. Citons le cas extrême où chaque transaction déclencherait les actions suivantes :

  1. Un espace de données est créé.

  2. La transaction modifie certaines données.

  3. L'espace de données est fusionné, fermé, puis supprimé.

Dans ce cas, aucune référence à l'espace de données ne sera nécessaire par la suite ; son utilisation pour modifier de données isolées n'est donc pas nécessaire. Ainsi, l'utilisation de Procedure fournit déjà une isolation suffisante pour éviter les conflits entre opérations concurrentes. Il serait alors plus efficace de réaliser les modifications directement dans l'espace de données cible, et de ne pas conserver les étapes de branche et de fusion.

Voici une analogie à l'attention des développeurs, portant sur un outil de gestion de code source (CVS, SVN, etc.) : pour réaliser une modification simple n'impactant que quelques fichiers, il suffit de le faire directement dans la branche principale. En fait, ce ne serait ni pratique ni durable, en ce qui concerne le tag/la copie des fichiers, si chaque modification de fichier impliquait de brancher l'ensemble du projet, de modifier les fichiers, puis de fusionner la branche dédiée.

Mémoire insuffisante

Lorsqu'une table est en mode sémantique (par défaut), le cache de la mémoire Java d'EBX® est utilisé. Cela garantit un accès aux données bien plus efficace lorsque ces données sont déjà chargées dans le cache. Toutefois, s'il n'y a pas assez d'espace pour les données courantes, des rechargements intempestifs de données depuis la base de données sous-jacente vers le cache de la JVM peuvent avoir un lourd impact sur les performances globales.

Cette surcharge d'échanges de mémoire (swap) ne peut se produire que pour les tables dans un espace de données ayant une stratégie de chargement à la demande.

Ce type de problème peut être détecté via le fichier log de monitoring. Si cela se produit, différentes actions peuvent être envisagées :

Annulation de transaction

En mode sémantique, lorsqu'une transaction a réalisé des mises à jour dans l'espace de données courant et qu'elle est interrompue, les index chargés des tables modifiées sont réinitialisés. Si les mises à jour d'une table de grande taille sont souvent annulées et, qu'en même temps, les accès à cette table sont fréquents, alors le travail relatif à la reconstruction de l'index provoquera un ralentissement de l'accès à la table. Par ailleurs, l'allocation de mémoire induite et l'activité de "garbage collector" peuvent mener à une réduction globale des performances.

Réorganisation des tables de la base de données

Comme avec toute base de données, l'insertion et la suppression de volumes de données importants peuvent mener à une fragmentation des données, qui peut détériorer les performances avec le temps. Pour résoudre ce problème, la réorganisation des tables impactées de la base de données est nécessaire. Voir Monitoring and cleanup of the relational database.

Une spécificité d' EBX® est que la création d'espaces de données et d'images ajoute de nouvelles entrées aux tables HTA et ATB. Si l'on constate une baisse des performances, il peut donc être nécessaire de planifier une réorganisation de ces tables, pour les référentiels de taille importante dans lesquels de nombreux espaces de données sont créés et supprimés.

Gestion de la mémoire

Stratégie de chargement

L'administrateur peut préciser la stratégie de chargement de l'espace de données ou de l'image dans ses informations. La stratégie par défaut est de charger et de décharger les ressources à la demande. Pour les ressources fréquemment utilisées, une stratégie de chargement forcé est généralement recommandée.

La table suivante détaille les modes de chargement disponibles en mode sémantique. Le serveur d'applications doit être redémarré afin de prendre en compte tout changement de stratégie de chargement.

Chargement et déchargement à la demande

Dans ce mode par défaut, chaque ressource d'un espace de données est uniquement chargée ou construite si nécessaire. Les ressources de l'espace de données sont référencées par le logiciel via la classe Java standard SoftReference. Par conséquent, chaque ressource peut être déchargée "à la discrétion du "garbage collector" en réponse à la demande mémoire".

L'avantage principal de ce mode est sa capacité à libérer de la mémoire lorsque cela est nécessaire. En contrepartie, cela implique un coût de chargement/construction lorsque la ressource accédée n'a pas encore été chargée depuis le démarrage du serveur, ou si elle a été déchargée depuis.

Chargement forcé

Si la stratégie de chargement forcé est activée pour un espace de données ou une image, ses ressources sont chargées de manière asynchrone au démarrage du serveur. Chaque ressource de l'espace de données est conservée en mémoire jusqu'à l'arrêt du serveur ou la fermeture de l'espace de données.

Ce mode est particulièrement recommandé pour les espaces de données ayant une longue durée de vie et/ou ceux qui sont fréquemment utilisés, à savoir tout espace de données utilisé comme référence.

Chargement forcé et pré-validation

Cette stratégie est similaire à la stratégie de chargement forcé, la différence étant que le contenu de l'espace de données chargé ou de l'image sera aussi validé au démarrage du serveur.

Monitoring

Les indications relatives au chargement/déchargement du cache d'EBX® sont fournies par le monitoring de la base de données sous-jacente, ainsi que par la catégorie de logging du 'monitoring'.

Si le nombre d'objets cleared et built demeure élevé sur une longue période, cela signifie qu'EBX® effectue de nombreux chargements et déchargements d'objets dans le cache.

Afin de faciliter l'analyse des journaux générés par EBX®, il est possible d'utiliser la feuille de calcul OpenOffice fournie (clic-droit et sauvegarder).

Réglage de la mémoire

La mémoire maximum pouvant être allouée à la JVM est habituellement spécifiée en utilisant l'option de ligne de commande Java -Xmx. Comme c'est le cas pour tout processus intensif, il est important que la taille spécifiée par cette option n'excède pas la mémoire physique disponible, ainsi le processus Java n'utilisera pas le disque pour des échanges mémoire (swap) au niveau du système d'exploitation.

Le réglage du "garbage collector" peut aussi améliorer les performances globales. Ce réglage doit être adapté au cas d'utilisation ainsi qu'à l'environnement spécifique Java Runtime utilisé.

Validation

Le mécanisme de validation incrémentale permet d'optimiser le travail nécessaire lors des mises à jour. Le processus de validation incrémentale a le comportement suivant :

Certains noeuds sont systématiquement revalidés, et ce, même si aucune mise à jour n'a eu lieu depuis la dernière validation. Ce sont des noeuds à dépendances inconnues. Un noeud a des dépendances inconnues si : 

Par conséquent, pour les tables de grande taille (au delà de l'ordre de grandeur 10 5 ), il est recommandé d'éviter les noeuds ayant des dépendances inconnues (ou au moins d'en minimiser le nombre). Pour les contraintes programmatiques, le développeur peut définir deux modes alternatifs qui réduiront de manière drastique les coûts de validation incrémentale : mode dépendance locale et dépendances explicites. Pour plus d'informations, voir Dépendances et validation.

Note

Il est possible, pour un utilisateur administrateur, de réinitialiser manuellement le rapport de validation d'un jeu de données. Cette option est disponible dans la section du rapport de validation dans EBX®.

Mises à jour de masse

Les mises à jour de masse peuvent inclure plusieurs centaines de milliers d'insertions, de modifications et de suppressions. Ces mises à jour sont assez rares (habituellement imports de données initiales), ou sont réalisées de manière non-interactive (traitements par lot de nuit). Ainsi, l'importance des performances pour ces mises à jour est moins critique que pour des opérations interactives ou fréquentes. Toutefois, tout comme le traitement par lot classique, elles peuvent donner lieu à certains problèmes spécifiques.

Mode batch

Pour les tables en mode relationnel, l'implémentation des insertions, mises à jours et suppressions s'appuie sur la fonction JDBC de traitement par lot (batch). Pour des procédures à fort volume, ceci améliore grandement les performances, en limitant le nombre d'allers-retours entre le serveur d'applications et la base de données.

Afin d'exploiter totalement cette fonctionnalité, il est possible d'activer le mode batch sur des procédures à fort volume. Voir ProcedureContext.setBatch. Ceci désactive le test d'existence avant insertion d'un enregistrement, et réduit ainsi le nombre de requêtes émises vers la base de données. Le traitement par lot en est rendu encore plus efficace.

Limites de transaction

Il n'est généralement pas recommandé d'utiliser une seule transaction lorsque le nombre de mises à jour atomiques dans la transaction est supérieur à l'ordre de grandeur 10 4 . Les transactions de taille importante nécessitent beaucoup de ressources, particulièrement mémoire, d'EBX® ainsi que de la base de données sous-jacente.

Afin de réduire la taille de la transaction, il est possible de :

D'autre part, définir une taille de transaction très basse peut aussi altérer les performances à cause des tâches persistantes qui doivent être exécutées sur chaque commit.

Note

Si des commits intermédiaires posent problème du fait que l'atomicité transactionnelle n'est plus garantie, il est recommandé d'exécuter la mise à jour de masse à l'intérieur d'un espace de données dédié. Cet espace de données sera créé juste avant la mise à jour de masse. Si la mise à jour ne s'achève pas avec succès, l'espace de données doit être fermé, et il faudra rententer la mise à jour après avoir corrigé la cause de l'échec initial. Si la mise à jour aboutit avec succès, l'espace de données peut alors être fusionné sans risque avec l'espace de données d'origine.

Triggers

Si nécessaire, les triggers peuvent être désactivés en utilisant la méthode ProcedureContext.setTriggerActivation.

Accès aux tables

Fonctionnalités

On accède généralement aux tables via EBX® et aussi via l'API Request et les services de données. Cet accès implique un ensemble unique de fonctions, incluant un processus de résolution dynamique. Ce processus a le comportement suivant :

Accès aux tables en mode sémantique

Architecture et conception

Afin d'améliorer la vitesse des opérations sur les tables, des index sont gérés par le moteur d'EBX®.

Les fonctions avancées d'EBX®, telles que le cycle de vie avancé (images et espaces de données), l'héritage de jeu de données, et la modélisation souple de schéma XML, ont conduit à une conception spécialisée des mécanismes d'indexation. Cette conception peut être résumée de la façon suivante :

Attention

Un accès plus rapide aux tables est assuré si les index sont prêts et maintenus dans le cache mémoire. Comme mentionné ci-dessus, il est important pour la Machine Virtuelle Java d'avoir un espace alloué suffisant pour qu'elle ne libère pas les index trop rapidement.

Facteurs de performance

L'optimiseur de requêtes préfère l'utilisation des index lors du calcul du résultat d'une requête.

Attention

  • Seuls les filtres XPath sont pris en compte pour l'optimisation de l'index.

  • Les index des clés non-primaires ne sont pas pris en compte pour les jeux de données enfants.

En supposant que les index soient déjà construits, les impacts sur les performances sont les suivants :

  1. Si la requête n'inclut ni filtrage, ni règles programmatiques, ni tri, alors l'accès à ses premières lignes (celles récupérées par une vue paginée) est presque instantané.

  2. Si la requête peut être résolue sans étape de tri supplémentaire (c'est le cas s'il n'y a pas de critère de tri, ou si ses critères de tri se rapportent à ceux de l'index utilisé pour le calcul de la requête), l'accès aux premières lignes d'une table devrait être rapide. Plus précisément, cela dépend du coût de l'algorithme de filtrage spécifique exécuté lors de la récupération d'au moins 2000 enregistrements.

  3. Les deux cas ci-dessus garantissent un temps d'accès indépendant de la taille de la table, tout en fournissant une vue triée par l'index utilisé. Si un tri supplémentaire est requis, le temps nécessaire au premier accès dépend de la taille de la table, conformément à une fonction Nlog(N), où N est le nombre d'enregistrements dans la vue résolue.

Note

Les requêtes paginées ajoutent automatiquement la clé primaire à la fin du critère spécifié, afin d'assurer un tri cohérent. Ainsi, les champs de clé primaire devraient aussi être ajoutés à la fin de tout index destiné à améliorer les performances des requêtes paginées. Celles-ci incluent les vues tabulaires et hiérarchiques, ainsi que les menus déroulants pour les clés étrangères.

Si les index ne sont pas encore construits, ou ont été déchargés, un temps supplémentaire est nécessaire. Le temps de construction est O(Nlog(N)).

L'accès aux blocs de données de la table est nécessaire lorsque la requête ne peut pas être calculée sur un index unique (que ce soit pour résoudre une règle, filtrer ou trier), ainsi que pour la construction de l'index. Si les blocs de table ne sont pas présents en mémoire, un temps supplémentaire est nécessaire afin d'aller les chercher dans la base de données.

Il est possible d'obtenir des informations via les logs de catégorie "request" et "monitoring".

Autres opérations sur les tables

La création de nouveaux enregistrements ou l'insertion d'enregistrements dépend de l'index de la clé primaire. Ainsi, une création devient quasi immédiate si cet index est déjà chargé.

Accès REST aux tables historisées

Les informations de fusion dans la table d'historique (le champ merge_info) a un coût d'accès potentiellement élevé. Pour améliorer les performances et si le code client n'a pas besoin de ce champ, le paramètre includeMergeInfo doit être défini à false.

Pour plus d'informations, voir Historique.

Accès aux tables en mode relationnel

Lors du calcul du résultat d'une requête, le moteur d'EBX® délègue ce qui suit au SGBDR :

L'information sur la requête SQL transmise est enregistrée dans les logs de catégorie persistance. Voir Configuring the EBX® logs.

Indexation

Afin d'améliorer la vitesse des opérations sur les tables, des index peuvent être déclarés sur une table au niveau du modèle de données. Cela déclenchera la création d'un index de la table correspondante en base de données.

Lors de la conception d'un index visant à améliorer les performances d'une requête donnée, les mêmes règles que pour la conception d'un index de base de données classique s'appliquent.

Définir une taille de récupération (fetch size)

Afin d'améliorer les performances, la taille de récupération (fetch size) doit être définie en fonction de la taille attendue pour le résultat de la requête sur une table. Si aucune taille de récupération n'est définie, la valeur par défaut sera utilisée.

Documentation > Manuel de référence > Divers