2015-03-23 9 views
5

Ich habe eine MongoDB Sammlung mit> 1.000.000 Dokumente. Ich führe eine erste .find({ my_query }), um eine Teilmenge dieser Dokumente (~ 25.000 Dokumente) zurück, die ich dann in ein list Objekt.PyMongo wirft [errno 49] kann die angeforderte Adresse nach einer großen Anzahl von Abfragen nicht zuweisen

Ich bin dann über jedes der Objekte Looping, einige Werte aus dem zurückgegebenen Dokument in der Liste Parsen und Ausführen einer zusätzlichen Abfrage diese analysiert Werte über den Code verwendet:

def _perform_queries(query): 
    conn = pymongo.MongoClient('mongodb://localhost:27017') 
    try: 
     coll = conn.databases['race_results'] 
     races = coll.find(query).sort("date", -1) 
    except BaseException, err: 
     print('An error occured in runner query: %s\n' % err) 
    finally: 
     conn.close() 
     return races 

In diesem Fall meine query Wörterbuch ist:

{"$and": [{"opponents": 
    {"$elemMatch": {"$and": [ 
     {"runner.name": name}, 
     {"runner.jockey": jockey} 
    ]}}}, 
    {"summary.dist": "1"} 
]} 

Hier mein Problem ist. Ich habe einen Index auf opponents.runner.name und opponents.runner.jockey erstellt. Dies macht die Abfragen wirklich sehr schnell. Doch nach etwa 10.000 Anfragen in einer Reihe, pymongo eine Ausnahme erzieht:

pymongo.errors.AutoReconnect: [Errno 49] Can't assign requested address 

Wenn ich den Index zu entfernen, habe ich nicht diesen Fehler sehen. Aber es dauert etwa 0.5 seconds pro Abfrage, die in meinem Fall unbrauchbar ist.

Weiß jemand, warum die [Errno 49] can't assign requested address auftreten könnte? Ich habe ein paar andere SO Fragen im Zusammenhang mit can't assign requested address, aber nicht in Bezug auf pymongo gesehen und dort Antworten führen mich nirgends.

UPDATE:

unter Serge Rat folgend, hier ist die Ausgabe von ulimit -a:

core file size   (blocks, -c) unlimited 
data seg size   (kbytes, -d) unlimited 
file size    (blocks, -f) unlimited 
max locked memory  (kbytes, -l) unlimited 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 2560 
pipe size   (512 bytes, -p) 1 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 709 
virtual memory   (kbytes, -v) unlimited 

Mein MongoDB auf OS X Yosemite läuft.

Antwort

12

Dies liegt daran, dass Sie PyMongo falsch verwenden. Sie erstellen für jede Abfrage einen neuen MongoClient, bei dem Sie für jede neue Abfrage einen neuen Socket öffnen müssen. Dies verhindert das Verbindungs-Pooling von PyMongo und ist außerdem extrem langsam. Es bedeutet auch, dass Sie Sockets schneller öffnen und schließen als Ihr TCP-Stack mithalten kann: Sie belassen zu viele Sockets im TIME_WAIT-Zustand, sodass Ihnen die Ports ausgehen.

Zum Glück ist die Lösung einfach. Erstellen Sie einen MongoClient und verwenden Sie ihn durchgängig:

conn = pymongo.MongoClient('mongodb://localhost:27017') 
coll = conn.databases['race_results'] 

def _perform_queries(query): 
    return coll.find(query).sort("date", -1) 
+2

Ah ja! Dies macht jetzt mehr Sinn. Ich lerne jeden Tag mehr und mehr über MongoDB. Vielen Dank! Antwort angenommen! – Brett

Verwandte Themen