緩存
計算機的讀寫速度在不同的硬件中是不同的逞敷,通常讀寫速度由慢到快順序為:
硬盤文件 > 內存空間 > 寄存器【數(shù)據(jù)運算】
當我們的web項目在大量用戶訪問大量數(shù)據(jù)的時候,已經不滿足快速展示數(shù)據(jù)允华,大大降低了用戶體驗粘咖,要提升程序處理的性能有一下幾種方法:
1霍弹、提高硬件配置选侨,通過提升硬性條件提高性能
2哪怔、分布式集群部署項目灶伊,在高并發(fā)處理中有絕佳的提升
3、使用緩存——針對程序最慢的從數(shù)據(jù)庫獲取數(shù)據(jù)這一步驟進行優(yōu)化
緩存是直接在內存寄存器中進行數(shù)據(jù)讀取肚逸,相對比從數(shù)據(jù)庫中讀取數(shù)據(jù)快了很多爷辙;通過緩存的方式,將頻繁查詢的數(shù)據(jù)朦促,存儲在緩存中膝晾,省略掉了從數(shù)據(jù)庫查詢數(shù)據(jù)的過程,從而提高了數(shù)據(jù)處理性能务冕。
Django中如何使用緩存
Django中常見的緩存手段:
1血当、memcache緩存
2、redis緩存
3、數(shù)據(jù)庫緩存
4歹颓、文件緩存
其中memcache和redis緩存是最常用的坯屿,這里介紹Django和redis配合完成緩存油湖,提升性能和解決一些問題
django-redis第三方工具
官方文檔[中文]http://django-redis-chs.readthedocs.io/zh_CN/latest/
通過pip install django-redis 安裝
settings中配置django-redis
# 添加django-redis緩存配置
CACHES = {
"default": {
# 后臺引擎
"BACKEND": "django_redis.cache.RedisCache",
# 緩存器類型://host:port/1號庫
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
處理函數(shù)中操作緩存
這里我們選擇將所有用戶的列表作為需要緩存的數(shù)據(jù)進行操作巍扛,首先創(chuàng)建用戶數(shù)據(jù)類型:
# models.py文件內容
from django.db import models
class Users(models.Model):
id = AutoField(primary_key=True)
name = models.CharField(max_length=50)
age = models.IntegerField(default=0)
birthday=models.DateField()
# 定義數(shù)據(jù)管理器對象
users_manager = models.Manager()
在處理函數(shù)中首先要引入django操作緩存的模塊,然后操作緩存
# views.py,導入包時遵循:framework > 內置庫 > 擴展庫 > 自定義包
from django.shortcuts import render redirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.core.cache import cache
from datetime import datetime
from . import models
# 展示所有用戶的處理函數(shù)
def index(request):
# 首先從緩存中獲取數(shù)據(jù)乏德,不存在則訪問數(shù)據(jù)庫并將數(shù)據(jù)添加到緩存提升以后訪問的性能
user_list = cache.get("cache_user_list")
if user_list is None:
# 數(shù)據(jù)管理器從數(shù)據(jù)庫獲取數(shù)據(jù)撤奸,按生日倒序排列
user_list = models.Users.users_manager.order_by("-birthday")
# 保存到緩存中
cache.set("cache_user_list",user_list)
return render(request,"index.html",{"user_list":user_list})
# 我們再定義一個創(chuàng)建用戶的處理函數(shù)
def create_user(request):
# 獲取請求體中的post數(shù)據(jù)
name = request.POST["name"]
age = request.POST.get["age"]
# 前端傳輸?shù)臄?shù)據(jù)是字符串時間如1991/01/01對其進行處理轉成時間對象入庫
birthday = request.POST["birthday"]
birthday = datetime.strptime(birthday,"%Y/%m/%d")
# 數(shù)據(jù)管理器入庫
models.Users.users_manager.create(name=name,age=age,birthday=birthday)
# 這時我們注意到了問題,添加數(shù)據(jù)后再次返回頁面時數(shù)據(jù)庫數(shù)據(jù)已經發(fā)生了改變喊括,
# 但是緩存中的數(shù)據(jù)還是舊數(shù)據(jù)胧瓜,所以需要刷新緩存,這是非常重要的步驟郑什!
user_list = models.Users.users_manager.order_by("-birthday")
cache.set("cache_user_list",user_list)
# 直接通過路由name反向查找路由
return redirect(reverse("mysite:index"))
這樣就實現(xiàn)了簡單的緩存操作府喳,但是以上的代碼有很多冗余,并且處理數(shù)據(jù)的操作函數(shù)和操作緩存的函數(shù)放在了一起蘑拯,不符合編碼規(guī)范钝满,所以對代碼進行一下改造:
# 新建一個文件cache_manager.py專門負責控制緩存的操作
from django.core.cache import cache
from . import models
def get_user_list(flush=False):
user_list = cache.get("cache_user_list")
if user_list is None or flush:
user_list = models.Users.users_manager.order_by("-birthday")
cache.set("cache_user_list",user_list)
return user_list
# views.py 修改部分
from . import cache_manager.py
def index(request):
user_list = cache_manager.get_user_list()
return render(request,"index.html",{"user_list":user_list})
def create_user(request):
...
# 刷新緩存
cache_manager.get_user_list(flush=True)
return redirect(reverse("mysite:index"))
什么樣的數(shù)據(jù)應該被緩存
通過以上的代碼我們發(fā)現(xiàn)如果數(shù)據(jù)頻繁被修改或新增,數(shù)據(jù)的展示總會伴隨著刷新緩存的操作申窘,這樣反而增大了數(shù)據(jù)處理的負擔弯蚜,所以頻繁改變的數(shù)據(jù)不應該被緩存,而大量的需要頻繁展示剃法,很少改變的數(shù)據(jù)是可以被緩存的碎捺。
使用緩存:
1、大量的贷洲,頻繁展示收厨,并且極少改變的數(shù)據(jù);
2优构、需要設置過期時間帽氓,讓用戶在規(guī)定時間內操作的數(shù)據(jù);
3俩块、最長用的地方:分布式部署時黎休,保證狀態(tài)保持讓所有的session儲存在同一個緩存服務器上,解決集群不同服務器對同一用戶頻繁訪問無法實現(xiàn)狀態(tài)保持的問題