2009-04-28 7 views
5

Tengo una vista Django, que recibe parte de sus datos de un sitio web externo, que analizo usando urllib2/BeautifulSoup.Caché de Django: ¿se puede hacer de forma preventiva?

Esta operación es bastante cara, así que la guardo en caché utilizando la API de caché de bajo nivel, durante ~ 5 minutos. Sin embargo, cada usuario que accede al sitio después de que caduquen los datos en caché recibirá una demora significativa de unos segundos mientras voy al sitio externo para analizar los nuevos datos.

¿Hay alguna forma de cargar los nuevos datos perezosamente para que ningún usuario tenga ese tipo de retraso? ¿O es esto inevitable?

Tenga en cuenta que estoy en un servidor de alojamiento compartido, así que tenlo en cuenta con tus respuestas.

EDIT: gracias por la ayuda hasta ahora. Sin embargo, todavía no estoy seguro de cómo lograr esto con el script de Python que voy a llamar. Una prueba básica que hice muestra que el caché django no es global. Es decir, si lo llamo desde un script externo, no ve los datos de caché en el marco. Sugerencias?

Otro EDIT: volviendo a pensar en esto, esto es probablemente porque todavía estoy usando memoria caché local. Sospecho que si muevo el caché a Memcached, DB, lo que sea, esto será resuelto.

+0

No estoy seguro de que te refieras perezosamente en este contexto. La memoria caché casi siempre se llena de forma perezosa, es decir, solo cuando es necesario. Creo que realmente estás hablando de analizar el material de otros sitios web de forma perezosa. –

Respuesta

8

¿Desea programar algo para que se ejecute a intervalos regulares? A costa de un poco de tiempo de CPU, puede usar this simple app.

Alternativamente, si se puede usar, la cron job por cada 5 minutos es:

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

servidores de Internet ofrecen diferentes formas de establecer estas arriba. Para cPanel, use el Administrador de Cron. Para Google App Engine, use cron.yaml. Para todo esto, primero necesitará set up the environment en refresh_cache.py.

Por cierto, responder a la solicitud de un usuario se considera caché diferido. Esto es almacenamiento en caché preventivo. ¡Y no te olvides de almacenar en caché el tiempo suficiente para que la página sea recreada!

4

"Todavía estoy seguro de cómo puedo lograr esto con el script en Python, te llamaré."

La cuestión es que su "importante retraso de unos segundos, mientras que ir al sitio externo a analizar los nuevos datos "no tiene nada que ver con el caché de Django.

Puede almacenar en caché en cualquier lugar, y cuando vaya a volver a rastrear el sitio externo, hay un retraso. El truco es NO analizar el sitio externo mientras un usuario está esperando su página.

El truco es analizar el sitio externo antes de un usuario pide una página. Como no puede retroceder en el tiempo, tiene que analizar periódicamente el sitio externo y dejar los resultados analizados en un archivo local o una base de datos o algo así.

Cuando un usuario realiza una solicitud, ya tiene los resultados obtenidos y analizados, y todo lo que está haciendo es presentar.

0

También puede utilizar un script en Python para llamar a su punto de vista y escribir en un archivo, y luego entregarlo staticaly con lightpd por ejemplo:

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() 

luego llamar a la secuencia de comandos con un cron

4

I no tengo pruebas, pero he leído que BeautifulSoup es lento y consume mucha memoria. Puede utilizar el módulo lxml en su lugar. Se supone que lxml es mucho más rápido y eficiente, y puede hacer mucho más que BeautifulSoup.

Por supuesto, el análisis probablemente no sea su cuello de botella aquí; la E/S externa es

Primero, usa memcached!

Entonces, una estrategia que se puede utilizar es el siguiente:

  • Su objeto en caché, llamada A, se almacena en la memoria caché con una clave dinámica (A_<timestamp>, por ejemplo).
  • Otro objeto en caché contiene la clave actual para A, llamada A_key.
  • Su aplicación sería entonces obtener la clave para A por conseguir primero el valor en A_key
  • un proceso periódico que poblar la memoria caché con las teclas A_<timestamp> y al terminar, cambiar el valor en el A_key a la nueva clave

Con este método, todos los usuarios cada 5 minutos no tendrán que esperar a que se actualice la caché, sino que obtendrán versiones anteriores hasta que se realice la actualización.

Cuestiones relacionadas