2016-12-07 3 views
0

Je travaille actuellement sur l'informatique distribuée. Mes travailleurs retourne ses résultats en l'insérant dans une base de données mongoDB.Le code fonctionne bien, mais la connexion reste ouverte et à un moment mon système est à court de sockets. Voici mon code de travail:Comment puis-je forcer Pymongo à fermer des sockets?

def worker(elt): 
    client=pymongo.MongoClient(MONGODB_URI) 
    db = client.get_default_database() 
    essaiElt = db['essaiElt'] 
    #compute here 
    essaiElt.insert(elt.toDict()) 
    client.close() 

En utilisant cette commande « -anbo netstat » Je peux voir toutes les prises de courant encore ouvert (plus de 3000), le nombre maximum de travailleurs est de 14, mais ils doivent faire face à plus que 10 000 tâches.

... 
TCP 10.130.151.11:4999 10.130.137.128:27017 En attente 0 
TCP 10.130.151.11:5000 10.130.137.128:27017 En attente 0 

J'ai essayé de définir des délais mais cela n'a aucun effet.

Comment puis-je fermer des sockets sans redémarrer ma base de données?

Python 2.7.12 Pymongo 3.3 MongoDB 3.2.10

+0

Combien de temps faut-il pour exécuter la section "Calculer ici"? Est-ce qu'un seul processus Python insère plusieurs documents dans la base de données, ou un seul, avant que le processus ne se termine? –

+0

Combien de temps faut-il pour exécuter la section "Calculer ici"? En fait, il est vide. Est-ce qu'un seul processus Python insère plusieurs documents dans la base de données, ou un seul, avant que le processus ne se termine? Le worker est géré par la bibliothèque pp (python parallèle) Il obtient donc une tâche, crée un socket, insère l'élément, ferme le socket et récupère une autre tâche pour faire la même chose. Donc, un travailleur peut éventuellement créer beaucoup de socket. –

Répondre

0

ce qui se passe probablement est, vous créez un client, insérez un document, et fermez le client, plusieurs fois par seconde. Un MongoClient peut prendre une seconde ou deux pour terminer son processus d'arrêt. (Un MongoClient démarre un thread d'arrière-plan par serveur et ces threads ne se terminent pas instantanément.) Même une fois que le MongoClient a complètement fermé ses sockets, le serveur MongoDB prend quelques secondes pour nettoyer toutes les ressources liées à la connexion TCP et le réseau du système d'exploitation couche prend quelques minutes pour nettoyer. (Voir l'état TIME-WAIT Wikipedia's TCP entry.)

En général, vous devez créer un MongoClient au début de votre processus de Python, et utiliser une MongoClient tout au long de cette vie de processus Python:

client = pymongo.MongoClient(MONGODB_URI) 

def worker(elt):  
    db = client.get_default_database() 
    essaiElt = db['essaiElt'] 
    #compute here 
    essaiElt.insert(elt.toDict()) 

Don » t créer un nouveau MongoClient par opération. Ne le ferme jamais.

Voir aussi the PyMongo FAQ:

Créer ce client une fois pour chaque processus, et le réutiliser pour toutes les opérations. C'est une erreur courante de créer un nouveau client pour chaque requête, ce qui est très inefficace.

+0

"Ne jamais le fermer." - Quand est-il fermé? –

+1

Il est fermé automatiquement lorsque votre processus Python se termine. Il n'y a aucune raison de fermer un MongoClient avant cela. –

+0

C'est une information précieuse! Êtes-vous en train de dire que les développeurs de 'pymongo' exposent la méthode' .close' avec minutie, ou ne sont "jamais" une exagération et ont des cas d'utilisation légitimes? –