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