2009-04-28 9 views
5

Ho una vista Django, che riceve parte dei suoi dati da un sito web esterno, che analizzo usando urllib2/BeautifulSoup.Il caching di Django - può essere fatto in modo preventivo?

Questa operazione è piuttosto costoso quindi ho Cache utilizzando la cache API di basso livello, per ~ 5 minuti. Tuttavia, ogni utente che accede al sito dopo la scadenza dei dati nella cache riceverà un ritardo significativo di alcuni secondi mentre si visita il sito esterno per analizzare i nuovi dati.

C'è un modo per caricare i nuovi dati pigramente in modo che nessun utente possa mai ottenere quel tipo di ritardo? O è inevitabile?

Si prega di notare che io sono su un server di hosting condiviso, in modo da tenere a mente con le vostre risposte.

MODIFICA: grazie per l'aiuto finora. Tuttavia, non sono ancora sicuro di come ottengo ciò con lo script Python che chiamerò. Un test di base che ho fatto mostra che la cache di django non è globale. Significato se lo chiamo da uno script esterno, non vede i dati della cache in corso nel framework. Suggerimenti?

Un altro EDIT: che viene a pensarci, questo è probabilmente perché sto ancora utilizzando la cache di memoria locale. Ho il sospetto che se sposto la cache in memcached, DB, qualunque cosa, questo sarà risolto.

+0

Non sono sicuro che intendi pigramente in questo contesto. La cache viene quasi sempre riempita pigramente - cioè, solo quando necessario. Penso che tu stia davvero parlando di analizzare il materiale da altri siti pigramente. –

risposta

8

Quindi si desidera pianificare qualcosa da eseguire a intervalli regolari? Al costo di un po 'di tempo della CPU, è possibile utilizzare this simple app.

In alternativa, se si può usare, il cron job per ogni 5 minuti è:

*/5 * * * * /path/to/project/refresh_cache.py 

host Web forniscono diversi modi per configurare questi. Per cPanel, utilizzare il Cron Manager. Per Google App Engine, utilizza cron.yaml. Per tutti questi, è necessario prima di set up the environment in refresh_cache.py.

A proposito, rispondere alla richiesta di un utente viene considerato come cache nascosta. Questa è la cache preventiva. E non dimenticare di mettere in cache abbastanza a lungo per ricreare la pagina!

4

"Sono ancora sicuri di come compio questo con lo script python sarò chiamando."

Il problema è che il "ritardo significativo di pochi secondi, mentre io andare al sito esterno a analizzare i nuovi dati "non ha nulla a che fare con il cache di Django.

È possibile memorizzarlo ovunque e quando si esegue il repar, il sito esterno, c'è un ritardo. Il trucco è NON analizzare il sito esterno mentre un utente è in attesa della sua pagina.

Il trucco è analizzare il sito esterno prima di un utente richiede una pagina. Poiché non è possibile tornare indietro nel tempo, è necessario analizzare periodicamente il sito esterno e lasciare i risultati analizzati in un file locale o in un database o qualcosa del genere.

Quando un utente effettua una richiesta di avere già i risultati recuperati e analizzati, e tutto quello che stai facendo sta presentando.

0

È inoltre possibile utilizzare uno script python per chiamare la visualizzazione e scrivere in un file, quindi consegnarlo staticaly con lightpd ad esempio:

request = HttpRequest() 
request.path = url # the url of your view 
(detail_func, foo, params) = resolve(url) 
params['gmap_key'] = settings.GMAP_KEY_STATIC 
detail = detail_func(request, **params) 
out = open(dir + "index.html", 'w') 
out.write(detail.content) 
out.close() 

quindi chiamare lo script con un cron

4

I non ho prove, ma ho letto che BeautifulSoup è lento e consuma molta memoria. Potresti voler usare invece il modulo lxml. lxml dovrebbe essere molto più veloce ed efficiente e può fare molto più di BeautifulSoup.

Ovviamente, l'analisi non è probabilmente il collo di bottiglia qui; l'I/O esterno è.

Prima di tutto, utilizzare memcached!

Poi, una strategia che può essere utilizzato è il seguente:

  • vostro oggetto in cache, chiamato A, viene memorizzata nella cache con una chiave dinamica (A_<timestamp>, per esempio).
  • Un altro oggetto memorizzato nella cache contiene la chiave corrente per A, denominata A_key.
  • La vostra applicazione dovrebbe quindi ottenere la chiave per A attraverso il collegamento il valore al A_key
  • Un processo periodico avrebbero popolato la cache con i tasti A_<timestamp> e al termine, modificare il valore al A_key alla nuova chiave

Utilizzando questo metodo, tutti gli utenti ogni 5 minuti non dovranno attendere l'aggiornamento della cache, ma avranno solo versioni precedenti fino a quando non si verifica l'aggiornamento.

Problemi correlati