摘要:實際執行緩存操作的函數需要用到數據行的延遲值,如果某個數據行的延遲值不存在,那么程序將取消對這個數據行的調度。上一篇文章實戰第二章使用構建應用第三節網頁緩存下一篇文章實戰第二章使用構建應用第五節網頁分析
上一篇文章: Python--Redis實戰:第二章:使用Redis構建Web應用:第三節:網頁緩存
下一篇文章:Python--Redis實戰:第二章:使用Redis構建Web應用:第五節:網頁分析
到目前為止,我們已經:
將原本由關系數據庫和網頁瀏覽器實現的登錄和訪客會話轉移到了Redis上面實現;
將原本有關系數據庫實現的購物車也放到了Redis上面實現;
將所有頁面緩存到了Redis里面;
這一系列工作提升了網站的性能,降低了關系數據庫的負載并較少了網站的成本。
現在經過分析,我們的網站的商品頁面通常只會從數據庫里面載入一兩行數據,包括已登錄用戶的用戶信息【這些信息可以通過AJAX動態載入,所以不會對頁面緩存造成影響】和商品本身的信息。即使是那些無法被整個緩存起來的頁面:比如用戶賬號頁面、記錄用戶以往購買商品的頁面等等,程序也可以通過緩存頁面載入時所需的數據庫行來減少載入頁面所需的時間。
為了展示數據行緩存的作用,我們假設我們的網站為了清空舊庫存和吸引客戶消費,決定開始新一輪的促銷活動:這個活動每天都會推出一些特價商品供用戶搶購,所有特價商品的數量都是限定的,賣完即止。在這種情況下,網址是不能對整個促銷頁面進行緩存的,因為這可能會導致用戶看到錯誤的特價商品的剩余數量,但是每次載入頁面都從數據庫里面取出特價商品的剩余數量的話,又會給數據庫帶來巨大的壓力,并導致我們需要花費額外的成本來擴展數據庫。
為了應對促銷互動帶來的大量負載,我們需要對數據行進行緩存,具體的做法是:編寫一個持續運行的守護進程函數,讓這個函數將指定的數據行緩存到Redis里面,并不定期地對這些緩存進行更新。緩存函數會將數據行編碼【encode】為JSON字典并存儲在Redis的字符串里面,其中,數據列【column】的名字會被映射為JSON字典的鍵,而數據行的值則會被映射為JSON字典的值。
程序使用了兩個有序集合來記錄應該在何時對緩存進行更新:
第一個有序集合為調度【schedule】有序集合,它的成員為數據行的行ID,而分值則是一個時間戳,這個時間戳記錄了應該在何時將制定的數據行緩存到Redus里面
第二個有序集合為延時【delay】有序集合,它的成員也是數據行的ID,而分值則記錄了指定數據行的緩存需要每隔多少秒更新一次。
為了讓緩存函數定期的緩存數據行,程序首先需要將行ID和給定的延遲值添加到延遲有序集合里面,然后再將行ID和當前時間的時間戳添加到調度有序集合里面。實際執行緩存操作的函數需要用到數據行的延遲值,如果某個數據行的延遲值不存在,那么程序將取消對這個數據行的調度。如果我們想要移除某個數據行已有的緩存,并且讓緩存函數不再緩存那個數據行,那么只需要把那個數據行的延遲值設置為小于或等于0就可以了。
#負責調度緩存和終止緩存的函數 import time def schedule_row_cache(conn,row_id,delay): #先設置數據行的延遲值 conn.zadd("delay:",row_id,delay) #立即對需要緩存的數據行進行調度 conn.zadd("schedule:",row_id,time.time())
現在我們已經完成了調度部分,那么接下來該如何對數據進行緩存呢?負責緩存數據行的函數會嘗試讀取調度有序集合的第一個元素以及該元素的分值,如果調度有序集合沒有包含任何元素,或者分值存儲的時間戳所指定的時間尚未來臨,那么函數會先休眠50毫秒,然后再重新進行檢查。當緩存函數發現了一個需要理解進行更新的數據行時,緩存函數會檢查這個數據行的延遲值:如果數據行的延遲值小于或者等于0,那么緩存函數會從延遲有序集合和調度有序集合里面移除這個數據行ID,并從緩存里面刪除這個數據行已有的緩存,然后再重新進行檢查;對于延遲值大于0的數據行來說,緩存函數會中數據庫里面取出這些行,將他們編碼為JSON格式并存儲到Redis里面,然后更新這些行的調度時間。
def cahce_rows(conn): while not QUIT: #嘗試獲取下一個需要被緩存的數據行以及該行的調度時間戳,命令會返回一個包含0或1個元祖【tuple】的列表 next=conn.zrange("schedule:",0,0,withscores=True) now=time.time() if not next or next[0][3]>now: #暫時沒有行需要被緩存,休眠50毫秒后重試 time.sleep(.05) continue row_id=next[0][0] #獲取下一次調度的延遲水岸 delay=conn.zscore("delay:",row_id) if delay<=0: #不必再緩存這個行,將他從緩存中移除 conn.zrem("delay:",row_id) conn.delete("inv:"+row_id) continue #讀取行數據 row=Inventory.get(row_id) #更新調度時間并設置緩存值 conn.zadd("schedule:",row_id,now+delay) conn.set("inv:"+row_id,json.dumps(row.to_dict()))
通過組合使用調度函數和持續運行緩存函數,我們實現了一種重復進行調度的自動緩存機制,并且可以隨心所欲地控制緩存行緩存的更新頻率:如果數據行記錄的是特價促銷商品的剩余數量,并且參與促銷活動的用戶非常多的話,那么我們最好每隔幾秒更新一次數據行緩存;另一方面,如果數據并不經常改變,或者商品缺貨是可以接受的,那么我們可以每分鐘更新一次緩存。
在這一節中,我們學習了如何將數據行緩存到Redis里面,在下面一節中,我們通過只緩存一部分頁面來減少時間頁面緩存所需的內存數量。
上一篇文章: Python--Redis實戰:第二章:使用Redis構建Web應用:第三節:網頁緩存
下一篇文章:Python--Redis實戰:第二章:使用Redis構建Web應用:第五節:網頁分析
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/42562.html
摘要:研究表明,減少用戶等待頁面載入的時間,可以增加用戶使用網站的欲望,并改善用戶對網站的印象。上一篇文章實戰第二章使用構建應用第二節使用實現購物車下一篇文章實戰第二章使用構建應用第四節數據行緩存 上一篇文章: Python--Redis實戰:第二章:使用Redis構建Web應用:第二節:使用Redis實現購物車下一篇文章:Python--Redis實戰:第二章:使用Redis構建Web應用...
摘要:每個分值,函數就會刪除所有排名在名之后的商品,并將刪除之后剩余的所有商品的瀏覽次數減半。上一篇文章實戰第二章使用構建應用第四節數據行緩存下一篇文章實戰第三章命令第一節字符串 上一篇文章:Python--Redis實戰:第二章:使用Redis構建Web應用:第四節:數據行緩存下一篇文章:Python--Redis實戰:第三章:Redis命令:第一節:字符串 網站可以從用戶的訪問、交互、...
閱讀 2148·2021-10-12 10:11
閱讀 849·2021-10-09 09:41
閱讀 3766·2021-09-09 11:37
閱讀 1942·2021-09-08 10:41
閱讀 2644·2019-08-30 12:58
閱讀 2375·2019-08-30 10:58
閱讀 1281·2019-08-26 13:40
閱讀 4118·2019-08-26 13:36