2011-09-01 70 views
0

我們現在使用Redis作爲我們的Django應用程序的內存緩存(我們以前使用過memcached,性能沒有太大的區別,因爲我們使用Redis,因爲磁盤轉儲功能)。Django緩存性能

問題是,在我看來,Django緩存的性能很糟糕。我們認爲,有102個緩存命中(沒有丟失),它需要81毫秒(只是緩存部分,用Django調試工具欄測量)。在我看來 - 這是非常多的時間。我知道,對數據庫進行查詢將花費10倍的時間(甚至100倍),但即使這樣,緩存性能也不好。

我們在不同的主機上運行Redis(和之前的memcached),在本地網絡中與其他服務器連接。

有什麼辦法可以調整Django中的緩存性能嗎?

+0

難道這81毫秒花費從緩存中取出東西嗎?還是包含其他內容?你在緩存什麼? HTML片段還是酸洗複雜的對象或模型實例? –

+0

如果81 ms是完整請求,直到您在遠程主機上收到響應,那麼時間確實相當不錯。:) –

+0

81毫秒僅用於獲取緩存內容。完整請求(緩存,不可緩存的SQL,模板解析等)大約需要250-300 ms。我們緩存不同的東西,從小塊文本(多數)到更大的HTML塊。 – ThomK

回答

2

問題很可能是每個頁面需要檢索的項目數量,而不是緩存本身的性能。 102緩存呼叫意味着網絡延遲時間浪費了很多時間。在完全控制代碼的情況下,你可以用多線程或流水線來解決這個問題,但在這種情況下,你沒有這個選擇 - 使用框架意味着以更低性能爲代價獲得更簡單的代碼。

最簡單的修復方法可能是將redis緩存移動到Web服務器上 - 本地請求速度更快。這會使緩存失效變得複雜化,但是您可以通過複製來修復這個問題 - 要麼執行所有寫入主節點的操作,並從本地從屬設備讀取數據,以便所有節點具有相同的緩存,或者使用用於複製當你需要使一個對象失效時,del命令給所有的從站。

要看的另一件事是,如果性能實際上是一個問題。根據個人用戶的體驗,300ms加載頁面並不算太差。如果這意味着您無法在所有用戶中處理超過3頁的頁面,這只是一個問題 - 在這種情況下,不可能出現瓶頸是網絡延遲而不是CPU或本地I/O。

2

主機之間的網絡延遲可能是原因。在本地主機上與Redis進行簡單通信對於小鍵和值需要+ 200us(微秒)。 Memcached也通過網絡進行通信,因此會遇到同樣的延遲問題。根據您分享的號碼,每個請求大約需要800us。

並非所有緩存都通過網絡進行通信。更快的方法是將緩存的一部分直接存儲到進程的內存中。如果你使用多個網絡服務器,那麼他們每個人都有自己的緩存,但如果你一直路由請求(通過IP,用戶名等),你可以減少緩存未命中。假設您已將數據庫移至單獨的主機,您的網絡服務器上可能會有可用的磁盤循環。

如果您想嘗試此方法,請考慮使用DiskCache,這是一個Apache2許可的磁盤和文件支持緩存庫,採用純Python編寫,並與Django兼容。 DiskCache包含許多cache benchmarksDjango cache benchmarks。鍵和小值被存儲器映射到Django進程內存中,因此檢索速度非常快(比您的設置快3-12倍)。如基準測試中所示,「get」延遲甚至比Memcached(本地主機上)少。還有一些可調的settings,您可以根據自己的喜好進行自定義。