Autre idée : N dédoublonneurs en parallèle. Tu envoies ton message M dans
la file p=Hash(M) mod N. Et tu es sûr que tous les doublons de M seront
dans la même file. Du coup, plus de lock.
Me gourre-je ?
> Question :: Est-ce une catastrophe si un message est traité en double de
> temps à autre où pas ?
> Si ton objectif est simplement d'économiser du temps de calcul, tu peux ne
> locker qu'en écriture (ou au besoin utiliser un ReaderWriterSlimLock).
> Certains messages seront traités en double, mais bon, c'est pas la mort.
> Si en revanche traiter deux fois le même message relève de la catastrophe
> nucléaire, il va falloir ruser un peu plus. Il existe un truc plus rapide
> que le hashset pour déterminer les doublons*. Je ne retrouve plus le nom,
> mais en gros c'est un champ de bits dans lequel on insère des infos. C'est
> destructeur (cad que tu ne peux retrouver un truc inséré)) mais ça permet
> de tester l'existence avec un simple ou binaire. J'essaie de te retrouver
> le nom du truc, sauf si quelqu'un le connait de tête.
> * du moins sur un hashset qui évolue, vu que sur un hashset fixe, ta
> complexité tend vers O(1)
> Mick
> Le 9 août 2012 22:45, mathias kluba <mathias.kl...@gmail.com> a écrit :
> Arf, non, car la traitement A génère le messages à partir d'un fichier
>> texte, et génère l'ID aussi.
>> Même si je colle la Hashmap dans ce thread, ça ira pas plus vite.
>> L'intérêt c'est que je puisse avoir plusieurs threads pour le traitement
>> A, pour traiter encore plus de fichiers (ce qui ne sert à rien pour
>> l'instant car ça bloque au dédoublonnage)
>> 2012/8/9 Mathieu Despriee <mdespr...@octo.com>
>>> Peut-être qu'il y a un truc que je pige pas, mais : je suppose que si le
>>> traitement A est rapide, il n'est que sur une thread. Est-ce que ça peut
>>> pas être lui qui a la hashmap et qui dedoublonne ?
>>> Le 9 août 2012 à 22:14, mathias kluba <mathias.kl...@gmail.com> a
>>> écrit :
>>> Tout d'abord, j'ai plusieurs queues.
>>> Donc je décolère déjà traitement et "détection des doublons".
>>> Avant je n'avais pas de problème car les traitements prenaient pas mal
>>> de CPU.
>>> Mais quand je suis passé en prod avec un serveur de ouf, les traitements
>>> vont trop vite et tout bloque sur la détection des doublons.
>>> message => queue 1 => traitements A => queue 2 => détection des
>>> doublons => queue 3 => traitements B
>>> le problème c'est que le "traitements A" va tellement vite, que la queue
>>> 2 est pleine (capé sinon ça explose en mémoire).
>>> et la queue3 est vide, car la "détection des doublons" va pas assez vite
>>> pour dépiler la queue 2, et pas assez vite pour remplir la queue 3.
>>> Concernant le lock au niveau du message: mes threads ne peuvent pas
>>> dépiler le même message (blockingQueue).
>>> J'ai des doublons au niveau de la source des messages.
>>> désolé de ne pas avoir été assez détaillé dans mon premier message,
>>> j'étais sur iPhone dans le metro :p
>>> PS: je sais que ma solution de "blocking queue" n'est pas idéal: je
>>> pourrais déjà utiliser TPL Dataflow, voir même le Disruptor.
>>> Le jeudi 9 août 2012 21:42:16 UTC+2, Mick Philippon a écrit :
>>>> Ou alors tu fais porter l'info de traitement au message. En gros tu
>>>> ajoutes à ton message deux booleens (volatiles) et une date : en cours de
>>>> traitement, traité, date de début de traitement (et un object de synchro)
>>>> Tu as une queue avec tous les messages qui ne sont pas en cours de
>>>> traitement et une avec les messages en cours de traitement (important pour
>>>> la reprise sur erreur)
>>>> Ton début de traitement d'un message revient à faire
>>>> var msg = queue.take(); // au pire tu as deux ou trois threads qui
>>>> prennent le même message
>>>> lock(msg.__sync) // J'appelle toujours mes objets de synchro __sync,
>>>> mais tu n'es pas obligé de faire pareil
>>>> {
>>>> if(!msg.Processing && !msg.Processed)
>>>> {
>>>> msg.Processing = true;
>>>> msg.StartProcessingDate = DateTime.Now; // à voir si la précision
>>>> est suffisante
>>>> processingQueue.Put(msg);
>>>> process (msg);
>>>> }
>>>> }
>>>> Quand ta queue de départ est vide, tu vas chercher dans la
>>>> processingQueue les message qui ne sont pas déjà traités et dont la date de
>>>> début est antérieure à x minutes, histoire de pallier aux défaillance de
>>>> tes consumers.
>>>> Avantage : tu lockes au niveau du message seulement, donc dans le pire
>>>> des cas tu vas bloquer deux ou trois thread (ceux qui ont fait le take en
>>>> même temps du même message)
>>>> Mick, distribué.
>>>> Le 9 août 2012 21:35, Mathieu Despriee <mdes...@octo.com> a écrit :
>>>>> Salut Mathias,
>>>>> Idée : decorreler dédoublonnage et traitement.
>>>>> Une thread de dedoublonnage (qui fait que ça) et qui remet le résultat
>>>>> dans une autre Q pour les consumers.
>>>>> Make sense ?
>>>>> Mathieu
>>>>> Le 9 août 2012 à 20:46, Mathias Kluba <mathia...@gmail.com> a écrit :
>>>>> > Hello,
>>>>> > J'ai une petite question concernant la gestion de la concurrence.
>>>>> > J'ai un programme avec des threads "producer" et "consumer".
>>>>> > Je me sert d'une "blockingqueue" pour comminiquer.
>>>>> > au départ, j'arrivais à ajuster le nombre de producer/consumers pour
>>>>> que le consumer dépile la queue assez vite.
>>>>> > mais maintenant que je suis en prod, je suis sur un serveur mega
>>>>> puissant (avec beaucoup de core).
>>>>> > même si j'ai un seul thread producer, et le reste des cores pour le
>>>>> consumer, ils n'arrivent pas à dépiler.
>>>>> > le problème vient du fait qu'a un moment, le consumer doit voir s'il
>>>>> n'a pas traité un message (doublons).
>>>>> > pour ça, je fait un truc moche qui bloque tous les threads: un lock
>>>>> sur un HashSet.
>>>>> > j'essaye d'ajouter l'id du message dans le HashSet, si ça renvoit
>>>>> "true" c'est qu'il
>>>>> > n'existait pas déjà, false dans le cas contraire.
>>>>> > du coup, tous les threads bloquent pour vérifier si l'item n'est pas
>>>>> déjà dans la hashset...
>>>>> > avez vous des idées pour eviter ce lock?
>>>>> > une idée que j'ai c'est de "router" les messages dans des blocking
>>>>> queue différentes (1 par thread consumer) le routing se fait à l'aide d'un
>>>>> hash sur l'id du message. et chaque thread possède sa Hashset d'id déjà
>>>>> traité...
>>>>> > je garantie ansi que les doublons vont dans la même queue, que
>>>>> l'unicité est donc garantie, mais je répartie les locks par thread...
>>>>> > qui dit mieux?
>>>>> > --
>>>>> > Mathias Kluba
>>>>> > Twitter: @mathiaskluba
>>>>> > Blog: http://grozeille.com