2013-03-16 1 views
3

Простой вопрос:Джанго Cache: Использование Memcached и возврат к FileSystem

Мой сервер имеет 1G RAM и 10GB дискового пространства

Я использую per-site cache, и я хочу, чтобы использовать как можно больше Memcached, но когда его вне пространства, что cache will be saved in hard disk.

(страницы Всего сайта вместе около 2 Гб)

Есть простая конфигурация для того чтобы достигнуть этого?

Действительно ли это умная вещь?

Благодаря

+0

Один из способов (не уверен, что самый простой), чтобы написать [пользовательский бэкенд] (https://docs.djangoproject.com/en/dev/topics/cache/#using-a-custom-cache- backend) и переключиться на кеш файловой системы, если memcached не может хранить вещи больше. Взгляните на django [встроенные бэкэнды] (https://github.com/django/django/tree/master/django/core/cache/backends). – alecxe

+0

@AlexanderAfanasiev Я знаю, что это направление, мой вопрос о лучшей практике для его реализации. – YardenST

ответ

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 может управлять своим собственным откатом, и только самые старые удары должны будут вернуться к файловому_качу. Это то, что вы хотите.

Конечно, вам также придется реализовать остальные функции кеша, такие как delete(), get_many() и т. Д. Надеемся, это поможет вам на правильном пути.

+0

Tnx для подробного ответа, однако не будет ли метод set() всегда сохранять значение в memcahed? он просто снизит старое значение и сохранит новый, что приведет к тому, что метод get никогда не достигнет file_cache. Поправьте меня если я ошибаюсь. – YardenST

+0

Да, set() будет хранить в обоих. Но если memcached заполняется (что произойдет с 1 ГБ оперативной памяти и 2-гигабайтным набором данных), то половина значений будет в обоих, а половина будет только в файле_качестве. Поскольку memcached падает наименее используемым, если он заполняется, половина файла file_cache будет наименее используемыми страницами. Это то, что ты хочешь. Если вы затем попытаетесь попасть на страницу, которая редко используется, она пропустит получение memcached и вернет файл file_cache. – krimkus

+0

Я получаю его сейчас, я попробую его позже, чтобы увидеть, работает ли он так, как ожидалось. – YardenST

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', 
     } 
    }