2015-03-23 8 views
5

Ho una collezione MongoDB con> 1.000.000 di documenti. Sto eseguendo un iniziale .find({ my_query }) per restituire un sottoinsieme di quei documenti (~ 25.000 documenti), che poi inserisco in un oggetto list.PyMongo solleva [errno 49] non può assegnare l'indirizzo richiesto dopo un gran numero di domande

sto poi loop su ciascuno degli oggetti, l'analisi di alcuni valori dal documento restituito nella lista, e l'esecuzione di una query aggiuntiva usando quei valori analizzati tramite il codice:

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 questo caso, il mio query dizionario è:

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

Qui è il mio problema. Ho creato un indice su opponents.runner.name e opponents.runner.jockey. Questo rende le query davvero molto veloci. Tuttavia, dopo circa 10.000 domande di fila, pymongo sta sollevando un'eccezione:

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

Quando ho rimuovere l'indice, non vedo questo errore. Ma ci vuole circa 0.5 seconds per query, che è inutilizzabile nel mio caso.

Qualcuno sa perché potrebbe verificarsi [Errno 49] can't assign requested address? Ho visto alcune altre domande SO relative a can't assign requested address ma non in relazione a pymongo e le risposte non mi portano da nessuna parte.

UPDATE:

Seguendo il consiglio di Serge di seguito, ecco l'output del 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 

mio MongoDB è in esecuzione su OS X Yosemite.

risposta

12

Questo perché si sta usando PyMongo in modo errato. Stai creando un nuovo MongoClient per ogni query, che richiede l'apertura di un nuovo socket per ogni nuova query. Ciò sconfigge il pool di connessioni PyMongo e, oltre ad essere estremamente lento, significa anche aprire e chiudere i socket più velocemente di quanto lo stack TCP possa mantenere: si lasciano troppi socket nello stato TIME_WAIT in modo che alla fine si esauriscano le porte.

Fortunatamente, la soluzione è semplice. Crea un MongoClient e usalo in tutto:

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

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

Ah sì! Questo ha più senso ora. Sto imparando sempre di più su MongoDB ogni giorno. Grazie! Risposta accettata! – Brett

Problemi correlati