2012-03-21 10 views
5

Ho bisogno di qualcosa come un archivio di valori-chiave temporaneo in-memory. So che ci sono soluzioni come Redis. Ma mi chiedo se l'utilizzo di un dizionario Python potrebbe funzionare? E potenzialmente essere ancora più veloce? Quindi pensa a un server Tornado (o simile) in esecuzione e in possesso di un dizionario python in memoria e basta restituire il valore appropriato in base alla richiesta HTTP.Utilizzo del dizionario Python come database temporaneo in memoria con valori-chiave?

Perché ho bisogno di questo? Come parte di un servizio ci sono valori chiave in fase di memorizzazione, ma hanno questa proprietà: più recenti sono, più è probabile che si acceda. Quindi voglio continuare a dire gli ultimi 100 valori chiave in memoria (così come scrivere su disco) per un recupero più veloce.

Se il server muore, è possibile ripristinare nuovamente il dizionario dal disco.

Qualcuno ha fatto qualcosa del genere? Mi manca qualcosa qui?

PS: Penso che non sia possibile con un server WSGI, giusto? Perché per quanto ne so non puoi tenere qualcosa in memoria tra le singole richieste.

risposta

4

Lavorerei sicuramente con memcached. Una volta che è stata messa a punto si può facilmente decorare le vostre funzioni/metodi come è fatto nel mio esempio:

#!/usr/bin/env python 

import time 
import memcache 
import hashlib 

def memoize(f): 

    def newfn(*args, **kwargs): 
     mc = memcache.Client(['127.0.0.1:11211'], debug=0) 
     # generate md5 out of args and function 
     m = hashlib.md5() 
     margs = [x.__repr__() for x in args] 
     mkwargs = [x.__repr__() for x in kwargs.values()] 
     map(m.update, margs + mkwargs) 
     m.update(f.__name__) 
     m.update(f.__class__.__name__) 
     key = m.hexdigest() 

     value = mc.get(key) 
     if value: 
      return value 
     else: 
      value = f(*args, **kwargs) 
      mc.set(key, value, 60) 
      return value 
     return f(*args) 

    return newfn 

@memoize 
def expensive_function(x): 
    time.sleep(5) 
    return x 

if __name__ == '__main__': 
    print expensive_function('abc') 
    print expensive_function('abc') 

non si cura di latenza della rete da quel tipo di ottimizzazione sarà uno spreco di vostro tempo.

0

Se si associa il dizionario allo stesso server che esegue il servizio effettivo, allora sì, funzionerebbe correttamente.


Se si sta creando cose separate, beh, questo è fondamentalmente ciò che è per memcached. Don't reinvent the wheel.

0

È possibile ed è molto più veloce di redis/memcache a causa della mancanza di latenza di rete. Puoi usare cPickle per scaricare il dizionario ogni tanto. È complicato se il tuo programma genera processi secondari, quindi l'aggiornamento dei valori in un processo non influisce sull'altro.

+0

Dato che l'OP si riferisce a un server Tornado che interroga le richieste al dict ... ci sarà ancora latenza di rete. – Amber

+0

@amber ma non per memcache/redis. –

+0

Ciò che l'OP sembra suggerire è * reimplementare * memcache/redis tramite tornado. – Amber

0
  1. Si potrebbe semplicemente cache Ultimo dati in dict, nessuno vieta su di esso e funziona in ambiente con un server
  2. Quando i nuovi dati aggiunti - conservarlo ad alcuni Redis (memcachedb)
  3. Al riavvio del server - basta caricare i nuovi record N sul dizionario

Tutto dipende dal volume di dati. Credo ci voglia più memoria per mantenere strutture complesse nel dizionario in python, l'accesso pensato sarà veloce - sì

2

Un dizionario Python in corso è modo più veloce di un server memcached. Secondo un benchmark non rigoroso che ho eseguito alcuni giorni fa, un singolo get prende circa 2us usando un dizionario in python in process e circa 50us usando un server memcached in ascolto su localhost. Nel mio benchmark, stavo usando libmemcached come client C e python-libmemcached come python wrapper su questo C-client.

1

Sto sperimentando qualcosa di simile e la libreria Corecache è un ottimo modo per testare alcuni sistemi di memorizzazione nella cache. https://pypi.python.org/pypi/cachecore

In particolare, la loro attuazione SimpleCache si basa su un pitone dict vaniglia, e nei miei test preliminari è estremamente veloce, 10 volte più veloce di chiamare memcached localmente (supponendo che io sono già nella domanda di pitone che ha bisogno di caching, probabilmente la servizio di tornado nel tuo caso).

Problemi correlati