2013-03-16 49 views
3

简单问题:Django的缓存:使用Memcached和退回到文件系统

我的服务器有1G的RAM和10GB的磁盘空间

我使用per-site cache,我想用尽可能Memcached,但是当它的空间不足时,那个cache will be saved in hard disk

(所有网站的页面一起约2GB)

有一个简单的配置来实现这一目标?

这是一件聪明的事情吗?

感谢

+0

的一种方式(不知道最简单的)是写[自定义后端(https://docs.djangoproject.com/en/dev/topics/cache/#using-a-custom-cache-后端),如果memcached无法再存储,则切换到文件系统缓存。看看django [内置后端](https://github.com/django/django/tree/master/django/core/cache/backends)。 – alecxe 2013-03-19 08:04:22

+0

@AlexanderAfanasiev我知道这是方向,我的问题是关于实现它的最佳实践 – YardenST 2013-03-19 09:27:08

回答

7

这听起来像你想的Memcached的行为像正常的RAM和页面到磁盘时是满。它不是默认的,但你可以通过编写你自己的缓存后端来模拟它,就像@AlexanderAfanasiev所说的那样。该实施将沿着这些路线的东西:

首先,定义三个缓存:

CACHES = { 
    'default': { 
     'BACKEND': 'myapp.cache.DoubleCache', 
    }, 
    'memcached': { 
     'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 
     'LOCATION': '127.0.0.1:11211', 
    }, 
    'filecache': { 
     'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 
     'LOCATION': '/foo/bar', 
    } 
} 

然后,在MYAPP/cache.py:

from django.core.cache.backends.base import BaseCache 
from django.core.cache import get_cache, cache 
mem_cache = get_cache('memcached') 
file_cache = get_cache('filecache') 

class DoubleCache(BaseCache): 

    def get(self, key, default=None, version=None): 
     result = mem_cache.get(key, default=default, version=version) 
     if result: 
      return result 
     else: 
      return file_cache.get(key, default=default, version=version) 

    def set(self, key, value, timeout=None, version=None, client=None, _add_only=False): 
     memcache_result = mem_cache.set(key, value, timeout=timeout, version=version, client=client, _add_only=_add_only) 
     file_result = file_cache.set(key, value, timeout=timeout, version=version, client=client, _add_only=_add_only) 
     return memcache_result 

这将始终存储值在两个高速缓存。它将从Memcached中检索值,如果它未命中,将尝试file_cache。这意味着Memcached可以管理自己的滚降,只有最老的命中才会回退到file_cache。这是你想要的。

当然,你还必须实现其余的缓存功能,如delete(),get_many()等。希望这可以让你走上正确的道路。

+0

Tnx的详细答案,但是set()方法会不会始终成功地将值存储在memcahed中?它只会删除一个较旧的值并存储新的值,导致get方法永远不会到达file_cache。如我错了请纠正我。 – YardenST 2013-03-20 07:24:15

+0

是的,set()将存储在两者中。但是,如果memcached填满(这将发生在1GB ram和2GB数据集中),那么一半的值将在两个半中只会在file_cache中。由于memcached在填充时丢弃次数最少,所以file_cache中的一半将是最少使用的页面。那就是你想要的。如果你尝试去做一个很少使用的页面,它会错过memcached get,然后返回file_cache。 – krimkus 2013-03-20 15:45:15

+0

我现在明白了,稍后我会试一下,看它是否按预期工作 – YardenST 2013-03-20 15:56:59

0

利用TCP/IP。通过较小的努力,这个逻辑可以扩展为创建具有后备功能的完美多重缓冲后端。

import socket 
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

try: 
    socket.connect(('127.0.0.1', 11211)) 
    socket.close() 

    CACHES = { 
     'default': { 
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 
      'LOCATION': '127.0.0.1:11211', 
     } 
    } 
except: 
    CACHES = { 
     'default': { 
      'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 
      'LOCATION': '/srv/django_cache', 
     } 
    }