France Hardware : Forums de discussion
Retrouvez les prix près de chez vous :  
Index du forum | Liste des membres | Liste des groupes | Inscription | F-A-Q | Recherche
Pseudo :    Password :     
23 592 membres enregistrés - 1 913 480 posts - 99 188 topics
Index des forums FH  | Index des forums DegroupNews
      Programmation
           Traitement parallèle Split Unix
16 connectés(record : 272 le 28 octobre 2008 - 04 h 23)

Vous devez vous connecter pour répondre au topic.
Traitement parallèle Split Unix

mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 05 mai 2003 - 11 h 40 m 03 s
Bonjour,

Je developpe une appli qui doit traiter des sous fichiers obtenus par un split de très volumineux fichiers (insertion dans un base de donnees oblige). Le problème c'est que le split me prend des heures (ce sont des fichiers de logs ) et je dois attendre la fin de cette operation pour commencer l'insertion de mes donnees dans une base de données. Dans un souci d'optimisation, je pense qu'il serait interressant de proceder parallèlement à l'execution du split à l'insertion des données a chaque fois que le split crée un sous fichier. Quelqu'un aurait il une idee de comment recuperer parallèlement à l'execution de split un sous fichier créé?

Merci




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 05 mai 2003 - 13 h 16 m 43 s
Si tu traites de gros fichiers logs, est-ce une necessité de passer par les splits ? un script Perl te permet un accès sequentiel au log (lecture ligne par ligne, ca ne sature pas la mémoire système), des traitement très efficaces (vive les RegExp en Perl: rapides, souples), et limite l'accès DB à une connexion (le fait de creer une connexion DB est une "grosse" opération, parce que le système genère un process pour chaque connexion)

Bon, si tu a vraiment besoin de passer par la phase de split, qq idées:

un boucle qui parcoure les suffixes générés par split (aa,ab,ac,...)

dans la boucle, pour l'incrément n (supposons le suffixe "aa", et le fichier a splitter nommé FILE):

- tu testes si le "sous-fichier" n+1 (FILEab) du split existe:
tu ne vas pas traiter FILEaa dès qu'il existe, car tu ne sais pas si le split a terminé l'écriture de ce fichier. Il faut attendre d'avoir FILEab pour traiter FILEaa - attention, effet de bord sur le dernier "sous-fichier" qu'il faudra déterminer - par exemple process de split terminé...-

=> si le "sous-fichier" n+1 (FILEab) existe:
tu lances en background ta procedure de chargement du sous-fichier n (FILEaa) dans la base. eventuellement mettre un verrou (compteur,semaphore - qu'il faut penser à incrementer/decrementer chaque fois qu'un chargement est terminé) sur le nombre de chargements // en cours. Si tu ne limite pas le nombre de chargements en cours, ta base risque de faire la gueule, voire tu risque de saturer le nombre de connexions à cette base, ou tu vas occuper eventuellement toutes les CPUs au détriment du split ou de la DB si le chargement nécessite également du traitement...

=> si le "sous-fichier" n+1 n'existe pas, une petite temporisation (à determiner de manière empirique... 5/30/60... secondes selon le temps qu'il faut pour obtenir un "sous-fichier") et retour au test...

Bien entendu, je suppose que le traitement (split, chargement) est realisé sur une machine Xprocesseurs. A la rigueur, si c'est pour executer sur une machine monoproc, il faut quand même que la base utilise des ressources disques différentes de celles où sont stockés les sous-fichiers. Ainsi la base peux realiser des IOs meme si le split ou les process de chargement sont en attentes de leurs IOs. Sinon ca n'a aucun sens de faire des chargements en //.






mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 05 mai 2003 - 14 h 53 m 18 s

Le 05/05/2003 à 13h16 , tempo a écrit:
Si tu traites de gros fichiers logs, est-ce une necessité de passer par les splits ? un script Perl te permet un accès sequentiel au log (lecture ligne par ligne, ca ne sature pas la mémoire système), des traitement très efficaces (vive les RegExp en Perl: rapides, souples), et limite l'accès DB à une connexion (le fait de creer une connexion DB est une "grosse" opération, parce que le système genère un process pour chaque connexion)

Bon, si tu a vraiment besoin de passer par la phase de split, qq idées:

un boucle qui parcoure les suffixes générés par split (aa,ab,ac,...)

dans la boucle, pour l'incrément n (supposons le suffixe "aa", et le fichier a splitter nommé FILE):

- tu testes si le "sous-fichier" n+1 (FILEab) du split existe:
tu ne vas pas traiter FILEaa dès qu'il existe, car tu ne sais pas si le split a terminé l'écriture de ce fichier. Il faut attendre d'avoir FILEab pour traiter FILEaa - attention, effet de bord sur le dernier "sous-fichier" qu'il faudra déterminer - par exemple process de split terminé...-

=> si le "sous-fichier" n+1 (FILEab) existe:
tu lances en background ta procedure de chargement du sous-fichier n (FILEaa) dans la base. eventuellement mettre un verrou (compteur,semaphore - qu'il faut penser à incrementer/decrementer chaque fois qu'un chargement est terminé) sur le nombre de chargements // en cours. Si tu ne limite pas le nombre de chargements en cours, ta base risque de faire la gueule, voire tu risque de saturer le nombre de connexions à cette base, ou tu vas occuper eventuellement toutes les CPUs au détriment du split ou de la DB si le chargement nécessite également du traitement...

=> si le "sous-fichier" n+1 n'existe pas, une petite temporisation (à determiner de manière empirique... 5/30/60... secondes selon le temps qu'il faut pour obtenir un "sous-fichier") et retour au test...

Bien entendu, je suppose que le traitement (split, chargement) est realisé sur une machine Xprocesseurs. A la rigueur, si c'est pour executer sur une machine monoproc, il faut quand même que la base utilise des ressources disques différentes de celles où sont stockés les sous-fichiers. Ainsi la base peux realiser des IOs meme si le split ou les process de chargement sont en attentes de leurs IOs. Sinon ca n'a aucun sens de faire des chargements en //.





Merci bien pour tes conseils, Tempo. En fait, je connais pas assez bien Perl mais veux bien essayer et j'utilise l'outil Sybase bcp pour effectuer l'insertion du contenu du fichier texte dans une base de données Sybase. En fait, c'est dans le cadre de mon stage et je dois reprendre le travail que quelqu'un d'autre a fait car le traitement realisé actuellement est très lent (un peu trop d'ailleurs). Ces fichiers de logs sont recuperés au format zippé. Voici une idée de bout de code qu'il utilise pour l'insertion des donnees bruts dans la base de donnees :
%gunzip -c ${SRC} | ${FILTRE} | split -l 240000 - ${TMPDIR}/${DEST} // le fichier de log peut etre tres volumineux
// le filtre existe deja et est un script Perl
.....
....
for F_NAME in $( ls ${TO_FILE}?? ) ; do
// corps de la procedure d'insertion
% /opt/sybase/bin/bcp ${TABLE_DESTINATION} in ${FILE_SOURCE} -S ${SYB_HOST} -U ${SYB_LOGIN} -P ${SYB_PASSWD} -e ${ERROR_LOG} -b 12000

done

S'il m'est possible de ne pas passer par l'etape du split, je gagnerai enorment de temps.
Peux tu me donner un idee de comment je pourrais faire cela sous Perl ?

Merci d'avance




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 05 mai 2003 - 18 h 24 m 19 s
ok, c'est plus cool avec ces infos...

le gros probleme est que d'un coté on lise un fichier (gunzip) et que de l'autre on ecrive les "chunks" (split). Si ces operations sont realisée sur un meme disque, c'est pas ce qui est des plus performant

le mieux est de faire un seul script perl qui lit STDIN (garder le "gunzip -c" pipé) ligne par ligne, traite les données log, et fasse des INSERT directement dans la table (sans passer par le "bcp" de Sybase...). ca evitera de faire des "aller-retour" de données sur le disque.

il existe egalement un "module" Perl pour se connecter sur une base Sybase (module "DBD" = DataBase Driver):
http://search.cpan.org/author/MEWP/DBD-Sybase-1.00/Sybase.pm
Apres, tu utlises le module DBI qui donne un acces "generique" a une base (juste preciser le drivers DBD Sybase et qq parametres a la connexion...)

un debut d'idee en perl:

#!/usr/bin/perl -w (a adapter a l'install de perl, garder -w pour les warning...)
use strict;
use DBI;

my $dbh = DBI->connect("dbi:Sybase:server=....", $user, $passwd);

foreach my $ligne (<STDIN>){
# ligne contient un ligne du fichier passé a STDIN...
# la, j'imagine:
next if $ligne =~ /^#/; # fcommentaire, passe a la ligne suivante...
my ($champ1,$champ2,champ3) = split ' ',$ligne; #separateur: espace
my $sth = $dbh->execute("INSERT table(field1,field2,field3) VALUES ($champ1,$champ2,$champ3)");
}

(je connais pas DBI, mais la syntaxe d'un Insert ne devrait pas etre trop eloignee...)

Bien sur, je te dis tout ca... vois quand meme avec ton maitre de stage




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 05 mai 2003 - 19 h 11 m 12 s
Merci Tempo, j'ai maintenant une idée assez nette, je pense pouvoir m'en tirer assez facilement. Mon maitre de stage est Ingenieur système, les SGBD c'est pas trop son truc.
Encore merci pour ton coup de main.
Je te recontacte si d'aventure je bute sur un os.

Bonne journee et merci encore pour ton coup de main. C'est trop gentil à toi de prendre autant de temps pour me faire cette belle analyse.






tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 05 mai 2003 - 20 h 35 m 41 s
Un (bon) ingé systeme devrait avoir qq rudiments en perl, mais pourra surtout te confirmer qu'il faut éviter les accès IOs (disques) pour eliminer une bonne part des pb de performance.

Dans tous les cas, tu trouveras plein d'exemple en Perl sur le web, pour lire un fichier ligne par ligne et analyser ces lignes ("parser") et utiliser le module DBI.

Pour moi, ca me fait plaisir...

(tempo = un ingé pas vraiment système, pas vraiment analyste, mais qui est en vacances pour tout le mois de Mai !!!)




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 07 mai 2003 - 11 h 59 m 42 s




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 07 mai 2003 - 12 h 06 m 14 s
salut Tempo,

Une information que je viens d'avoir : Le bcp semble necessaire dans la mesure ou il ecrit dans le fichier de logs ce qui permet de faires des Rollbacks,des checkpoints et autres operations necessaires à la gestion des transactions. De plus, toute erreur rencontrée par bcp lors de l'insertion est loggée dans un fichier d'erreur ...ce qui permet ensuite un debuggage.
Autre chose : penses tu que zcat donne de meilleurs resultats que gunzip -c ?

Merci




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 07 mai 2003 - 13 h 10 m 20 s
pour bcp:
- pourquoi traiter des chunks ("sous-fichiers") ? pour garder un "point de reprise" en cas de plantage ? sinon, pour eviter les IOS (disques), peut etre piper directement la sortie du traitement dans bcp (ou via un FIFO)
- avec Perl+DBI, on peux aussi desactiver l'autocommit, et faire du transactionnel... par contre c'est au script de gerer les erreurs (traitement, connexion DB) et il faut apprendre Perl :D

pour zcat
c'est pas plutot gzcat ??? (les algo Z et gz sont differents...). Normalement, gzcat est le meme binaire que gunzip (juste le nom qui chnage :D - verifie la taille des binaires et essaie un md5sum pour verifier leurs signatures). La commande info sur le binaire du gunzip pourra aussi te dire si ton binaire est optimisé pour la plateforme sur laquelle tu travailles (vu sous HP-UX 11, processeurs 64bits PA2.0: les binaires sont encore compilés en 32 bits PA 1.1...). Recompiler ton propre gunzip est un jeu d'enfant (quand tu a un compilo et un linker :) ) et pourra eventuellement ameliorer les performances en decompression...




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 07 mai 2003 - 14 h 26 m 05 s
:o oups, la commande pour les infos sur un binaire c'est file... :)




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 07 mai 2003 - 18 h 39 m 23 s
Ouais, le bcp sur les chunks c'est pour eviter que toute l'operation ne s'annule lorsqu'on rencontre une erreur. Comme ca en cas d'erreur, on n'aura qu'a agir sur le chunk concerné et non sur tout le fichier de log.
Pour zcat c'etait une erreur, je voulais dire gzcat. J'ai eu la confirmation après que gunzip -c = gzcat .
J'ai verifié : mon gunzip ainsi que mon split sont compilés sous 32 bits ( ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped )

Merci








tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 07 mai 2003 - 19 h 48 m 58 s
si t'es sur un serveur ou une workstation avec proco UltraSparc et OS Solaris 7(ou +) tu dois pouvoir utiliser gunzip|gzcat et split en version 64 bits :D j'oubliai, Perl aussi peut etre plus performant en 64 bits...

Pour ce, soit tu recompiles ces packages toi-même dans ton home (ou le home "applicatif", ou le filesystem dedié a l'application), et tu set ton PATH pour utiliser les binaires avant ceux définis dans le PATH "standard", soit tu demandes à l'admin système qu'il installe les packages 64bits prets a l'emploi :)
:love: La compilation de gzip et split, c'est normalement tres facile. Perl, faut bien lire la doc... (sous HP-UX c'est galere... mais c'est lié aux packages qui sont sur nos machines et qui nous obligent a garder du perl 5.005, alors que 5.8 semble au point pour ces portages 64 bits)

Le filtre Perl peut aussi etre a la base du "bottleneck" (point de contention) du traitement... essaie un gunzip directement pipé dans split, pour voir si c'est vraiment plus rapide :)

Enfin, vu que t'es obligé de passer via bcp, y'a plus que le systeme de la boucle qui check la presence du chunk suivant pour traiter un chunck...

courage !!!




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 12 mai 2003 - 16 h 53 m 17 s
Salut Tempo,

Je procède par etape pour tuner mon système. Le bcp est obligatoire et en plus, je peux pas installer de compilateur sur le serveur qui se trouve dans la DMZ (donc pas moyen installer DBI qui utilise cc ou gcc) . je suis à la phase de filtrage de mes donnees pour le rendre dans un format correct afin de le spliter et inserer les chunks dans ma base de donnees. Voici le format des logs contenus dans le fichier zippé.
2104.461 1045 196.20.20.17 TCP_TUNNELED/900 195 CONNECT https://www.turbo.com:132/ CN=Jeff Smith-Adolph,OR=sf,E=silog DIRECT/www.achat.com - uncategorized Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)

Voici le script perl que j'ai amelioré pour faire le filtrage (je gagne du temps par rapport à la version originale) . Je met 33m30.908s pour traiter un fichier de log de 1592326 lignes contre 35m48.435s pour le script de filtrage original (c'est tres negligeable comme gain de temps). Crois tu que ce temps soit raisonnable ? Le comble c'est que l'appli doit traiter au moins 5 fichiers de cette taille par jour alors merci la lenteur ....
Si tu as une idee pour l'amelioration de mon script, ca m'ira très bien :
le voici : (dans la version originale, les champs transitaient dans des variables avant l'ecriture final)

#!/usr/bin/perl

use POSIX;
use URI::URL;

$base = "s";
$space_ended = '([^s ]*)s';
$slash_ended = '([^s]*)/';
$ip = '(d*.d*.d*.d*)s';
$r_date = '(d*.d*)s';
$r_elap = '(d*)s';
$r_ipc = $ip;
$r_type = '([^s]*)/';
$r_stat = $space_ended;
$r_siz = $space_ended;
$r_meth = $space_ended;
$r_url = '(.*)s';
$r_url1 = $space_ended;
$r_usr = 'CN=(.*O=[^s]*)s+';
$r_ousr = $space_ended;
$r_nusr = '(-)s';
$r_hier = $slash_ended;
$r_dom = $space_ended;
$r_cont = $space_ended;
$r_scf = $space_ended;
$r_ref = '(.*)';

$LOG= '^'.$r_date.$r_elap.$r_ipc.$r_type.$r_stat.$r_siz.$r_meth.$r_url.$r_usr.$r_hier.$r_dom.$r_cont.$r_scf.$r_r
ef;

open (FILE,">/LOG_bad_lines.log") || die "Pb d'ouverture : $! ";

while (<>) {
if ( m#$LOG# ) {
$date = POSIX::strftime("%d/%b/%Y %T", localtime($1));
if ( $4 !~ /TCP_DENIED|TCP_ERR_MISS|TCP_SWAPFAIL|UDP_DENIED|UDP_INVALID/ )
{
$uri = URI::URL->new($8, $base) || die "probleme: $! $_";
$url = $uri->epath;
$domaine = $11;
if ( ( $domaine eq '-' ) || ( $domaine eq '' ) ) { if ( $url =~ ///(.*)// ) { $domaine=$1 } }
print STDOUT "$date#$2#$3#$4#$5#$6#$7#$urlt$9#$10#$domaine#$12#$13n";
}
else {
print FILE $_;
}
}
}


Merci d'avance




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 12 mai 2003 - 18 h 54 m 26 s
t'as l'air de bien maitriser les regexp :D

le ligne de log de ton proxy (il semble que c'en soit un) n'est pas optimale pour etre traitee (en general, on utilise des "" autour des champs pouvant contenir des espaces - agent, authldap, ...- ... mais bon, faut que tu fasses avec...)

pour separer la ligne de log en champs, en general on utilise "split" en Perl ( my @champs = split /regexp/,$logline ) (attention, split peut avoir des comportement etranges quand on ne le connais pas trop...)

Mais en utilisant le "match", pourquoi pas... Par contre, comme le motif de l'expression reguliere est "constant" et que tu le mets dans le scalaire $LOG pour faciliter la concatenation, tu devrais gagner en mettant le modificateur o:

if ( m#$LOG#o ) {

ainsi, la valeur du motif $LOG est evaluée a la compilation|1ere execution puis n'est plus reevaluée à chaque iteration
Les autres motifs sont constants, donc il ne devrait pas y avoir de probleme...

Enfin, si tu as 5 fichiers comme ca a traiter par jour, c'est pas le bout du monde si chacun prend 3/4 d'heure et que tout est fait en batch... faut juste pas depasser les 24h de traitement pour l'ensemble :D




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 14 mai 2003 - 17 h 51 m 16 s
Merci Tempo,

J'essaie d'appliquer tes conseils et je te tiens au courant des resultats obtenus.

Merci pour tout.




tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 14 mai 2003 - 18 h 37 m 52 s
surtout le "o" pour la regexp du match !!!




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 15 mai 2003 - 15 h 04 m 17 s
ok, c'est bien noté pour le o. Par contre j'ai un souci : j'execute 2 scripts ksh en parallele (par un pipe) et je souhaite executer des fonctions disponibles dans le 1er à partir du 2ème. Est ce possible ?

@+




mandrake74
Buffer overflow

Messages : 1 287
Inscrit le 09/12/02
Ville : Paname
Non connecté
  Posté le 15 mai 2003 - 16 h 05 m 13 s
taka essayer :D

Je crois pas ke le shell ait ete concu pour l'heritage des methodes, surtout en utilsant le pipe..:wink: mais bon tu peux toujours t'en sortir en creant un shell "main" appellant tes shells "fonctions" avec les parametres ki vont bien ca marche aussi.

Et si tu peux pas eviter ton pipe, tourne toi vers le perl et passe par les forks -jolie la lecon tempo, j'avoue tu m'as bluffé là, et voui des kon fait un peu de systeme fo se forcer un peu au perl, mais apres on ne jure ke par lui des ke ca se complike un peu :wink:


faut juste pas depasser les 24h de traitement pour l'ensemble :D

:lol: :lol: :lol:


(tempo = un ingé pas vraiment système, pas vraiment analyste, mais qui est en vacances pour tout le mois de Mai !!!)

:D
(mandrake = un ingé pas vraiment système, pas vraiment analyste, mais qui fait un taf alacon jusko mois de juin)
:wink:




NOP NOP NOP LOOP CALL

tempo
Zen

Messages : 2 177
Inscrit le 14/09/02
Ville : Grenoble (SMH)
Non connecté
  Posté le 16 mai 2003 - 01 h 34 m 54 s

Le 15/05/2003 à 15h04 , mikila a écrit:
ok, c'est bien noté pour le o. Par contre j'ai un souci : j'execute 2 scripts ksh en parallele (par un pipe) et je souhaite executer des fonctions disponibles dans le 1er à partir du 2ème. Est ce possible ?

@+



facile :D :

1/ tu définis tes fonctions dans un ksh "tiers", par ex /opt/projet/scripts/functions.ksh

2/ tu "sources" ce script de fonction dans chacun de tes 2 scripts ksh

#!/usr/bin/sh (<= adapte)

. /opt/projet/scripts/functions.ksh


(mandrake, dis pas que c'était difficile :wink: )

En effet, tu as bien du voir que si tu executes un script A a partir d'un script B, en revenant dans le script B tu ne peux pas utiliser les variables eventuellement définies|calculée dans A (normal, A s'execute dans un nouveau shell)

Avec la parade de "sourer" un script ("point-espace-script"), ce script s'execute dans le shell courant.

Je te conseille vivement d'utiliser ce principe pour tes scripts avec les variables d'environnement ou de fonctions (sic !!! des fonctions en ksh !!! mandrake a raison, Perl est fait pour ça :wink: )

Note (si tu vas utiliser cron, ce qui est fort a parier :D ):
un truc qui me :x et que je vois trop frequement, c'est les gens qui definissent les varibles d'environnement "applicatives" (ORACLE_HOME, PATH et autres variables propres aux traitement) dans le ".profile".
Si ces même variables sont alors utilisée par des scripts cron, le premier truc qui va etre fait par ces gens sera de sourcer le .profile dans le script du cron (juste a "maintenir" le .profile)...
Erreur: le .profile (notament en ksh) contient des commandes d'init du terminal qui genere des erreurs lorsqu'elles sont executée en cron (normal, pas de tty ...). or les sorties d'erreur cron sont retournée via mail au compte pour lequel cron réalise le job.
Là,
a/ soit ces gens ne lisent pas les mails des comptes unix: ils ratent donc d'eventuelles erreurs d'execution et les mailbox se remplissent
b/ soit ces gens redirigent les mail des comptes unix vers un compte mail support (fichier .forward :D ) et sont blasés de ces fausses alertes (=> suppresion .forward et retour à a/) ou redirigent la sortie d'erreur des scripts vers /dev/null
solution (propre):
1/ faire un fichier ou sont definies les variables d'environnement
applicatives
2/ sourcer ce fichier dans le .profile
3/ sourcer ce fichier dans les scripts cron




mikila


Messages : 10
Inscrit le 05/05/03
Ville : Paris
Non connecté
  Posté le 16 mai 2003 - 13 h 37 m 58 s
Merci pour vos contribs, je suis parti pour 10 heures de code non stop (j'ai interet a avancer assez bien avant que Tempo ne reprennes son job debut Juin) :)
Bon week end a tous ...




Page genérée en 1.6193 secondes par RahForum 2.0 | Gzip off |  Stats |  Metaforums |  RSS
© 2004 Cerbere Systems.
Prix Matériel Informatique | Informatique Lyon | Informatique Grenoble | Informatique Annecy | Informatique Marseille | Informatique Bordeaux | Forum Informatique
ADSL |Actualité ADSL | e-commerce | Commande Au Volant
Creative Commons
Message Boards and Forums Directory