如何将Django缓存中的数据存储为引用而不是值。

时间:2016-04-21 07:56:58

标签: python django memcached suffix-tree

我正在为python Programmer使用Suffix Tree包装器。 https://hkn.eecs.berkeley.edu/~dyoo/python/suffix_trees/

我每次都需要相同的后缀树实例,在Django中调用视图。因此,我将后缀树实例存储在django-cache中,并在每次需要该实例时检索它。

问题1:当我从缓存中检索它时,它总是会改变内存位置。即使python存储数据使用引用。

问题2:2次检索后,python浮动“分段错误(核心转储)”

问题1:为什么后缀树的实例会从缓存中更改其内存位置?

问题2:为什么显示分段错误?

问题3:他们是否有任何其他方式在django中的某个地方存储Suffix Tree的持久实例,并使用相同的实例?

$ python manage.py shell                        
Python 2.7.5 (default, Mar 22 2016, 00:57:36) 
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import SuffixTree
>>> d=SuffixTree.SubstringDict()
>>> d["3132"]=1
>>> d["3"]
[1]
>>> d["4343"]=2
>>> d["3"]                                                                     
[1, 2]
>>> from django.core.cache import cache
>>> cache.set("c",d,1000)                                                      
>>> d
<SuffixTree.SubstringDict.SubstringDict instance at 0x27bd830>
>>> cache.get("c")
<SuffixTree.SubstringDict.SubstringDict instance at 0x27ca908>
>>> cache.get("c")
<SuffixTree.SubstringDict.SubstringDict instance at 0x27ca9e0>
>>> cache.get("c")
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:1)

问题的关键在于Django不会将缓存存储在进程内存中,因此放在缓存中的所有对象在存储之前都会被序列化,并在您获取它们时进行反序列化。每次检索它们时,都会创建新对象,它是存储对象的副本。

实现是这样的,因为在生产环境中,您将拥有多个django工作进程(可能在不同的服务器上运行)。并且所有工作进程都需要共享相同的缓存。因此,您不能在每个请求上拥有相同的实例,因为您可以使用不同的工作人员处理您的请求。

此问题的解决方法因应用程序的用途而异。

根据您的评论,您可以创建一个模块,用于在请求之间缓存实例:

from datetime import timedelta, datetime

MAX_LIVE_TIME = timedelta(seconds=3600)

_tree_instance = None
_tree_timestamp = None

def get_cached_tree():
    global _tree_instance, _tree_timestamp
    if _tree_instance is not None and _tree_timestamp - datetime.now() < MAX_LIVE_TIME:
        return _tree_instance

    _tree_instance = 'SuffixTree' # Replace this with SuffixTree creation
    _tree_timestamp = now()
    return _tree_instance

然后在您的视图中调用get_cached_tree()以获取SuffixTree。对于不同的工作人员,您仍然会有不同的实例,但它的工作速度会更快,并且没有段错误

P.S。分段错误是您使用的Python解释器中的错误的结果,或者更可能是您使用的包的错误。您应该确保使用包的最新版本(https://github.com/JDonner/SuffixTree),如果它没有帮助,您应该分析堆栈跟踪(核心转储)并向SuffixTree仓库提交错误。