您好,登錄后才能下訂單哦!
這篇文章主要介紹了在Python應用程序中實現緩存的方法,具有一定借鑒價值,需要的朋友可以參考下。下面就和我一起來看看吧。
緩存對于每個Python程序員來說都是一個需要理解的重要概念。
簡而言之,緩存的概念主要是利用編程技術將數據存儲在臨時位置,而不是每次都從源檢索數據。
隨后,緩存可以提高應用程序的性能,因為從臨時位置訪問數據比每次從源(如數據庫、web服務等)獲取數據更快。
本文旨在解釋Python中的緩存是如何工作的。
要理解緩存是什么以及為什么需要緩存,請考慮下面的場景。
我們正在用Python構建一個應用程序,它將向最終用戶顯示產品列表。這個應用程序每天會被超過100個用戶多次訪問。應用程序將托管在應用程序服務器上,并且可以在internet上訪問它。產品將存儲在一個數據庫中,該數據庫將安裝在數據庫服務器上。因此,應用服務器將查詢數據庫以獲取相關記錄。
下圖演示了我們的目標應用程序是如何設置的:
問題
從數據庫獲取數據是一個io綁定操作。因此,它的本性是緩慢的。如果頻繁發送請求,而響應更新不頻繁,那么我們可以將響應緩存到應用程序的內存中。
我們可以緩存結果,而不是每次都查詢數據庫,如下所示:
獲取數據的請求必須通過線路,響應必須通過線路返回。
這在本質上是緩慢的。因此,引入了緩存。
我們可以緩存結果,以減少計算時間和節省計算機資源。
緩存是一個臨時存儲位置。它以惰性加載方式工作。
最初,緩存是空的。當應用程序服務器從數據庫服務器獲取數據時,它將用所需的數據集填充緩存。從那時起,后續的請求將從緩存獲取數據,而不是一路到應用程序服務器。
我們還需要及時使緩存失效,以確保向最終用戶顯示最新的信息。
這就引出了本文的下一節:緩存規則。
在我看來,緩存有三條規則。
在啟用緩存之前,我們需要執行分析應用程序的關鍵步驟。
因此,在應用程序中引入緩存之前的第一步是對應用程序進行概要分析。只有這樣,我們才能了解每個函數需要多長時間以及它被調用了多少次。分析過程完成后,我們需要確定需要緩存的內容。
我們需要一種機制來連接函數的輸入和輸出,并將它們存儲在內存中。這就引出了緩存的第一條規則。
1. 緩存的第一條規則:
第一個規則是確保目標函數需要很長時間才能返回輸出,它經常被執行,并且函數的輸出不會經常改變。
我們不希望為那些不需要很長時間就能完成的函數、在應用程序中很少被調用的函數或那些返回結果卻在源代碼中頻繁更改的函數引入緩存。
這是一個需要記住的重要規則。
適合緩存的候選者:頻繁調用的函數,輸出不經常改變,執行需要很長時間
作為一個實例,如果一個函數執行了100次,并且函數需要很長時間才能返回結果,并且對于給定的輸入它返回相同的結果,那么我們可以緩存結果。
然而,如果一個函數返回的值更新每一秒在源得到請求執行函數每分鐘然后理解真的很重要我們需要緩存結果是否會最終將陳舊的數據發送給用戶。這可以幫助我們理解我們是否需要緩存,或者我們是否需要不同的通信通道、數據結構或序列化機制來更快地檢索數據,例如通過在套接字上使用二進制序列化器發送數據,而不是使用http上的xml序列化。
此外,知道什么時候使緩存失效,什么時候用新數據重新加載緩存也很重要。
2. 第二個規則:
第二條規則是確保從引入的緩存機制獲取數據比執行目標函數更快。
只有當從緩存中檢索結果的時間比從數據源檢索數據的時間快時,我們才應該引入緩存。
緩存應該比從當前數據源獲取數據快
因此,選擇合適的數據結構(如字典或LRU緩存)作為實例是至關重要的。
3.第三個規則:
第三條重要的規則是關于內存占用的,這一點經常被忽略。您是在執行IO操作(如查詢數據庫、web服務),還是在執行CPU密集型操作(如計算數字和執行內存計算)?
當我們緩存結果時,應用程序的內存占用將會增加,因此選擇適當的數據結構并只緩存需要緩存的數據屬性是至關重要的。
有時我們查詢多個表來創建一個類的對象。但是,我們只需要在應用程序中緩存基本屬性。
緩存影響內存占用
作為一個實例,考慮我們構建了一個報告指示板,它查詢數據庫并檢索訂單列表。為了便于說明,讓我們考慮一下儀表板上只顯示訂單名。
因此,我們可以只緩存每個訂單的名稱,而不是緩存整個訂單對象。通常,架構師建議創建一個具有__slots__屬性的精益數據傳輸對象(DTO),以減少內存占用。也使用了命名元組或Python數據類。
這就引出了本文的最后一節,概述了如何實現緩存的細節。
有多種實現緩存的方法。
我們可以在Python進程中創建本地數據結構來構建緩存,或者將緩存作為服務器,充當代理并為請求提供服務。
有一些內置的Python工具,比如使用functools庫中的cached_property裝飾器。我想通過提供緩存裝飾器屬性的概述來介紹緩存的實現。
下面的代碼片段說明了緩存屬性是如何工作的。
from functools import cached_propertyclass FinTech: @cached_property def run(self): return list(range(1,100))
結果,FinTech().run現在被緩存,range(1100)的輸出將只生成一次。然而,在實際場景中,我們幾乎不需要緩存屬性。
讓我們回顧一下其他方法。
1. 字典的方法
對于簡單的用例,我們可以創建/使用映射數據結構,如字典,我們可以保存在內存中,并使其在全局框架上可訪問。
有多種方法來實現它。最簡單的方法是創建一個單例樣式的模塊,例如config.py
在配置。我們可以創建一個dictionary類型的字段,在開始時填充一次。從那時起,可以使用dictionary字段來獲取結果。
2. 最近使用的算法
我們可以使用Python的內置特性LRU。
LRU代表最近最少使用的算法。LRU可以緩存函數的返回值,這些返回值依賴于傳遞給函數的參數。
LRU在遞歸CPU綁定操作中特別有用。
它本質上是一個裝飾器:@lru_cache(maxsize, typed),我們可以用它來裝飾函數。
maxsize告訴裝飾器緩存的最大大小。如果我們不想設置大小,那么只需將其設置為None。
typed用于指示是否要將輸出緩存為可以比較不同類型值的相同值。
當我們期望相同的輸入產生相同的輸出時,這是有效的。
將所有數據保存在應用程序的內存中可能會帶來麻煩。
在具有多個進程的分布式應用程序中,這可能會成為一個問題,因為不適合將所有結果緩存到所有進程的內存中。
一個很好的用例是應用程序運行在一個機器集群上。我們可以將緩存作為一種服務托管。
3.緩存即服務
第三種選擇是將緩存數據作為外部服務托管。該服務可以負責存儲所有請求和響應。
所有應用程序都可以通過緩存服務檢索數據。它就像一個代理。
假設我們正在構建一個和Wikipedia一樣大的應用程序,它將同時或并行地服務1000個請求。
我們需要一個緩存機制,并希望在服務器之間分布緩存。
我們可以使用memcache并緩存數據。
Memcached在Linux和Windows中非常流行,因為:
它可以用于實現具有狀態的記憶緩存。
它甚至可以跨服務器分布。
它使用起來非常簡單,速度很快,并且在多個大型組織中廣泛使用。
它支持自動過期緩存的數據
我們需要安裝一個叫做pymemcache的python庫。
Memcache要求數據以字符串或二進制形式存儲。因此,我們必須序列化緩存的對象,并在需要檢索它們時反序列化它們。
代碼片段展示了如何啟動和使用memcache:
client = Client(host, serialiser, deserialiser)client.set(‘blog’: {‘name’:’caching’, ‘publication’:’fintechexplained’}}blog = client.get(‘blog’)
以上就是在Python應用程序中實現緩存的方法的詳細內容了,看完之后是否有所收獲呢?如果想了解更多相關內容,歡迎來億速云行業資訊!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。