【问题标题】:Employing caching for the first page of a paginated view in Django在 Django 中为分页视图的第一页使用缓存
【发布时间】:2017-02-02 09:05:00
【问题描述】:

我有一个分页的 Django 论坛,其中用户的帖子根据最近的发布时间累积。我每页显示 20 个帖子。在高峰期,每约 2 秒会保存一篇新帖子,而请求页面每秒查看多达 11 次。

我想通过引入缓存来减少数据库命中。我注意到大部分流量都到达第一页 - 所以这是我要缓存的。本质上,我计划在每次写入时 set 缓存中的第一页,并在观众想要使用它时 get 它。我可以选择redis 和memcache 作为缓存后端。

我的问题是如何缓存和提供只是第一页。我的未缓存代码如下:

#object_list has up to 1000 object ids at a time
paginator = Paginator(object_list, 20) #pass list of obj ids & no. of objs/page
page = request.GET.get('page', '1')
try:
    page = paginator.page(page)
except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    page = paginator.page(1)
except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
    page = paginator.page(paginator.num_pages)
page_contents = retrieve_posts(page.object_list) #retrieve 20 objects

【问题讨论】:

    标签: python django caching pagination memcached


    【解决方案1】:

    如果页码为 1,以下将尝试检查缓存。如果没有找到,则会向数据库发出请求。

    page = request.GET.get('page', '1')
    if page == '1':
        cached_page = cache.get('cached_page',None)
        if cached_page:
            return cached_page
    
    #object_list has up to 1000 object ids at a time
    paginator = Paginator(object_list, 20) #pass list of obj ids & no. of objs/page
    try:
        page = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        page = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        page = paginator.page(paginator.num_pages)
    
    page_contents = retrieve_posts(page.object_list) #retrieve 20 objects
    if page == '1':
        cache.set('cached_page',page_contents)
    

    不清楚您的查询集是什么样的。但是除非你有令人信服的证据表明这是一个缓慢的查询,否则这是过早的优化。使用主键从数据库中检索项目非常快。由于您必须每秒两次使缓存无效,因此这种开销可能不值得付出努力。

    【讨论】:

    • 你好!我会试一试,然后用精确的基准等回复你。实际上,缓存失效可能是这里的瓶颈。我想知道 memcached 或 redis 是否适合这种微缓存。
    • memcached 可能更好
    • 既然是多线程的,在这种特殊情况下会不会有竞争条件的风险?
    • 使用缓存总是存在竞争条件的可能性。仅当竞争条件无关紧要时才应使用缓存
    • 我计划在每次写入时更新缓存中的键。然后只需使用cache.get() 在需要时检索缓存的数据(就像您也指出的那样)。所以从技术上讲,这种模式不应该导致任何不良后果,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2013-12-25
    • 2020-10-26
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多