07.Django-快取

快取

快取是將一些常用的數據保存到記憶體或者memcache中。在一定的時間內有人來訪問這些數據時,則不再去執行資料庫及渲染等操作,而是直接從記憶體或memcache的快取中去取得數據,然後返回給用戶。

一、如何提高網站並發量?

  1. cdn加速:把靜態資源放到別人伺服器
  2. 精靈圖
  3. 後台資料庫用mysql+redis
  4. sql的優化:索引,分庫分表,讀寫分離
  5. 用快取
  6. 程式架構:集群化的部署,分散式+非同步 celery:分散式非同步任務

二、快取方式

1. 開發調式快取

開發調試快取為開發調試使用,實際上不執行任何操作

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',  # 快取後台使用的引擎
        'TIMEOUT': 300,     # 快取超時時間(默認300秒,None表示永不過期,0表示立即過期)
        'OPTIONS':{
            'MAX_ENTRIES': 300,    # 最大快取記錄的數量(默認300)      
            # 快取到達最大個數之後,剔除快取個數的比例,即:1/CULL_FREQUENCY(默認3)
            'CULL_FREQUENCY': 3,           
        }
    }
}

2. 記憶體快取

將快取內容保存至記憶體區域中

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 指定快取使用的引擎
        'LOCATION': 'unique-snowflake',         # 寫在記憶體中的變數的唯一值 
        'TIMEOUT':300,             # 快取超時時間(默認為300秒,None表示永不過期)
        'OPTIONS':{
            'MAX_ENTRIES': 300,    # 最大快取記錄的數量(默認300)      
            # 快取到達最大個數之後,剔除快取個數的比例,即:1/CULL_FREQUENCY(默認3)
            'CULL_FREQUENCY': 3,           
        } 
    }
}

3. 文件快取

Django會以自己的形式把快取文件保存在配置文件中指定的目錄中

CACHES = {
    'default': {
        'BACKEND':'django.core.cache.backends.filebased.FileBasedCache', #指定快取使用的引擎
        'LOCATION': '/var/tmp/django_cache',        #指定快取的路徑
        'TIMEOUT':300,              #快取超時時間(默認為300秒,None表示永不過期)
        'OPTIONS':{
            'MAX_ENTRIES': 300,    # 最大快取記錄的數量(默認300)      
            # 快取到達最大個數之後,剔除快取個數的比例,即:1/CULL_FREQUENCY(默認3)
            'CULL_FREQUENCY': 3,           
        }
    }   
}

4. 資料庫快取

把快取數據存儲在資料庫中

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',  # 指定快取使用的引擎
        'LOCATION': 'cache_table',          # 資料庫表    
        'OPTIONS':{
            'MAX_ENTRIES': 300, 	# 最大快取記錄的數量(默認300)
            # 快取到達最大個數之後,剔除快取個數的比例,即:1/CULL_FREQUENCY(默認3)
            'CULL_FREQUENCY': 3,          
        }  
    }   
}

5. Memcache快取

5.1 使用python-memcached模組

快取到Memcache資料庫

# 此快取使用python-memcached模組連接memcache          
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',   #通過網路socket連接,快取到單台服務的 memcache資料庫
    }
}
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': 'unix:/tmp/memcached.sock',  #通過本地文件socket,快取本機memcache資料庫
    }
}   
#通過網路socket連接,快取到memcache 集群
CACHES = {              #其中 6和89為
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            ('172.19.26.240:11211',6),                   
            ('172.19.26.242:11211',89),                 
        ]
    }
}
5.2 使用pylibmc模組

還可以使用其他Python模組連接到Memcache,老鐵你是否聯想到了 redis?默認還不支援!需要藉助第三方插件;

# 此快取使用pylibmc模組連接memcache
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '/tmp/memcached.sock',
    }
}   
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    }
}

三、快取應用

1. 單獨視圖快取

因為快取的原因,不停的刷新瀏覽器時會發現,頁面上顯示的時間每15秒鐘變化一次;

立即在資料庫中添加一個用戶對象,刷新瀏覽器,網頁上不會立即顯示剛才添加的用戶;

一直刷新瀏覽器15秒後,新添加的用戶才會在前端頁面上顯示出來。

添加路由記錄

url(r"^index$",views.index)

定義視圖函數

from app01 import models
from django.views.decorators.cache import cache_page  #導入設置快取的裝飾器
import time

@cache_page(15)	#超時時間為15秒
def index(request):
    user_list = models.UserInfo.objects.all()
    ctime = time.time()
    return render(request,"index.html",{"user_list":user_list,"ctime":ctime})

定義HTML頁面

<body>
    <h1>{{ ctime }}</h1>
    <ul>
        {% for user in user_list %}
        <li>{{ user.name }}</li>
        {% endfor %}
    </ul>
</body>

2. 局部視圖快取

刷新頁面時,整個網頁有一部分頁面實現快取即為局部視圖快取

添加路由記錄

url(r"^index$",views.index)

定義視圖函數

from django.shortcuts import render
import time
def index(request):
    ctime = time.time()
    return render(request,"index.html",{"ctime":ctime})

定義HTML頁面

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meat charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ ctime }}</h1>
    {% cache 15 'aaa' %}
    <h1>{{ ctime }}</h1>
    {% endcache %}
</body>
</html>

刷新瀏覽器可以看到,第一個時間實時變化,後面一個時間15秒鐘變化一次

3. 全站使用快取

  1. 用戶的請求到達中間件,並經過中間件的認證

  2. 如果請求的內容在快取中,則使用FetchFromCacheMiddleware獲取內容並返回給用戶

  3. 請求的內容不存在快取,去操作資料庫取得數據,經過渲染生成字元串返回給用戶

  4. 當返回給用戶之前,判斷快取中是否已經存在該數據,如果不存在,則UpdateCacheMiddleware會基於取得的數據生成Django的快取

添加路由記錄

url(r"^index$",views.index)

配置文件

from django.middleware.cache import UpdateCacheMiddleware
from django.middleware.cache import FetchFromCacheMiddleware
MIDDLEWARE_CLASSES = [
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
] 
CACHE_MIDDLEWARE_SECONDS=15

定義視圖函數

from django.shortcuts import render
import time
def index(request):
    ctime = time.time()
    return render(request,"index.html",{"ctime":ctime})

定義HTML網頁

<body>
    <h1>{{ ctime }}</h1>
    <ul>
        {% for user in user_list %}
        <li>{{ user.name }}</li>
    </ul>
</body>

刷新瀏覽器時15秒,頁面上的時間變化一次,這樣就實現了全站快取