07.Django-快取
快取
快取是將一些常用的數據保存到記憶體或者memcache中。在一定的時間內有人來訪問這些數據時,則不再去執行資料庫及渲染等操作,而是直接從記憶體或memcache的快取中去取得數據,然後返回給用戶。
一、如何提高網站並發量?
- cdn加速:把靜態資源放到別人伺服器
- 精靈圖
- 後台資料庫用mysql+redis
- sql的優化:索引,分庫分表,讀寫分離
- 用快取
- 程式架構:集群化的部署,分散式+非同步 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. 全站使用快取
-
用戶的請求到達中間件,並經過中間件的認證
-
如果請求的內容在快取中,則使用FetchFromCacheMiddleware獲取內容並返回給用戶
-
請求的內容不存在快取,去操作資料庫取得數據,經過渲染生成字元串返回給用戶
-
當返回給用戶之前,判斷快取中是否已經存在該數據,如果不存在,則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秒,頁面上的時間變化一次,這樣就實現了全站快取