2013-03-16 51 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', 
     } 
    }