轮播图接口加缓存
为什么要加缓存
- 网站首页被访问的频率很高,同一时间1w个人在访问,首页的轮播图接口会执行1w次,如果每一次都向后台拿数据,则效率较低
- 想一种方式,让这1w个访问,效率更高一些,不查数据库了,直接走缓存--》redis--》效率高
- 现在的逻辑变成了
- 轮播图接口请求来了,先去缓存中看,如果有,直接返回
- 如果没有,查数据库,然后把轮播图数据,放到redis中,缓存起来
轮播图接口修改
from rest_framework.viewsets import GenericViewSet from .models import Banner from .serializer import BannerSerializer from rest_framework.mixins import ListModelMixin from utils.common_response import APIResponse from django.core.cache import cache class BannerView(GenericViewSet,ListModelMixin): queryset = Banner.objects.filter(is_delete=False,is_show=True).order_by('orders') serializer_class = BannerSerializer # 原来的接口 # def list(self, request, *args, **kwargs): # res = super().list(request,*args,**kwargs) # return APIResponse(data=res.data) # 加入缓存的轮播图接口 def list(self, request, *args, **kwargs): # 获取缓存中的数据 banner_list=cache.get('banner_list') if banner_list: print('走了缓存') # 缓存中有数据,直接返回缓存中的数据 return APIResponse(data=banner_list) else: print('走了数据库') # 缓存中没有,走数据库 res = super().list(request,*args,**kwargs) # 把序列化后的数据存入缓存中 cache.set('banner_list',res.data) return APIResponse(data=res.data)
双写一致性
- 加入缓存后,缓存中有数据,先去缓存拿,但是如果mysql中数据变了,缓存不会自动变化,出现数据不一致的问题
如何解决数据不一致问题
- 1 修改数据,删除缓存
- 2 修改数据,更新缓存
- 3 定时更新缓存 ---》实时性差
示例:定时更新(使用celery的定时任务)
celery_task/home_task.py
from .celery import app from home.models import Banner from home.serializer import BannerSerializer from django.core.cache import cache @app.task def update_banner(): # 只要这个任务一更新,就更新轮播图的缓存 banners = Banner.objects.all().filter(is_delete=False,is_show=True).order_by('orders') ser=BannerSerializer(instance=banners,many=True) cache.set('banner_list',ser.data) return True
celery.py
from celery import Celery import os os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev') broker = 'redis://127.0.0.1:6379/1' backend = 'redis://127.0.0.1:6379/2' app = Celery('test',broker=broker,backend=backend,include=['celery_task.home_task']) # 设置时区 app.conf.timezone = 'Asia/Shanghai' # 是否使用UTC app.conf.enable_utc = False from datetime import timedelta from celery.schedules import crontab # 任务的定时配置 app.conf.beat_schedule = { 'update_banner': { 'task': 'celery_task.home_task.update_banner', # 定时任务路径 'schedule': timedelta(days=7), # 每隔7天更新一次,具体时间看项目需求 } }
补充:使用视图函数存在的问题
- home页面图片无法正常显示(轮播图地址显示不全)
- 如果是在视图类中,会自动处理
解决方法:
1. 在配置文件设置后台路径
# dev.py BACKEND_URL='http://127.0.0.1:8000'
2. celery_task/home_task.py修改
from .celery import app from home.models import Banner from home.serializer import BannerSerializer from django.core.cache import cache from settings.dev import BACKEND_URL @app.task def update_banner(): # 只要这个任务一更新,就更新轮播图的缓存 banners = Banner.objects.all().filter(is_delete=False,is_show=True).order_by('orders') ser=BannerSerializer(instance=banners,many=True) for item in ser.data: item['image'] = BACKEND_URL + item['image'] cache.set('banner_list',ser.data) return True
标签:缓存,cache,list,Celery,task,import,banner,双写 From: https://www.cnblogs.com/chen-ao666/p/17201862.html