简单问题:Django的缓存:使用Memcached和退回到文件系统
我的服务器有1G的RAM和10GB的磁盘空间
我使用per-site cache,我想用尽可能Memcached,但是当它的空间不足时,那个cache will be saved in hard disk。
(所有网站的页面一起约2GB)
有一个简单的配置来实现这一目标?
这是一件聪明的事情吗?
感谢
简单问题:Django的缓存:使用Memcached和退回到文件系统
我的服务器有1G的RAM和10GB的磁盘空间
我使用per-site cache,我想用尽可能Memcached,但是当它的空间不足时,那个cache will be saved in hard disk。
(所有网站的页面一起约2GB)
有一个简单的配置来实现这一目标?
这是一件聪明的事情吗?
感谢
这听起来像你想的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()
等。希望这可以让你走上正确的道路。
Tnx的详细答案,但是set()方法会不会始终成功地将值存储在memcahed中?它只会删除一个较旧的值并存储新的值,导致get方法永远不会到达file_cache。如我错了请纠正我。 – YardenST 2013-03-20 07:24:15
是的,set()将存储在两者中。但是,如果memcached填满(这将发生在1GB ram和2GB数据集中),那么一半的值将在两个半中只会在file_cache中。由于memcached在填充时丢弃次数最少,所以file_cache中的一半将是最少使用的页面。那就是你想要的。如果你尝试去做一个很少使用的页面,它会错过memcached get,然后返回file_cache。 – krimkus 2013-03-20 15:45:15
我现在明白了,稍后我会试一下,看它是否按预期工作 – YardenST 2013-03-20 15:56:59
利用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',
}
}
的一种方式(不知道最简单的)是写[自定义后端(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
@AlexanderAfanasiev我知道这是方向,我的问题是关于实现它的最佳实践 – YardenST 2013-03-19 09:27:08