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

How to store data in Django cache as a reference rather than value.?

我正在为 python 程序员使用后缀树包装器。 https://hkn.eecs.berkeley.edu/~dyoo/python/suffix_trees/

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

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

问题2:在2次检索后,python浮动了一个"Segmentation fault (core dumped)"

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

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

问题 3:他们是否有任何其他方法在 django 的某个地方存储后缀树的持久实例,具有相同的实例?

$ 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)

问题的关键在于 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 存储库提交错误。