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