1

我正在使用 Django 1.7 和 GeoDjango 创建一个网站。当我需要优化网站速度时,我已经达到了目的。

瓶颈之一是查询执行。即使经过优化,有些查询也会运行缓慢。所以我想缓存查询结果并将它们存储在 Redis 中。

我得到的问题是我无法缓存一些查询结果。特别是那些包含几何类型和距离计算的。我遇到了“TypeError:无法腌制二进制对象”错误。

缓存 Django/GeoDjango QuerySets 的推荐/正确方法是什么?

4

1 回答 1

0

原来存储查询集的主要问题是:

  1. QuerySet 是惰性的
  2. 要评估它们,您需要对它们进行序列化 [链接]
  3. 并非所有 QuerySet 都可以序列化,因为 Python 的序列化程序(Pickle)有其自身的限制[链接]

我找到的最佳解决方案是将查询结果缓存在模板中。

所以在我的模板“sample.html”中我写了这样的东西:

{% cache 600 slow_query_results %}
<!-- result of page generation -->
{% endcache %}

鉴于我这样做:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key
...
slow_query_results_key = make_template_fragment_key('slow_query_results')
if not cache.get(slow_query_results_key):
    # return calculated result
    slow_query_results = perform_some_slow_query()

这种方法很好,因为存储在缓存中的数据是预期的文本形式。所以在存储数据时应该没有问题/异常。

主要缺点是:

  1. 缓存可能包含重复的相似数据。当您缓存包含语言翻译字符串等的 html 片段时,可能会发生这种情况。所以在某些情况下,您必须使用语言作为参数来生成缓存。如果您有 2 种语言的翻译,您将拥有 2 个相同数据的缓存。

  2. 在对 html 进行更改时,您必须使缓存无效。如果您正在缓存的代码块中的 html 不断变化,这可能会变得非常痛苦。

我个人认为问题1)没什么大不了的。问题 2) 可以通过对站点结构进行良好规划并知道您可以在 Redis 中对缓存键进行大量失效来避免。[链接]这是可能的,因为缓存以以下密钥格式存储:":1:template.cache.slow_query.8a5b358dfc28a6bc1b3397e398d28b66"

因此应该可以删除与某个缓存块相关的所有缓存键。

于 2014-12-02T11:02:33.027 回答