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

Persistance des données Java Discussion :

Répartition de répertoires en plusieurs groupes de "même" taille


Sujet :

Persistance des données Java

  1. #1
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut Répartition de répertoires en plusieurs groupes de "même" taille
    Salut à tous !

    Je suis nouveau sur ce forum, donc j'espère que j'ai bien placé mon post ! Sinon je m'en excuse et j'essaierai de faire le nécessaire pour le positionner à l'emplacement voulut.

    Donc je vous explique rapidement mon problème

    J'ai créé une application java qui parcourt des milliers de fichiers et qui en fait une signature numérique (md5), afin de détecter un fichier ajouté/modifié/supprimé.
    Je dispose de plusieurs machines linux, c'est pour cela que je souhaite exécuter mon programme sur chaque machine (via SSH), afin d'aller plus vite ! Car pour l'instant sur une seule machine ça me prendrait environ 2 mois à tout parcourir et signer.

    Bref, ce module étant réalisé, je suis en train de développer une autre application qui se chargera de répartir les répertoires à parcourir sur chaque machines.
    J'ai dans ma base de données MySql une table qui contient les répertoires à parcourir ainsi que leurs poids.
    J'ai donc calculé la taille moyenne qu'une machine peut parcourir (Poids total de tous les répertoires, divisé par le nombre de machines disponibles), et j'aimerai faire un petit algo qui va remplir la troisième colonne de ma table, à savoir le nom de la machine attribué au répertoire.

    J'ai donc créé une classe DirectoryToParse qui contient 3 attributs : path, size et machineNumber.
    J'ai également créé un Vector qui contient tous les directory sous forme d'objet DirectoryToParse trié par size croissant.


    J'ai donc pensé à faire ça :
    Le premier objet de mon Vector a-t-il une size supérieure à la taille moyenne qu'une machine peut parcourir ?
    __oui -> Alors j'attribue une machine pour ce seul directory
    __non -> Alors, le premier objet de mon Vector (avec la size la plus petite) + le dernier objet de mon vector (avec la size la plus grande) sont-t-il supérieur à la taille moyenne ?
    ______oui -> Ok j'attribue ces deux directory à une machine
    ______non -> idem avec premier objet + deuxième + dernier ?
    __________ oui -> ...
    __________non -> ...

    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
     
    public static void createAllProcesses() {
            int nbOfPrecesses = 0;
            long totalSizeToParse = DBUtils.getTotalSizeToParse();
            long maxSizeOfAProcess = totalSizeToParse / Constants.Constants.getNbOfEngine();
     
            Vector list = new Vector(DBUtils.getListToParse());
            int nbOfElement = list.size();
     
            for (int i = 1; i <= nbOfElement; i++) {
                Model.DirectoryToParse firstDirectoryObject = (DirectoryToParse) list.get(i);
                long size = firstDirectoryObject.Size;
                if (size>=maxSizeOfAProcess) {
                    nbOfPrecesses++;
                    firstDirectoryObject.processNb = nbOfPrecesses;
                } else {
                    while (size <= maxSizeOfAProcess) {
                         Model.DirectoryToParse secondDirectoryObject = (DirectoryToParse) list.get(nbOfElement);
                         nbOfElement--;
                         long secondSize = secondDirectoryObject.Size;
                         if (secondSize + size >= maxSizeOfAProcess) {
                             nbOfPrecesses++;
                             firstDirectoryObject.processNb = nbOfPrecesses;
                             secondDirectoryObject.processNb = nbOfPrecesses;
                         }
                    }
                }
            }
        }
    Je pense que vous avez tous remarqué le problème dans mon algo.
    Il faut que je fasse une méthode récursive, à savoir une méthode qui s'appelle elle-même (j'espère ne pas dire de bêtises), cependant je n'arrive pas à savoir quelle partie du code isoler dans une méthode et comment l'organiser. Elle doit prendre en paramètre une size je suppose, mais je sais pas là je bloque...

    J'espère avoir réussi à expliquer mon problème de manière assez claire..
    Si vous avez des idées même si cela implique de changer totalement la logique de mon appli, je suis preneur !
    Je trouve que ce que je fais n'est pas du tout propre donc je suis preneur pour toute suggestion !

    Petites infos supplémentaires pouvant être importante :
    Java: 1.7
    IDE: NetBeans
    Platform: Red Hat 5
    BDD: MySql
    Connector: JDBC

    Merci à tous !

  2. #2
    Membre expérimenté Avatar de nchal
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 512
    Points : 1 656
    Points
    1 656
    Par défaut
    Salut

    Je pense que je vais faire une réponse qui est loin d'être complète mais ça peut toujours t'aider je pense
    Tout d'abord, plus de Vector, c'est vieux, mono-thread et obsolète. Le mieux (avis personnel), c'est une ArrayList. Ça fait parfaitement ce pour quoi c'est fait.

    Ensuite, niveau algo, je ne comprend pas pourquoi tu cherches à associer un gros dossier avec un petit (peut-être que tu as pensé à qqchose que je ne vois pas) mais moi je partirais plus sur :
    je prend tous les éléments de la liste dans l'ordre jusqu'à ce que je dépasse la taille max.

  3. #3
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut
    Salut !

    D'abord merci d'avoir pris le temps de lire et de répondre à mon problème.

    C'est noté pour le Vector effectivement c'est un ArrayList que je voulais …

    Ensuite ce qui est d'associer un gros dossier avec un petit et ainsi de suite, je sais pas trop j'ai pensé à ça mais il y a quelques temps déjà je me rappelle plus trop pourquoi j'ai pensé à faire ça comme ça, mais c'est vrai que si je fais comme tu as dit ça devrait être bon aussi
    Du coup je vais essayer de faire comme ça, j'aurai surement plus le problème d'isoler dans une méthode qui s'appelle elle-même, j'essaye ca et je reviens faire un récap.

    Merci à toi Nicolas !

    A bientôt

  4. #4
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut
    Salut !

    Ca y est j'ai réussi avec ta solution, merci encore !
    Je mets un petit bout de code, ça peut toujours servir !

    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
    34
    35
    36
     
    public static void createAllProcesses() {
     
            int processNumber = 0;
            long totalSizeToParse = DBUtils.getTotalSizeToParse();
            System.out.println("Total size to parse = " + totalSizeToParse);
            long maxSizeOfAProcess = totalSizeToParse / Constants.Constants.getNbOfProcessors();
            System.out.println("Max size per process = " + maxSizeOfAProcess);
     
            ArrayList<DirectoryToParse> list = new ArrayList<DirectoryToParse>(DBUtils.getListToParse());
     
            int nbOfElement = list.size();
            System.out.println("Number of element to parse = " + nbOfElement);
     
            long tmpSize = 0;
     
            for (int i = 0; i < nbOfElement; i++) {
                tmpSize = list.get(i).Size;
                System.out.println("tmpSize = " + tmpSize);
                int first = i;
                while(tmpSize < maxSizeOfAProcess) {
                    i++;
                    tmpSize = tmpSize + list.get(i).Size;
                    System.out.println("tmpSize = " + tmpSize);
                }
                int last = i;
                System.out.println("First = " + first + "\nLast = " + last);
                processNumber++;
                System.out.println("ProcessNumber = " + processNumber);
                while (first <= last) {
                    list.get(first).processNb = processNumber;
                    DBUtils.setProcessNumberInDB(processNumber, list.get(first).URL);
                    first++;
                }
             } 
        }
    Voilà je peux mettre les autres classes si quelqu’un ne comprend pas trop et qu'il veut le reste.
    Merci pour ton aide Nicolas et à bientôt sur ce forum

    Alex

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    je ne comprends pas, tu compte utiliser, disons, 3 machines pour faire le MD5 du contenu d'un seule machine? J'ai du mal à voir en quoi ça te permettrait de gagner du temps. Ce qu'il faut c'est que chaque machine fasse les MD5 de ses propres fichiers. Toute transmission par le réseau du fichier en vue de faire du md5 sera d'office plus lent que de faire ce md5 sur la machine d'origine. Pourquoi? Parce que la transmission sécurisé implique déjà d'effectuer toutes une série de signature cryptographiques sur les paquets => au lieu de faire un md5 tu en fais peut être des centaines.

    Si il te faut deux mois pour faire les md5 d'un seule machine, c'est le code de signature qu'il faut revoir

  6. #6
    Membre expérimenté Avatar de nchal
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 512
    Points : 1 656
    Points
    1 656
    Par défaut
    Je pense qu'il y a un stockage distant et il a voulu répartir les fichiers à traiter par machines. Par exemple, la machine 1 va traiter les fichiers tant à tant, la machine 2 de tant à tant, ainsi de suite. Toutes les machines vont mettre leurs résultats au même endroit.
    Ça explique pourquoi il y a une base avec un path et un numéro de machine, chaque machine va requêter la base pour connaitre tous les paths qu'ils lui sont attribués.
    L'algo sert juste à répartir les paths entre les machines pour ne pas avoir une machine qui traite 250Go et une autre 20Go.

    Concernant tous les machines MD5, j'y connais rien alors je ne me prononce pas

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    oui oui, mon point de vue est qu'il faut éviter de transférer le fichier pour faire un md5sum. Un simple test ici sur une machine "vieillotte" partagée entre plusieurs utilisateurs m'amène à 150MB/s pour une signature md5, et 281MB/s sur une machine plus récente.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ dd if=/dev/zero bs=5120k count=100 | md5sum
    100+0 records in
    100+0 records out
    524288000 bytes (524 MB) copied, 3.49809 s, 150 MB/s
    d8b61b2c0025919d5321461045c8226f  -
    Autrement dit, pour avoir un gain en parallélisant le calcul sur deux machines, et arriver à +- 500MB/s, il faudrait au pifomètre (je suppose que SCP + SSH + TCP + IP + Ethernet amène un overhead de *2) une ligne à 8Gbit reservée à cet usage!

  8. #8
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut
    Salut à tous !

    D'abord merci pour le temps que vous consacrez à mon sujet !

    En fait quel que soit la machine sur laquelle je suis, je vois les mêmes fichiers, je ne sais pas quelle technologie permet de faire ça, je travaille dans une très grande entreprise qui a une centaine de machines linux qui pointent toutes vers les mêmes fichiers.
    Le but étant que ce soit transparent pour les employés, et mon rôle est justement de vérifier lors d'un déplacement de fichier d'une machine à une autre ou simplement d'un disque a un autre, que avant et après, les fichiers sont bien identique, sauf qu'on peut pas être mit au courant avant le changement d'hardware, donc mon programme tournera périodiquement (toutes les semaines) et fera un rapport en disant tel fichier a était modifié ou supprimé etc...
    Le problème c'est qu'il y a plusieurs terras de données à traiter, et je ne peux pas savoir quels fichiers sont stockés sur quelle machine.
    Par contre c’est vrai que je dois pouvoir rendre mon appli beaucoup plus performante, mais je ne suis pas encore un Dieu en java, je sais faire, mais je ne suis pas expert, je pense m’orienté vers cette techno pour la suite de mon parcours.
    Mais c’est vrai que pour ce genre de situation où il y a au minimum 10 000 000 fichiers à parcourir, bah une petite optimisation dans le code, peut faire gagner beaucoup !
    Mais bon j’ose pas balancer un gros pâté de code comme ça et vous demander ce que vous en pensez quoi.. J’utilise le design pattern DAO/Factory, je sais pas si c’est le plus efficace en terme de performance, mais j’ai toujours utilisé ce pattern pour tous mes projets java, donc j’ai du mal à m’en détacher.

    En ce qui concerne l’élaboration du md5, je le fais pas en java, c’est mon programme qui exécute une commande linux « md5sum /exemple/exemple » et je récupère simplement le retour de la commande.
    Peut-être est-ce plus rapide de coder la fonction ? Ou d’utiliser une lib ?

    En tout cas merci encore pour votre participation !
    Alex

  9. #9
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut
    J’en profite pour dire que ce forum est vraiment super !
    J’ai longtemps hésité à m’inscrire et poser mes questions, et j’ai fini par le faire pour ce sujet, et je ne regrette vraiment pas ! Merci encore !
    Maintenant je vais bourrer le forum avec tous mes problèmes ! Mdr 
    A bientôt !

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par Sennad Voir le message
    Salut à tous !

    D'abord merci pour le temps que vous consacrez à mon sujet !

    En fait quel que soit la machine sur laquelle je suis, je vois les mêmes fichiers, je ne sais pas quelle technologie permet de faire ça, je travaille dans une très grande entreprise qui a une centaine de machines linux qui pointent toutes vers les mêmes fichiers.
    Ben tu demande aux admins, parce que connaitre cette techno est importante pour les perfs de ton programme. Là où je suis, on a aussi pas mal de dossier partagés entres des serveurs, avec du NFS, du SAN, du NAS, enfin un peu de tout.

    Mais je t'assure que si, sur un ou plusieurs serveurs, je commence à lire 200G de données NFS, j'aurais un admin furieux dans mon bureau parce que je mettrais toute la production à l'arrêt

  11. #11
    Membre éclairé Avatar de Sennad
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 180
    Points : 703
    Points
    703
    Par défaut
    Bah on me demande de faire cette application, donc il ne va pas être furax ^^
    Ce n’est pas des machine de production, seulement des ressources, des scripts d’install par exemple, ou des projets de références enfin c'est assez complexe mais je peux rien faire de plus, enfin je ne vois pas même si je sais quel techno est utilisée, ça m'avancera en quoi ?
    Puis les machines disposent d’énormément de ram et c’est en général du quad-core, mon programme ne monopolise pas les machines, enfin c’est ce que disent mes test après...
    J’utilise en moyenne 0.1% du proco et maxi 5% de la ram d’après la commande « top »

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    le problème n'est pas le proco, mais le réseau dans ce genre de cas là. En connaissant la techno, tu pourra déterminer quelle stratégie est la plus adaptée. Par exemple:

    Si les données sont locales, que chaque machine a une copie du jeu de données => Faire tourner sur chaque machine amène de meilleures performances
    Si les données sont montées par NFS, qui est vaguement similaire au système de dossier partagé de windows, chaque lecture impliquera un rappatriement depuis la sources, donc une augmentation du traffic. Dans ce cas là il est préférable, si c'est possible, de faire les calculs à la source et non pas depuis le client NFS.

    Si ton programme qui fais les signature ne sature pas la ram, ne sature pas le CPU et n'est pas un programme ineractif qui attends qu'on lui donne une fichiers, il ne reste plus qu'une chose sur laquelle il peut attendre: les IO. Et si ils sont montés dans le style nfs, attendre les IO ça veux dire, attendre le réseau, ça veux dire qu'il ne suit plus.

    JE dis tout ça car tu parle d'optimiser parce que, sinon, il faudrait des mois pour tout faire au rythme actuel => Il faut trouver le bottleneck, et avec 0.1% CPU, c'est pas le CPU le bottleneck

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Autoriser plusieurs groupes sur un même répertoire
    Par student_php dans le forum Réseau
    Réponses: 5
    Dernier message: 25/04/2012, 22h38
  2. [VB6] prob plusieur groupe OptionButton
    Par Cirdan Telemnar dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 04/07/2006, 11h20
  3. validation form en fonction de plusieurs groupe de checkbox
    Par Steph777 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/01/2006, 12h00

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