<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>

輪播圖接口加緩存和定時更新(雙寫一致性問題以及其解決方案)

一、輪播圖加緩存

有些知名網站首頁被訪問的頻率很高,假設瞬間 1w個人在訪問,首頁的輪播圖接口會執行1w次,1w次查詢輪播圖標的sql在執行,輪播圖基本不變,首先我們給自己寫的輪播圖接口加緩存,我們可以用緩存數據庫Redis來實現加緩存的需求

首先羅列一下文字版的邏輯,之后在代碼上實現

  1. 當輪播圖接口來了請求
  2. 先去緩存看看,如果有緩存,直接返回
  3. 如果沒有緩存,則去數據庫查詢
  4. 然后拿到數據放到Redis中,緩存起來

通過代碼實現加緩存

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from luffy_api.utils.common_response import APIResponse
from .models import Banner
from .serializer import BannerSerializer
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, headers={'Access-control-Allow-Origin': '*'})
    """加緩存之后的邏輯"""
    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)

image
Redis數據庫也查到了緩存數據的信息
image

二、那么到底什么是雙寫一致性?

雙寫一致性指的是當我們更新了數據庫的數據之后redis中的數據 也要同步去更新。使用redis讀取數據的流程,當用戶訪問數據的時候,會先從緩存中讀取數據,如果命中緩存的話,那么直接把緩存中的數據返回給用戶,如果緩存中沒有數據的話,先查詢數據庫把查詢到的數據保存到緩存中,然后返回給用戶??偨Y下來就是寫入mysql,redis沒動,數據不一致存在問題
image

三、如何解決雙寫一致性問題

  1. 修改數據,刪除緩存
  2. 修改數據,更新緩存
  3. 定時更新,用celery

四、使用celery來解決雙寫一致性問題

通過截圖解釋代碼的流程
image
在celery.py文件里面寫如下代碼

from datetime import timedelta
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'
# 不要忘了include
app = Celery('test', broker=broker, backend=backend,
             include=['celery_task.banner_update_task'])

# 任務的定時配置(celery的配置文件)
app.conf.timezone = 'Asia/Shanghai'  # 時區
app.conf.enable_utc = False  # 是否使用UTC
# 定時任務
app.conf.beat_schedule = {
    'update_banner': {
        'task': 'celery_task.banner_update_task.update_banner',
        'schedule': timedelta(seconds=3),  # 時間對象
    },
}

在任務文件里面寫如下代碼

from .celery import app
from home.models import Banner
from home.serializer import BannerSerializer
from django.core.cache import cache
from django.conf import settings


@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'] = settings.BACKEND_URL + item['image']

    cache.set('banner_list', ser.data)  # 會出問題,輪播圖地址顯示不全
    return True

啟動worker

celery  -A celery_task  worker -l info -P eventlet

啟動beat

celery -A celery_task beat -l info

確保過程中不出錯,把前后端都重啟一遍

posted @ 2023-03-12 18:07  阿麗米熱  閱讀(194)  評論(0編輯  收藏  舉報
Title
人碰人摸人爱免费视频播放

<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>