写入Django缓存的速度非常慢
我曾经在全局变量中缓存数据库查询以加速我的应用程序。由于这是强烈unadvised(并且它产生了问题),我想要使用任何类型的Django缓存。我尝试了LocMemCache和DatabaseCache,但都采取...约15秒设置我的变量(比生成数据所需的时间长两倍,即7MB大小)。写入Django缓存的速度非常慢
这是预期的吗?难道我做错了什么 ?
(Memcached限制为1MB,我不能分割我的数据,它包含任意大的二进制掩码)。
编辑: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']
这段代码实际上正常工作:https://djangosnippets.org/snippets/2396/
我的理解,the only problem使用全局变量缓存是线程安全的,这不,泡菜版本是线程安全的。
一种选项可使用diskcache.DjangoCache。 DiskCache扩展了Django缓存API以支持按原样写入和读取二进制流(避免酸洗)。对于大数值(比如大于1MB的数值)它特别有效。 DiskCache是一个Apache2许可磁盘,用纯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页面讨论并比较了备用缓存后端。
谢谢,我一定会试试这个。我真的想使用快速内存访问而不是磁盘,并避免转换,但( – JulienD
@muraveill为避免使用磁盘上的文件,请增加'large_value_threshold'设置([API文档](http://www.grantjenks。 com/docs/diskcache/api.html#diskcache.DEFAULT_SETTINGS))。高速缓存写入仍然会保留在磁盘上,但是读取会从同步的内存映射文件中发生,在这种情况下,不要用'io.StringIO'只传递原始字节字符串,不会被腌制,您可能还需要增加其他缓存设置以使用更多内存。 – GrantJ
缓存pickles的价值,我并不感到惊讶,需要如此长的时间来腌制一个7MB的值。根据你缓存的内容和你使用的内容,可能有更好的方法。 – knbk
这确实解释了,我完全错过了这一点。我绝对不想腌它(显然7MB内存不是问题)。我缓存位掩码(二进制numpy数组),我在每次计算中都重用。你有什么建议吗? – JulienD
我发现这个:https://djangosnippets.org/snippets/2396/。我唯一担心的是全局字典是我在使用缓存数组的计算中使用多处理。 – JulienD