《Django中使用Redis進(jìn)行緩存》要點:
本文介紹了Django中使用Redis進(jìn)行緩存,希望對您有用。如果有疑問,可以聯(lián)系我們。
Python部落(python.freelycode.com)組織翻譯,禁止轉(zhuǎn)載,歡迎轉(zhuǎn)發(fā).
應(yīng)用程序的性能對于你的產(chǎn)品的成功與否顯得至關(guān)重要.在用戶想要網(wǎng)站在不到一秒1s的時間里響應(yīng)的情況下,一個緩慢的應(yīng)用程序就可以造成金錢上的損失.就算你沒有在銷售什么東西,更快的頁面加載也會改善使用體驗.
所有在服務(wù)器收到數(shù)據(jù)和作出響應(yīng)之間發(fā)生的事情都會延長頁面加載時間.照經(jīng)驗來說,在服務(wù)器省略越多的步驟,你的應(yīng)用程序跑的就越快.在數(shù)據(jù)被處理后將其緩存并在下一次請求時直接拿出來是減輕服務(wù)器壓力的一種方法.在這篇教程里,我們來研究一下拖慢你應(yīng)用程序速度的因素,再演示怎樣用Redis實現(xiàn)緩存來抵消那些因素的作用效果.
什么是Redis?
Redis是一個可以用來作為緩存引擎的基于內(nèi)存的數(shù)據(jù)結(jié)構(gòu)存儲.既然它在內(nèi)存中存儲數(shù)據(jù),那么速度一定很快.Redis不是唯一可以用來作為緩存的產(chǎn)品.Memcached便是另一款出名的基于內(nèi)存的緩存系統(tǒng),但很多人認(rèn)為在大多數(shù)情況下Redis比Memcached更優(yōu)秀.個人來說,我們喜歡它的設(shè)置簡單以及還可以用于其他用途,比如說Redis Queue.
開始
我們創(chuàng)建了一個示例應(yīng)用程序來向你介紹緩存的概念.我們的程序使用:
Django (v1.9.8
Django Debug Toolbar (v1.4
django-redis (v4.4.3
Redis (v3.2.0
安裝這個程序
在你克隆倉庫之前,先安裝virtualenvwrapper,如果你還沒有的話.這個工具讓你安裝你的項目需要的特定的Python依賴,并允許你定位你的app需要的版本和庫.
接下來,把目錄切換到你保存項目的地方再克隆示例程序倉庫.完成以后,把目錄切換進(jìn)去,再用 mkvirtualenv 命令為示例程序創(chuàng)建一個新的虛擬環(huán)境:
注意:用 mkvirtualenv 命令創(chuàng)建一個虛擬環(huán)境也就同時把它激活了.
用 pip安裝所有需要的Python依賴,再檢查一下下面的標(biāo)簽:
通過構(gòu)建數(shù)據(jù)庫并向其中填入樣本數(shù)據(jù)來結(jié)束示例程序的設(shè)置.別忘了創(chuàng)建一個超級用戶,這樣你才能登陸管理站點.跟隨下面的示例代碼再試試運行程序,確保它能正常工作.在瀏覽器里進(jìn)入管理頁確認(rèn)一下數(shù)據(jù)是否正常加載.
當(dāng)你的Django程序運行起來后,就去安裝Redis.
安裝Redis
按照文檔里提供的步驟下載安裝Redis.或者,你也可以用一個包管理器來安裝Redis,比如說 apt-get或者homebrew,具體取決于你的操作系統(tǒng).
在一個新的終端窗口中啟動Redis服務(wù):
接下來,在另一個終端窗口啟動Redis命令行接口(CLI),測試一下是否連接到了Redis Server. 我們會用Redis CLI來檢查添加到緩存中的鍵.
Redis提供了一個有著多種命令的API,開發(fā)者可以用來操作數(shù)據(jù)存儲.Django使用 django-redis來在Redis里執(zhí)行命令.
在一個文本編輯器里查看我們的示例程序,我們可以在 settings.py里看到Redis配置.我們在CACHES里定義了一個默認(rèn)緩存,用內(nèi)置的 django-redis 作為后端.Redis默認(rèn)在6379端口運行,我們在設(shè)置里指出這個端口.最后要指出的是,django-redis附加了帶有前綴和版本的鍵名來區(qū)分相似的鍵.所以我們把前綴定義為 "example".
注意:雖然我們配置了緩存后端,但是還沒有一個視圖函數(shù)真正實現(xiàn)緩存.
程序性能
在這篇文章開頭我們就曾提到,服務(wù)器處理一個請求所做的所有事情都會延長程序加載時間.運行業(yè)務(wù)邏輯和呈現(xiàn)模板的處理開銷可能很大.網(wǎng)絡(luò)潛在因素也會影響查詢數(shù)據(jù)庫的時間.每當(dāng)一個客戶端向服務(wù)器發(fā)送一個HTTP請求時,這些因素都會出現(xiàn).當(dāng)用戶每秒發(fā)起多個請求時,由于服務(wù)器要處理所有請求,性能的影響將變得明顯.
當(dāng)我們實現(xiàn)緩存時,我們讓服務(wù)器處理一次請求,然后將它存儲在緩存中.當(dāng)我們的應(yīng)用程序接收到相同URL的請求時,服務(wù)器就直接從緩存中提取結(jié)果,而不是每次都重新處理它們. 通常,我們會設(shè)置緩存結(jié)果的存活時間,以便可以定期刷新數(shù)據(jù),這是實現(xiàn)緩存的一個重要步驟,以避免提供過時的數(shù)據(jù).
您應(yīng)該考慮在以下情況存在時緩存請求的結(jié)果:
呈現(xiàn)頁面涉及到大量數(shù)據(jù)庫查詢和/或業(yè)務(wù)邏輯.
頁面經(jīng)常被你的用戶訪問.
每個用戶的數(shù)據(jù)是相同的.
數(shù)據(jù)不經(jīng)常變化.
從測量性能開始
首先,通過衡量應(yīng)用程序在收到請求后的響應(yīng)速度來測試應(yīng)用程序中每個頁面的速度.
為了實現(xiàn)這一點,我們使用loadtest,一個HTTP負(fù)載生成器,用大量的請求來“轟炸”每個頁面,再密切關(guān)注請求速率.點擊上面的鏈接安裝.安裝好后,根據(jù)/cookbook/URL路徑測試結(jié)果.
注意到我們每秒鐘處理16個請求:
當(dāng)我們看見代碼在干什么的時候,我們就可以決定怎樣作出改動來改善性能.該應(yīng)用程序向一個數(shù)據(jù)庫發(fā)出3個網(wǎng)絡(luò)調(diào)用請求 /cookbook/,并且每次調(diào)用都需要時間打開一個連接并執(zhí)行查詢.在你的瀏覽器里訪問/cookbook/URL并展開Django Debug工具欄選項卡以確認(rèn)此行為.找到名為“SQL”的標(biāo)簽再看看查詢的數(shù)目.
cookbook/services.py
cookbook/views.py
這個應(yīng)用程序還會渲染一個有著潛在的開銷巨大的邏輯的模板.
實現(xiàn)緩存
想象一下當(dāng)用戶訪問我們的網(wǎng)站時我們的應(yīng)用程序會發(fā)出的網(wǎng)絡(luò)調(diào)用的總數(shù).如果1000個用戶調(diào)用獲取cookbook的API,我們的程序就會進(jìn)行3000次數(shù)據(jù)庫查詢,并且每次請求都會渲染一個新模板.這個數(shù)字會隨著應(yīng)用程序規(guī)模的增長而曾長.幸好,這個視圖是用于緩存的不二之選.cookbook里的食譜很少變化.再說,既然app的中心作用是讀取cookbook,那么獲取食譜的API一定會被經(jīng)常調(diào)用.
在下面的例子中,我們改變了視圖函數(shù)以使其使用緩存.當(dāng)函數(shù)工作時,它會檢查視圖鍵是否在緩存中.如果鍵存在的話,app就從緩存讀取數(shù)據(jù)并返回.如果不在的話,Django就會查詢數(shù)據(jù)庫并將其和視圖鍵存儲在緩存中.函數(shù)第一次被調(diào)用時,Django會查詢數(shù)據(jù)庫并渲染模板,再向Redis發(fā)起網(wǎng)絡(luò)調(diào)用將數(shù)據(jù)存進(jìn)緩存.隨后的函數(shù)調(diào)用將會完全繞過數(shù)據(jù)庫和業(yè)務(wù)邏輯并直接查詢Redis緩存.
注意我們向視圖函數(shù)添加了一個裝飾器 @cache_page,還添加了一個生存時間.再訪問一下/cookbook/并檢查Django Debug 工具欄.我們看到進(jìn)行了3次數(shù)據(jù)庫查詢,并對緩存進(jìn)行了3次調(diào)用,以便檢查鍵,然后保存它.Django保存兩個鍵(一個鍵用于標(biāo)題,一個用于呈現(xiàn)的頁面內(nèi)容).重新加載頁面看看頁面活動怎樣變化的.第二次,數(shù)據(jù)庫調(diào)用0次,緩存調(diào)用兩次.我們的頁面現(xiàn)在是緩存提供的!
當(dāng)我們重新運行性能測試時,我們看到我們的程序加載更快了.
緩存提高了總負(fù)載量,我們現(xiàn)在每秒解析21個請求,比我們的基準(zhǔn)多了5個.
用CLI檢查Redis
這時候我們可以用Redis CLI看看Redis Server上存了些什么.在Redis命令行中,輸入命令 keys *,這會返回滿足任何模式的鍵.你應(yīng)該會看到一個叫“example:1:views.decorators.cache.cache_page”的鍵.別忘了,“example”是我們的鍵前綴,“1”是版本,“views.decorators.cache.cache_page”是Django給鍵的名字.把鍵名復(fù)制下來輸在get命令后面.你可以看到已渲染的HTML代碼.
注意:在Redis CLI運行 flushall 命令來從數(shù)據(jù)存儲里清除所有的鍵,然后你可以重新過一遍這個教程,不用等緩存過期了.
總結(jié)
處理HTTP請求的代價是昂貴的,并且會隨著你的應(yīng)用程序的數(shù)量增長而增加.有的情況下,實現(xiàn)緩存會極大地減少服務(wù)器的處理量.這篇教程涉及了在Django中用Redis實現(xiàn)緩存的一些基本點,略過了一些復(fù)雜的主題.在一個健壯的程序里實現(xiàn)緩存有很多陷阱.控制哪些數(shù)據(jù)被緩存和存活期有多長很困難.緩存失效是計算機科學(xué)中一件棘手的事情.保證私有數(shù)據(jù)只能被特定的用戶訪問是個安全問題并且需要在緩存時仔細(xì)處理.在示例程序中去玩轉(zhuǎn)源碼,并且在你繼續(xù)用Django開發(fā)的時候,要常記著考慮性能.
英文原文:https://realpython.com/blog/python/caching-in-django-with-redis/
歡迎參與《Django中使用Redis進(jìn)行緩存》討論,分享您的想法,維易PHP學(xué)院為您提供專業(yè)教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/10664.html