2012-08-08 62 views
4

只是尋找一條建議。在我們的一個網頁上,我們有一個辯論/論壇網站。每次用戶請求辯論頁面時,他/她都會得到所有主題的列表(以及答案的數量等)。在PHP中緩存辯論/論壇條目

當用戶請求特定的主題/線程時,該線程的所有答案都會以用戶名,用戶圖片,年齡以及答案海報中的totalt論壇帖子的數量顯示給用戶。

當訪問頁面時,所有內容當前通過使用MySQL查詢來檢索。但是,這種情況開始變得非常緩慢(特別是對於大型線程,+ 3000個答案)。

我想以某種方式緩存辯論條目,以加快這個過程。但問題是,如果我緩存它自己的條目,帖子數量等(當然是動態的),並不總是最新的。

當這樣的東西被更新時,是否有任何智能的緩存頁面/回收它們的方法? :)

由於提前, 菲捨爾

回答

2

您應該創建一個標籤或基於它的數據高速緩存的名稱。

例如,對於名爲傑克的帖子後您可以創建名稱的MD5,這將給你的標籤49fec15add24931728652baacc08b8ee

現在緩存內容和一切與此帖子對標籤49fec15add24931728652baacc08b8ee。當帖子更新或添加評論時,請轉至緩存並刪除與49fec15add24931728652baacc08b8ee相關聯的所有內容。

現在沒有緩存,當下一個訪問者到達新的帖子時,它將被重建。

您可以通過爲每個帖子設置多個標籤來進一步細分。例如,您可以爲評論和答案添加標籤,添加評論時刪除評論標籤,但不包括答案標籤。這減少了重建緩存時服務器必須執行的工作,因爲現在只有註釋缺失。

有許多庫和框架可以幫助你做到這一點。

傑克

編輯

我會用文件來存儲數據,更具體頁面的HTML輸出。然後你可以這樣做:

if(file_exists($tag)) 
{ 
    // Load the contents of the cache file here and output it 
} 
else 
{ 
    // Do complex database look up and cache the file for later 
} 

請記住像Zend這樣的框架內置了這樣的東西。我會認真考慮使用框架。

+0

感謝您的輸入。聽起來像是一個很好的做法。我將爲此設計一個數據庫方案。你認爲在MySQL中存儲緩存會是一個好主意 - 或者我應該考慮以其他方式存儲緩存的條目(因爲我將要重寫我的代碼,實現緩存 - 機制)!? – fischer 2012-08-08 15:26:25

+0

我會使用類似文件的文件。看我的編輯。 – 2012-08-08 17:47:05

0

有趣的話題!

我首先要看的是優化您的數據庫 - 即使您必須花錢升級硬件,它將比引入緩存更容易,更便宜 - 移動部件更少,可能出錯的部件更少...

如果你不能從數據庫中獲得更多的性能,那麼接下來我要考慮的就是對數據進行一些標準化。例如,維護一個「reply_count」列,而不是針對每個主題計算回覆。這很醜陋,但卻引入了更少機會出錯 - 有點運氣,您可以本地化數據訪問層中的所有邏輯。

我會考慮的下一個選項是緩存頁面。例如,如果您擁有合理的流量級別,只是將「辯論頁面」緩存30秒鐘,應該可以大大減少數據庫的負載,即使它出錯了,因爲您正在緩存整個頁面,它會在下一次頁面失效時自行排列。在大多數情況下,緩存整個頁面是可以的 - 如果在過去的30秒內出現新帖子並且您沒有在頁面上看到它,那麼世界並不是世界末日。

如果您確實必須在頁面上提供更多「最新」內容,則可以在數據庫訪問級別引入緩存。過去,我已經構建了一個數據庫訪問層,該層根據關於將結果緩存多久的硬連線邏輯來緩存SQL查詢的結果。在我們的例子中,我們構建了一個函數來調用數據庫,它允許您指定查詢(例如,獲取用戶的帖子),一組參數(例如用戶名,日期來源)和緩存持續時間。數據庫訪問功能將根據查詢和參數緩存緩存持續時間的結果;如果高速緩存持續時間已過,則會刷新高速緩存。 這個方案相當有缺陷 - 作爲最終用戶,你很少會注意到由於緩存而產生的怪異現象,並且由於我們將緩存時間保持得相當短,所以它們都很快排序。

通過緩存內容片段來構建頁面是可能的,但很快就變得非常複雜。由於不同的緩存策略,創建一個對最終用戶沒有意義的頁面非常容易 - 「未讀帖子」不會增加故障中的帖子數量,因爲「摘要」和「詳情」。