2012-09-14 15 views
6

Ho un'app web python che utilizza lo pylibmc module per connettersi a un server memcached. Se provo la mia app con richieste una volta al secondo o più lente, tutto funziona correttamente. Se invio di più di una richiesta per secondo, invece, i miei applicazione si blocca e vedo quanto segue nei miei ceppi:pylibmc: 'Assertion' ptr-> query_id == query_id +1 "failed for function" memcached_get_by_key "'

Assertion "ptr-> query_id == query_id +1" fallito per la funzione "memcached_get_by_key" probabile per "Errore del programmatore, query_id non è stato incrementato.", In libmemcached/get.cc: 107

Asserzione "ptr-> query_id == query_id +1" non riuscita per la funzione "memcached_get_by_key" probabile per "Errore del programmatore, query_id non è stato incrementato. ", a libmemcached/get.cc: 89

Qualche idea di cosa non funziona o come risolverlo?

Il mio codice è simile al seguente:

self.mc = pylibmc.Client(
    servers=[os.environ.get(MEMCACHE_SERVER_VAR)], 
    username=os.environ.get(MEMCACHE_USER_VAR), 
    password=os.environ.get(MEMCACHE_PASS_VAR), 
    binary=True 
    ) 

#... 

if (self.mc != None): 
    self.mc.set(key, stored_data) 

#... 

page = self.mc.get(key) 
+0

Perché hai immediatamente postato una risposta alla tua stessa domanda? – grc

+0

@grc Perché ho risolto il problema? AFAIK [è incoraggiata la risposta alla tua domanda] (http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/). Stai dicendo che non dovrei? Sono aperto ad altri suggerimenti se altre persone li hanno, ma la mia risposta ha risolto il mio problema. Quando inizialmente ho cercato le risposte a questo problema, non ne ho trovato nessuno, quindi spero che la pubblicazione qui aiuti gli altri che vi si imbattono. – culix

risposta

4

Si tratta di un problema di threading. pylibmc clients are not thread-safe. Dovresti convertire il tuo codice per usare uno ThreadMappedPool object per assicurarti di mantenere una connessione separata per ogni thread. Qualcosa di simile a questo:

mc = pylibmc.Client(
    servers=[os.environ.get(MEMCACHE_SERVER_VAR)], 
    username=os.environ.get(MEMCACHE_USER_VAR), 
    password=os.environ.get(MEMCACHE_PASS_VAR), 
    binary=True 
    ) 
self.pool = pylibmc.ThreadMappedPool(mc) 

#... 

if (self.pool != None): 
    with self.pool.reserve() as mc: 
     mc.set(key, stored_data) 

#... 

if (self.pool != None): 
    with self.pool.reserve() as mc: 
     page = mc.get(key) 

Assicurati di chiamare self.pool.relinquish() quando il filo è finito, forse nel distruttore!

(Nel mio caso questo è accaduto perché stavo usando cherrypy come il mio server web, e cherrypy genera 10 thread separati per servire le richieste di default.)

1

Ho incontrato lo stesso problema in esecuzione Django su Apache. Passare da pylibmc a python-memcached ha eliminato il problema per me.

+0

Inoltre, consultare il back-end django_elasticache.memcached.ElastiCache. Usa pylibmc, ma lo chiama in modo tale da farlo funzionare bene con GIL e non si blocca. – Cerin