You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django项目Redis缓存性能异常:带缓存接口为何更慢?

Django中Redis缓存接口性能异常降低的问题排查

测试数据对比

无缓存接口(person)测试结果

[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Max requests:        50
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Concurrency level:   1
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Agent:               none
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO 
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Completed requests:  50
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Total errors:        0
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Total time:          0.40408834 s
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Requests per second: 124
[Thu Mar 23 2023 17:48:01 GMT+0530 (India Standard Time)] INFO Mean latency:        8 ms

带缓存接口(person1)测试结果

[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Max requests:        50
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Concurrency level:   1
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Agent:               none
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO 
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Completed requests:  50
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Total errors:        0
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Total time:          18.811554342 s
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Requests per second: 3
[Thu Mar 23 2023 17:47:56 GMT+0530 (India Standard Time)] INFO Mean latency:        376.1 ms

接口实现代码

def person(request):       
    if 'auth' in request.session and  request.session['auth']:
        res_all = Person.objects.values().all()
        return render(request,'blog.html',context={"all_data":res_all})
    else:
        return render(request,'blog.html',context={})


def person1(request):
    cache_data=cache.get('cache_key_person')
    if cache_data:
        return render(request,'blog.html',context={"all_data":cache_data})
    else:
        res_all = Person.objects.values().all()            
        cache.set('cache_key_person', res_all, CACHE_TTL) 
        return render(request,'blog.html',context={"all_data":res_all})

问题根因分析

带缓存接口性能暴跌的核心原因是缓存了未执行的QuerySet对象:

  • Django的Person.objects.values().all()返回的是惰性求值的QuerySet,它不是实际查询结果,而是包含数据库连接、查询参数等大量冗余信息的查询构造器。
  • 调用cache.set存储该QuerySet时,Django会通过pickle对其序列化,这个过程耗时极长,且生成的序列化数据体积远大于实际查询结果。
  • 后续从缓存获取数据时,还要对庞大的序列化对象反序列化,进一步拉长请求响应时间。
  • 无缓存接口中,Person.objects.values().all()在传递给模板时才执行查询,直接返回字典列表,无额外序列化/反序列化开销,若数据库本身查询速度快,整体性能自然远超带缓存接口。

修复方案

修改带缓存接口,将QuerySet执行后的实际结果存入缓存:

def person1(request):
    cache_data=cache.get('cache_key_person')
    if cache_data:
        return render(request,'blog.html',context={"all_data":cache_data})
    else:
        # 将QuerySet转为列表,执行查询并获取实际结果
        res_all = list(Person.objects.values().all())            
        cache.set('cache_key_person', res_all, CACHE_TTL) 
        return render(request,'blog.html',context={"all_data":res_all})

额外优化检查点:

  • 确认Redis连接配置合理性,避免每次请求新建连接(Django默认Redis缓存后端维护连接池,配置错误会导致连接开销过大)。
  • 若Person表数据量较大,可考虑对缓存结果分页,避免一次性缓存过多数据。

内容的提问来源于stack exchange,提问作者Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 10:12:56