這是一個針對PHP/Laravel + Redis的問題,但我確定它可以外推到其他語言/框架。優化的方式來緩存結果列表?
我正在研究一個顯示結果的應用程序(來自用戶發起的搜索或類別列表)。默認情況下,我們爲每頁分頁30個結果。
我使用Redis來緩存所有的結果,但我遇到了幾個優化問題。起初,我使用完全存儲在結果集中的對象(Products)來緩存整個結果集(因此基本上每個結果列表都是一個包含30個數據對象的巨大緩存條目)。這很好,但由於對象存儲在多個不同的緩存對象(產品可能出現在多個搜索結果以及類別中 - 然後每個對象將被默認單獨緩存),所以內存使用量激增。另外,另一個問題是,由於我們在不同的計數中允許不同的分頁,所以我們也必須緩存其他的對象計數。
那麼接下來我嘗試緩存每個頁面的對象標識列表。這大大減少了內存使用量,但每次加載頁面時,我們都必須遍歷30個對象並從緩存中檢索它們,然後重新創建它們。在每個對象大約50毫秒(這看起來很高)時,頁面加載可以累計高達1.5秒。即使我們進一步優化了對象的創建,它仍然是一個添加到頁面加載/渲染的具體時間。我們的下一個嘗試是HTML緩存(Cloudflare/Varnish等),這將要求我們重新設計應用程序的某些方面,這很好。然而,對我來說,我想知道沒有HTML緩存是他們優化這種方式的方式(或者我們正在做什麼的最佳方法是什麼?)。另外,我遇到的另一個問題是,當我知道每個請求都執行PHP腳本時,爲什麼我們不能將執行之間的對象作爲POPO(Plain Old PHP Objects)來維護?在這一點上,我似乎很愚蠢,我們仍然在2017年序列化和反序列化對象。我很想擁有一個後臺PHP應用程序,它維護所需的對象,並能夠根據需要將它們傳遞給每個腳本。
例如,從頁面加載到頁面加載,產品的變化不會很大。爲什麼每分鐘重新創建相同的產品對象數百次 - 即使它來自緩存?
愚蠢的問題警報,但在你的第二次嘗試中,你爲什麼要遍歷對象而不是一次全部獲取它們?聽起來像你的描述會節省你很多時間。值得一提的另一個解決方案是將數據轉換爲您實際需要的數據,並僅將其存儲在緩存中,而不是整個對象。你可以很容易地用例如分形。 –