2012-12-04 3 views
0

Salut J'essaie d'envoyer de gros paquets avec ZeroMQ en utilisant le modèle ventilateur/travailleur/évier.Fuite de mémoire Zeromq (pyzmq)

J'essaie d'ajouter des travailleurs. À chaque fois, l'utilisation de la mémoire du processus récepteur augmente un peu. Ensuite, il atteint un point de basculement à environ 6 ou 7 travailleurs où soudain la mémoire augmente de façon exponentielle jusqu'à ce qu'il meurt avec:

> *** error: can't allocate region 
> *** set a breakpoint in malloc_error_break to debug Assertion failed: (msg_->flags | ZMQ_MSG_MASK) == 0xff (zmq.cpp:211) 
> Python(42410,0xaccb8a28) malloc: *** mmap(size=3559424) failed (error 
> code=12) 

Voici le code (ne montrant que le travailleur/motif de puits):

import sys 
import resource 
import zmq 
import time 

context = zmq.Context() 


if sys.argv[1] == 'worker': 
    # Socket to send messages to 

    sender = context.socket(zmq.PUSH) 
    sender.connect("tcp://localhost:5558") 

    while True: 
     msg = 'x' * 3559333 
     time.sleep(.01) 
     sender.send(msg) 
else: 
    # Socket to receive messages on 

    receiver = context.socket(zmq.PULL) 
    receiver.bind("tcp://*:5558") 
    while True: 
     msg = receiver.recv() 

     print msg[0:5], len(msg), resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 

Est-ce simplement un manque de ressources matérielles? Un arriéré de données? Ou y a-t-il un moyen d'éviter cela? Je suis sous OSX Mountain Lion avec 16 Go de mémoire et Python 2.7 avec zmq 2.2.0.1.

Merci

Répondre

2

Est-ce simplement un manque de ressources matérielles?

Eh bien, faisons le calcul. Chaque travailleur envoie 3,3 Mo toutes les 10ms. Ou environ 300mb une seconde. Maintenant, vous ajoutez plus de travailleurs. Au moment où vous êtes jusqu'à 5 travailleurs, vous envoyez environ 1,5 Go par seconde.

Je pense que vous avez trouvé la limite de performance pour votre machine. Lorsque le processus de collecte est exécuté sur la même machine que tous les travailleurs, il est capable de consommer entre 1 et 2 Go par seconde. Lorsque les données arrivent plus vite que la file d'attente est accumulée dans le processus de puits plus rapidement que vous pouvez les vider et vous manquez de mémoire.

Ou y a-t-il un moyen d'éviter cela?

Envoyer des petits messages? Moins fréquemment? :) Ou mettre les travailleurs et le processus d'évier sur des machines différentes. Rappelez-vous que les travailleurs volent des ressources de l'unité centrale de l'évier. S'il s'agit d'une machine à quatre cœurs, avec l'évier et jusqu'à trois travailleurs, le système d'exploitation alloue probablement la quasi-totalité d'un cœur de processeur à chaque processus. Une fois que vous ajoutez le 4ème, 5ème, 6ème, le système d'exploitation ne peut pas donner 100% d'un noyau à n'importe quel processus. Ils doivent commencer à partager, donc l'évier ralentit même lorsque le taux de messages s'accélère. Cela expliquerait le point de bascule que vous voyez où l'utilisation de la mémoire augmente de façon exponentielle.

Hmmm - ce qui suggère une expérience intéressante. Pouvez-vous configurer votre mac pour que le processus de l'évier soit très prioritaire? Cela pourrait donner de meilleurs résultats. Je n'ai jamais essayé moi-même, mais voir le lien suivant pour des idées ... https://discussions.apple.com/thread/1491812?start=0&tstart=0

+0

Merci pour votre inscription. J'ai essayé de nier et cela n'a pas aidé mais ouais ça doit être un manque de réseau. Je pourrais couler dans une boîte séparée, comme vous dites. Je peux même avoir plusieurs lavabos si nécessaire. – user1556658

+0

Cela suggère cependant que je ferais mieux de ne pas étaler cela sur plusieurs cases. Le temps de calcul est trop petit par rapport aux limites de transfert réseau. Je ferais mieux d'avoir juste une de ces 20 boîtes d'unités de calcul sur ec2 et de tout faire là-bas. Je me demande combien de fois cela arrive, dans un monde où le hadoop est vendu comme la solution à toutes ces tâches. – user1556658

+0

C'est bien sûr plus que ce qui précède, mais pas beaucoup plus qu'une séparation sur un texte délimité par des tabulations et un peu de comptage et de filtrage. – user1556658