IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SGBD Perl Discussion :

paralélisation de programmes


Sujet :

SGBD Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut paralélisation de programmes
    Bonjour,

    Mon programme PERL fais une tres grande nombre d'insertions dans la base Oracle. Je risque de passer 30 heures à attendre...

    En un mot:
    - mon programme perl reçoit un fichier d'entrée avec beaucoup de données, les traite puis prépare les requetes SQL pour les mettre ensuite dans un fichier de sortie
    - SQLLOADER charge ces données

    ce que je vois comme solution, c'est couper ce fichier d'entrée en plusieurs petits fichiers , ça ira plus vite.
    - Première question: connaissez vous d'autres méthodes pour résoudre ?

    Avec ma solution, le soucis c'est que j'aurai des problèmes de gestion de clé primaire de la base, car SQLLOADER ne peut pas gérer la clé primaire (incrémenter d'une manière automatique). Il faut que je fasse par PERL l'incrémentation. Or comme j'ai plusieurs fichiers d'entrée et donc plusieurs programmes perl tournent en même temps, je ne vois pas comment gérer cette clé.

    que pensez vous ?

    existe il des threads qui peuvent résoudre ce problème en perl ?

    meri d'avance

    Cathy

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Déjà, je me demande si utiliser DBI et DBD::Oracle ne serait pas plus rapide, en particulier utiliser des requêtes avec placeholders de façon à avoir les requêtes en cache. Ensuite je te recommande d'oublier les threads en Perl, la situation s'est beaucoup amélioré, mais je ne leur ferais encore pas trop confiance pour des scripts en productions. Ce qui signifie des forks, avec une mémoire partagée pour la clé primaire peut-être... Néanmoins je dois avouer qu'une clé primaire que tu dois incrémenter à la main Tu es sûr que tu ne pourrais pas redésigner la base ?
    Par ailleurs je ne vois pas trop pourquoi avoir plusieurs petit fichiers serait plus rapide qu'un gros fichier, a priori il me semble que l'élément limitant c'est la BDD pas la vitesse des entrées/sorties de l'OS, de ce point de vue d'ailleurs, paralléliser le processus de requêtes ne semble pas susceptible d'améliorer la situation (je ne vois pas pourquoi la BDD traiterait plus vite des requêtes qu'elle recevrait en parallèle (vous avez un multicore, ou du vrai multiprocesseur ?).

    --
    Jedaï

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut alors...
    j'ai l'impression que plus les fichiers d'entrée /de sortie sont petits, plus ça va vite en perl en sachant que mon programme perl fait aussi des SELECT dans la base

    Concrètement:
    - avec un fichier d'entrée de 60 000 lignes qui donne un fichier de sortie de 99 803 lignes, mon programmme a pris 35 min
    - j'ai divisé ce fichier en 6 fichiers d'entrée (de 10 000 lignes) et crée aussi 6 fichiers de sortie : ç'a prit 12 min au total pour traiter ces 6 fichiers en même temps

    Quant au processeur je ne pense pas que ce soit du multicore, ou du vrai multiprocesseur car je fais des tests, je ne suis pas en prod


    cathy

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut j'avais oublié de dire
    que ce n'est pas SQLLOADER qui est lent, c'est le code perl qui traite les données (select dans la base + i/o dans les fichiers ) qui est lent

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 572
    Points : 2 014
    Points
    2 014
    Par défaut
    Qu'entends-tu par la lenteur de Perl ? Il prend trop de temps à écrire dans les fichiers à ton goùt ? Un petit problème de bufferisation ?

    Je dis ça, je dis rien mais si ça peut servir de piste...

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut je ne sais pas trop
    au fait c'est par rapport au résultat final: 35 min / 12 min

    Cathy

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ok, alors je crois que je comprends... En gros ce qui prend du temps ce ne sont pas les requêtes SQL par SQLLoader, mais la création du fichier de requête par Perl ?
    Dans ce cas je dirais que si tu peux diviser les fichiers d'entrée sans problème, c'est que tu n'as pas besoin de conserver l'intégralité des données en mémoire. Or le fait que Perl soit plus lent avec des plus gros fichiers découle très probablement du fait que tu swap, parce que l'intégralité des données est en mémoire.
    Autrement dit tu as un problème de structure de ton programme Perl : tu conserves des données en mémoire, tellement de données que tu te mets à swaper, ce qui te ralentit. Et apparemment il n'est pas nécessaire de conserver ces données (puisque tu peux découper ton entrée en plus petits fichiers, c'est donc qu'il n'y a pas d'interdépendance forte entre toutes les lignes de tes fichiers).

    Donc ton programme Perl est mal conçu... Il faudrait corriger cette conception.

    --
    Jedaï

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut swap
    Que veux tu par swapper ? je n'utilise pas de mémoire pour conserver les données, juste pour lire mon fichier ligne par ligne. Pour chaque ligne de 100 carcactère affectée à une variable, je fais 1 traitement et ensuite ecris dans le fichier en sortie. Cette ligne (cette variable)sera écrasée par la lecture de la ligne suivante.

    cathy

  9. #9
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Sauf que si c'est vraiment ce que tu fais, il n'y a aucune raison que passer à de plus petits fichiers change quoi que ce soit.... (du côté Perl en tout cas)
    Tu n'utiliserais pas for/foreach pour lire ton fichier par hasard ? Tu pourrais nous montrer ton code s'il n'est pas confidentiel ?

    --
    Jedaï

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut mon programme simplifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #affectation des variables
    #.......etc
     
    open(FILEOUT_PFSVOD,">$fileOut") ;
     
      while( defined( $line = <FILEIN> ) ){ 
       #- Enlever le retour chariot, les espaces, et Mettre dans le tableau
       $line =~ s/\n//g;
       $line =~ s/\s+//g;   
       @tab =split(/\;/, $line);   
     
       # TRAITEMENT ICI : récupérer les valeurs de la base, els calcules en fonction des valeurs dans @tab
       # si ok j'ecris dans le fichier................., la suite est:
     
       #- je traite seulement des actifs ET suspendu
       if ($myStatutMA ne "-1" && scalar(@tab)>2){   	   	 		   	        	      	  
       	    if ($tab[2] eq "CTRCAN"){		  		   		   	   	    	
    	   	print( FILEOUT_IDENTITE_AUX ";".$myVersion.";".$myIDMA.";".$myIdTypeIdentifiantCTRCAN.";".$tab[3].";0;".$myTimeStamp.";".$myDate."\n" ); 			   		   	
       		if ($myStatutMA eq "1" ){    		      		
    	   	   print( FILEOUT_PFSVOD $tab[3].";".$myOpeTechCTRCAN.";".$myProdTechCTRCAN."\n");   	
    	   	}
    	   }
    	   if (scalar(@tab)>4){	      
    	      if($tab[4] eq "CTRCSA"){	      	
    	   	print( FILEOUT_IDENTITE_AUX ";".$myVersion.";".$myIDMA.";".$myIdTypeIdentifiantCTRCSA.";".$tab[5].";0;".$myTimeStamp.";".$myDate."\n" ); 		   	   		   	
       		if ($myStatutMA eq "1" ){	  		
    	   	   print( FILEOUT_PFSVOD $tab[5].";".$myOpeTechCTRCSA.";".$myProdTechCTRCSA."\n");   	
    	   	}
    	     }
    	   }  	   			      
     
          }  	      
       }#while

  11. #11
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je ne vois rien d'évidemment mauvais.
    Je te conseillerais tout de même d'utiliser les pragmas strict et warnings.

    Cependant, le comportement même de l'application Perl indique un problème : il n'y a aucune raison que Perl aille plus vite avec plusieurs petits fichiers qu'avec un gros, du moment qu'il ne garde pas en mémoire une quantité trop grande de données.
    J'aimerais que tu me dises si il y a une différence de taille de la mémoire utilisée par Perl entre les cas petits fichiers et gros fichiers de façon à savoir s'il y a un point que tu ne nous montres pas ici et qui expliquerait le phénomène.
    J'aimerais aussi que tu vérifies que c'est bien la partie Perl qui pose problème, est-ce vraiment elle qui prend moins de temps avec des petits fichiers, ou est-ce sqlloader ?

    --
    Jedaï

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut alors:
    maintenant je ne pense pas aussi que ce soit perl car perl fonctionne sur mon PC et la base sur un autre.
    Quand le programme est lancé, mon CPU ne tourne pas à 100%, ce qui veut dire qu'il passe son temps à attendre la réponse de la base.
    Etant donnée que la base peut gérer en parallèle les requetes même si chacune peut prendre beaucoup de temps (comme muti processus), je pense qu'en lançant n exécutions de mon programme d'une manière parallèle (sur plusieur fenetre dos) , ça réduit le temps avec plsueires requetes envoyé à la base

    POur l'instant, j'ai juste un problème de conflit au niveau de clé primaire: tu peux voir par ex avec mes questions sur
    http://www.developpez.net/forums/sho...=1#post2102507

    en un mot, je dois gérer UNE variable commune entre tous les programmes lancés

    cathy

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut c dans
    Forum des développeurs > Bases de données > Oracle >incrémentation automatique de clé

  14. #14
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Mon conseil : tu continues avec un seul processus Perl, puisque ce n'est pas là qu'est situé le problème de vitesse, ainsi pas de problème de clé primaire (si j'ai bien compris), mais au lieu de produire un gros fichier que tu passes à sqlloader, tu produis une multitude de petit fichiers, que tu passes en parallèle à des instances de sqlloader avec un "system("sqlloader options $filename &");".
    Par exemple tu produis un fichier de sortie et tu le passes à sqlloader toutes les 500 entrées, ou quelque chose comme ça. Fais des test pour trouver la valeur optimale.

    --
    Jedaï

  15. #15
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Jedai
    "system("sqlloader options $filename &");".
    Si tu es sous Windows la syntaxe ci-dessus ne fonctionnera pas (puisqu'elle s'appuie sur une fonctionnalité des shells unix), il va falloir que tu fasses ton fork à la main ou que tu utilises un module type Win32::Job, ou Win32::Process.

    --
    Jedaï

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut hmmmm...
    j'ai encore du mal de voir comment cette méthode réduira le temps de traitement qui est l'objectif de ce sujet

    merci

    Cathy

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 75
    Points : 38
    Points
    38
    Par défaut grosso modo
    c'est le perl qui consulte la base qui pose le problème. Quand je disais que perle ne posait pas le problème c'est que les calculs sans des SQL dans ce
    code vont vite, parcontre quand perl lance une SQL à la base, il faut attendre un peu
    D'ou l'idée de lancer plusieurs programme perl: quand un est bloqué à cause de l'attende d'une réponse de la base, il peut laisser le processuer
    à un notre programme perl. Ainsi plusieurs proc perls=plusieurs requetes SQL. Comme la base peut paralliser les réponses des requetes.
    ceci ne change pas le temps de réponse de SQL au niveau de la base.
    C'est ainsi que ça va vite. Ex simple, pour le meme nombre de traitements, si je divise en
    - 1 proc=>35 min
    - 2 proc=>20min
    - 6 proc=>12min
    - 12 procs=>8min

  18. #18
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Les sqlloader tourneront en parallèle, pas le script Perl. Puisque là où il y a une perte de temps c'est lors de l'exécution des requêtes ceci devrait réduire le temps total. Mais comme il n'y a qu'une seule instance du script Perl, tu n'as pas le problème de la clé primaire.
    system("sqlloader options $filename &");
    Le & dans un shell unix ordonne au shell d'exécuter la commande en tâche de fond, autrement dit si tu étais sur un système Unix, ce system() lancerait un sqlloader puis continuerait sans attendre que sqlloader ait fini de traiter toutes ses requêtes. Il est très probable (cela dépend du nombre d'entrée entre deux system() que tu choisis) que le sqlloader suivant soit lancé avant que le premier n'ait terminé son exécution.

    Le script devrait ressembler à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    my $interval = 500;
     
    my $i = 0;
     
    my $outfile;
    my $outputbasename = 'output';
     
    open $outfile, '>', "$outputbasename.$i"
      or die "Can't open $outputbasename.$i : $!\n";
     
    while( my $line = <$data_input> ) {
     
      # lecture
     
      # écriture dans $outfile
     
      if( not $. % $interval ) {
        system "sqlloader options $outputbasename.$i &";
        $i++;
        open $outfile, '>', "$outputbasename.$i"
          or die "Can't open $outputbasename.$i : $!\n";
      }
    }
     
    system "sqlloader options $outputbasename.$i &";
    --
    Jedaï

  19. #19
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ok je n'avais pas compris que Perl était obligé de consulter la base à chaque lecture de ligne... Y a pas moyen de faire ça un peu plus intelligemment ? Par exemple faire une requête tous les 200 lignes (ça tu peux les maintenir en mémoire, ce n'est pas un problème) ? Evidemment sans savoir à quoi ressemblent ces requêtes il m'est difficile d'en dire plus. J'espère que tu utilises bien les placeholders et que tu prepare() tes requêtes en dehors de la boucle au moins ?

    --
    Jedaï

  20. #20
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Finalement si rien de tout ceci n'est possible, essaie d'utiliser les threads, si tu as une version récente de Perl et que tu ne fais pas de truc trop exotiques ça devrait passer.

    --
    Jedaï

Discussions similaires

  1. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  2. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  3. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05
  4. Comment débuter en programmation ?
    Par Marc Lussac dans le forum Débuter
    Réponses: 0
    Dernier message: 08/04/2002, 11h29
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo