2016-02-12 1 views
2

Я использовал для кэширования запроса базы данных в глобальной переменной для ускорения моего приложения. Поскольку это сильно недопустимо (и это создавало проблемы), я хочу использовать любой тип кеша Django. Я попробовал LocMemCache и DatabaseCache, но оба берут ... около 15 секунд, чтобы установить мою переменную (в два раза больше, чем требуется для генерации данных размером 7 МБ).Очень медленно писать в кеш Django

Ожидаемое? Я делаю что-то неправильно ?

(Memcached ограничен 1 МБ, и я не могу разбить свои данные, которые состоят из произвольно больших двоичных масок).

Редактировать: FileBasedCache занимает 30 секунд для установки.

Settings.py:

CACHES = { 
    'default': {...}, 
    'stats': { 
     'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 
     # or 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 
     'LOCATION': 'stats', 
    }, 
} 

Service.py:

from django.core.cache import caches 

def stats_service(): 
    stats_cache = caches['stats'] 
    if stats_cache.get('key') is None: 
     stats_cache.set('key', data) # 15s with DatabaseCache, 30s with LocMemCache 
    return stats_cache.get('key') 

Глобальная переменная (супер быстрая) версия:

_cache = {} 

def stats_service(): 
    if _cache.get('key') is None: 
     _cache['key'] = data 
    return _cache['key'] 
+1

Кэш замачивает значение, я не удивлен, что для определения количества 7MB требуется столько времени. В зависимости от того, к чему вы клонируете и для чего вы его используете, могут быть лучшие способы. – knbk

+0

Это объясняет это, я полностью пропустил этот момент. Я абсолютно не хочу рассортировать его (очевидно, 7 МБ ОЗУ не проблема). Я кэширую бит-маски (двоичные массивы numpy), которые я использую повторно при каждом вычислении. У вас есть какие-нибудь предложения? – JulienD

+0

Я нашел это: https://djangosnippets.org/snippets/2396/. Мой единственный страх с глобальным диктом заключается в том, что я использую многопроцессорность в вычислениях с использованием кэшированных массивов. – JulienD

ответ

0

Этот фрагмент кода на самом деле работает отлично: https://djangosnippets.org/snippets/2396/

Как я понял, the only problem с использованием глобальных переменных для кэширования потокобезопасность, и это не-рассол версия потокобезопасно.

2

Одним из вариантов может быть использование diskcache.DjangoCache. DiskCache расширяет API кеширования Django для поддержки записи и чтения двоичных потоков как есть (избегайте травления). Он работает особенно хорошо для больших значений (например, более 1 МБ). DiskCache - это лицензионный диск Apache2 и file backed cache library, написанный на чистом Python и совместимый с Django.

В вашем случае вы можете использовать ndarray tostring и numpy fromstring методы для быстрого преобразования в/из строки Python. Затем заверните строку с io.StringIO для сохранения/получения в кеше. Например:

from django.core.cache import cache 

value = cache.get('cache-key', read=True) 

if value: 
    data = numpy.fromstring(value.read()) 
    value.close() 
else: 
    data = ... # Generate 7MB array. 
    cachge.set('cache-key', io.StringIO(data.tostring()), read=True) 

DiskCache расширяет Django кэш API, разрешая значения файлов типа, которые хранятся в виде двоичных сгустков на диске. На странице Django cache benchmarks обсуждаются и сравниваются альтернативные кэш-серверы.

+0

Спасибо, я определенно собираюсь попробовать это. Я бы очень хотел использовать быстрый доступ к памяти вместо диска и избежать преобразования, хотя ( – JulienD

+0

@muraveill Чтобы избежать использования файлов на диске, увеличьте параметр 'large_value_threshold' ([API docs] (http: //www.grantjenks. com/docs/diskcache/api.html # diskcache.DEFAULT_SETTINGS)). Кэш-записи все еще сохраняются на диске, но чтение происходит из файла с синхронизированной памятью. В этом случае не переносите значения с помощью 'io.StringIO' просто передайте исходные строки байтов, они не будут мариноваться. Возможно, вам понадобится увеличить другие настройки кеша, чтобы использовать больше памяти. – GrantJ

 Смежные вопросы

  • Нет связанных вопросов^_^