Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
Je réalise actuellement un POC sur les traitements de masse à l'aide de Spring Batch et lors de la mise en place du multi-threading j'ai remarquer un problème de performance.
Lors de mes test avec 12 threads mes perfs ne sont pas du tout à la hauteur, suites a plusieurs tests je me suis rendu compte que quelque soit le nombre de threads (de 2 à 16) mes perfs batch sont les même. J'ai identifier que le problème provient de mon SGBD postgresql.
L'insertion massive dans mon SGBD par plusieurs thread créer de la concurrence qui augmente très significativement les temps de chaque insert.
Je suis dans un contexte où je ne peux pas utiliser de mécanisme de masse de postgres (COPY) et je ne peux que faire des action unitaire (insert), élément par élément.
Je vous présente mon cas de test que j'ai réalisé pour mettre en évidence mon problème :
Mon processus principal se charge de créer un nombre variable de threads, il se charge de répartir 1 million d'insert parmis les threads et va attendre la fin de chaque thread.
Chaque thread fait le nombre d'insert qu'il à reçu du processus principal, chaque requête insert est la même pour simplifier le test.
Lest résultat de mes test :
Pour 2 threads, les 1 million d'insert se font en 2 minutes
Pour 12 threads, les 1 million d'insert se font en 1 minute
Or, l'ensemble des inserts sont indépendant, mon test se place dans un cas des plus standard : 1 seule table, uniquement un insert, pas d'index, pas de contrainte autre que la clé primaire.
Ma config est des plus puissante pour le SGBD : 6 CPU Intel(R) Xeon(R) CPU E5-2667 0 @ 2.90GHz , le reste étant du même niveau.
J'ai exploré le problème dans tous les sens, j'ai passé plusieurs jours avec mes DataBase Administrator pour essayer de trouver la cause de mon problème mais rien n'y fait, c'est pourquoi je me tourne vers vous.
Les cause classique ont pour la plupart était écarter par les DBA.
le problème est clair : Lors d'un insert unitaire de masse multithreadé, il y a concurrence sans explication ...
Infos diverses :
Chaque thread se connecte une fois et effectue tous les inserts, aucun commit entre les insert.
SGBD en configuration standard, JBoss configuré pour pouvoir gérer les multiples connexion au SGBD.
La requête d'insert est classique "INSERT INTO declarant.entreprise ( dt_creation, dt_maj, version, cd_cat_juridique, cd_motif_siren_annule, cd_naf, dt_cessation_activ_economique, dt_cessation_juridique, dt_creation_entreprise, dt_derniere_maj_emetteur, nb_etablissements_actifs, raison_sociale, sigle, siren ) VALUES ( '2014-04-07 15:54:04.451', '2014-04-07 15:54:04.451', '0', '1000', NULL, '1111Z', '2009-06-01', NULL, '1993-07-28', '2010-09-02', '0', 'RAISON SOCIALE', NULL, '333222111' );"
Au niveau applicatif tout est bien gérer le problème ne peux pas provenir de cette partie.
Analyse pgBadger du test
Total duration Times executed Min duration Max duration Avg duration
Pour 12 Threads
51.333s 254,332 0.000s 0.029s 0.000s
Pour 2 Threads
14.866s 254,332 0.000s 0.011s 0.000s
Je suis de prêt ce post, si vous avez besoin de toute autre information je vous les donnerais.
J'espère que quelqu'un pourra m'aider à trouver la raison ^^
D'avance, merci !
Hors ligne
Bonjour,
Ce qui serait pas mal ce serait d'avoir les logs postgresql pour le lancement en 2 puis en 12 threads.
vous pouvez nous donner ça ?
Cordialement,
Sébastien.
Hors ligne
Les logs pour chacun des run font 2Go vu qu'on a activé le full trace du postgres pour pouvoir générer un pgBadger.
Sans le full trace, le log est "normal" d'après mon DBA.
Hors ligne
Bonjour,
Je réalise actuellement un POC sur les traitements de masse à l'aide de Spring Batch et lors de la mise en place du multi-threading j'ai remarquer un problème de performance.
Lors de mes test avec 12 threads mes perfs ne sont pas du tout à la hauteur, suites a plusieurs tests je me suis rendu compte que quelque soit le nombre de threads (de 2 à 16) mes perfs batch sont les même. J'ai identifier que le problème provient de mon SGBD postgresql.L'insertion massive dans mon SGBD par plusieurs thread créer de la concurrence qui augmente très significativement les temps de chaque insert.
Je suis dans un contexte où je ne peux pas utiliser de mécanisme de masse de postgres (COPY) et je ne peux que faire des action unitaire (insert), élément par élément.Je vous présente mon cas de test que j'ai réalisé pour mettre en évidence mon problème :
Mon processus principal se charge de créer un nombre variable de threads, il se charge de répartir 1 million d'insert parmis les threads et va attendre la fin de chaque thread.
Chaque thread fait le nombre d'insert qu'il à reçu du processus principal, chaque requête insert est la même pour simplifier le test.Lest résultat de mes test :
Pour 2 threads, les 1 million d'insert se font en 2 minutes
Pour 12 threads, les 1 million d'insert se font en 1 minuteOr, l'ensemble des inserts sont indépendant, mon test se place dans un cas des plus standard : 1 seule table, uniquement un insert, pas d'index, pas de contrainte autre que la clé primaire.
Ma config est des plus puissante pour le SGBD : 6 CPU Intel(R) Xeon(R) CPU E5-2667 0 @ 2.90GHz , le reste étant du même niveau.
J'ai exploré le problème dans tous les sens, j'ai passé plusieurs jours avec mes DataBase Administrator pour essayer de trouver la cause de mon problème mais rien n'y fait, c'est pourquoi je me tourne vers vous.
Les cause classique ont pour la plupart était écarter par les DBA.le problème est clair : Lors d'un insert unitaire de masse multithreadé, il y a concurrence sans explication ...
Infos diverses :
Chaque thread se connecte une fois et effectue tous les inserts, aucun commit entre les insert.
SGBD en configuration standard, JBoss configuré pour pouvoir gérer les multiples connexion au SGBD.
La requête d'insert est classique "INSERT INTO declarant.entreprise ( dt_creation, dt_maj, version, cd_cat_juridique, cd_motif_siren_annule, cd_naf, dt_cessation_activ_economique, dt_cessation_juridique, dt_creation_entreprise, dt_derniere_maj_emetteur, nb_etablissements_actifs, raison_sociale, sigle, siren ) VALUES ( '2014-04-07 15:54:04.451', '2014-04-07 15:54:04.451', '0', '1000', NULL, '1111Z', '2009-06-01', NULL, '1993-07-28', '2010-09-02', '0', 'RAISON SOCIALE', NULL, '333222111' );"
Au niveau applicatif tout est bien gérer le problème ne peux pas provenir de cette partie.
Analyse pgBadger du test
Total duration Times executed Min duration Max duration Avg duration
Pour 12 Threads
51.333s 254,332 0.000s 0.029s 0.000sPour 2 Threads
14.866s 254,332 0.000s 0.011s 0.000sJe suis de prêt ce post, si vous avez besoin de toute autre information je vous les donnerais.
J'espère que quelqu'un pourra m'aider à trouver la raison ^^
D'avance, merci !
Le frein est très certainement le JT; En effet, l'écriture dans le JT est un point de contention, car il n'est pas possible de paralléliser les écritures dans le journal de PG...
A +
Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES, Expert langage SQL
Le site sur les SGBD relationnel et langage SQL : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * * Enseignant CNAM PACA, ISEN Toulon, CESI Aix en Provence * * * * *
Hors ligne
J'ai transmis l'idée au DBA.
Petite précision sur le test en question : les N threads sont vu par le SGBD comme autant de connexion, le SGBD ne me semble pas être dans un cas de parallélisation.
L'applicatif et le SGBD sont sur des machines différentes.
Hors ligne
Il y a trop peu d'informations pour donner quelques conseils que ce soit. Avoir déjà le postgresql.conf serait un plus. Avoir une idée de ce qu'il se passe sur le serveur pendant l'exécution des deux tests serait encore un plus (un rapport pgcluu pourrait aider).
Guillaume.
Hors ligne
Plutôt que les JT (journal de transactions ?) je soupçonnerai plutôt mvcc : puisque vous faite des requêtes unitaires en parallèle avec 12 threads, chaque requête acquière un lock exclusif. Du coup avec 12 threads c'est l'embouteillage, chacun attend la libération du lock pour pouvoir ouvrir sa transaction (attention c'est un comportement tout à fait normal de mvcc, le problème vient de la manière dont vous voulez injecter vos données).
Pouvez vous programmer votre appli pour que chaque thread envoie un ensemble de requête plutôt qu'une seule à la fois ?
Cordialement,
Sébastien.
Hors ligne
évidemment sans les logs postgresql difficile d'avoir un avis.
Est ce que vous avez des messages du genre "checkpoints are occurring too frequently" dans les logs ?
Quel est le résultat de :
select name, setting from pg_settings where name like 'wal%' or name like 'check%';
Cordialement,
Sébastien.
Hors ligne
Pages : 1