2011-07-05 23 views
1

這個問題的標題可能會令人困惑,但問題很簡單。如何以分佈方式在memcached中使用Zend_cache?

我使用Zend_Cache和memcached作爲後端。我有兩個模塊叫做「最後的文章」和「熱門文章」。這兩個模塊的是每一個網頁,並使用類似的查詢,如:

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\ 

我的表有150萬行至今。我在上一個查詢中使用的每個字段都有索引。 我緩存最近的文章1小時,並流行4小時。我有4個Web服務器(php5/apache2)和1個數據庫服務器(mysql)。表引擎是innoDB。

問題有一段時間我的緩存在重負載中正好過期,這使得我的網站不可用,直到這些模塊再次被緩存爲止。我可以有一個新的MYSQL服務器。

但有沒有辦法以更聰明的方式處理緩存?例如server1將嘗試刷新緩存,而服務器2,3和4仍然使用緩存中的相同值。

我可以寫一些代碼來做到這一點,但我想知道是否有辦法直接用Zend_Cache做到這一點?如果有一種設計模式可以應用於我的問題?

[編輯]我想要的東西,我可以擴展到100個服務器

回答

0

我終於實現了一個繼承自Zend_Cache_Backend_Libmemcached的類 我重寫了load()方法。

我的每臺服務器都有主機名,由一組數字組成,如serv01,serv02,serv03,serv04。 主要思想是每個服務器都會認爲緩存在不同的時間到期。例如serv01會認爲緩存在實際到期前20分鐘過期,serv02將是15分鐘,serv03 10分鐘和serv04 5分鐘。

通過這樣做,我的緩存將永遠不會在每個服務器上同時刷新,並且如果一臺服務器關閉,緩存將被另一臺服務器刷新。

1

而不是依賴於緩存中到期,然後在HTTP請求中被重新填充(或者,更成問題,在幾個併發請求),爲什麼沒有緩存永不過期?

然後安排一些直到腳本來運行昂貴的查詢(只需一次!)並在後臺更新緩存。

+0

問題是查詢是每個「類別」,我有幾十萬個類別,因此每個類別有兩個查詢... +我會刷新一些沒有每天訪問的類別的事實。 – zzarbi

1

一切皆有可能:)

分佈式內存緩存(serv1,2,3,4)。

僅將serv4用於ReCache。

設置「僅限內部」網站(對用戶不可見)。

剝離「將刷新某些類別」的部分。

獲得「最多閱讀文章」 - >解析apache訪問日誌。

並重新提交到服務器4的網址。

有訪問時間,所以你只能得到所需的部分,即從2到6小時前。

分佈式內存緩存將自動填充它的值到serv1,2,3。

+0

有一件事我忘了提及我已經在服務器1,2,3,4上使用分佈式memcached另外,如果我的服務,解析日誌不工作我不會讓我的模塊刷新,如果服務器4不工作我不會讓我的模塊刷新。有4個Web服務器的整個想法是爲了適應負載,但同時在4臺服務器上有冗餘。所以如果一個人死了,我可以處理它,直到我修好它。有了解決方案,一臺服務器可能會損壞我的模塊我需要類似的東西,但當服務器4死了,服務器2將佔據他的位置... – zzarbi

1

這是您正在執行的實際查詢嗎?

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\ 

也許不是搜索高級緩存解決方案,看看爲什麼這個查詢強調你的數據庫服務器。一行1.5米的表不是不尋常的。

你嘗試添加一個LIMIT條款或只選擇您需要的列:

Select col1, col2 from table where status = 'published' and category = '' order by dateCreated LIMIT 5 

這將減少對數據庫和Web服務器顯著之間的流量。

+0

不,它不是實際的查詢。實際查詢已經過優化,看起來更像是選擇* from(選擇field1,field2 where category ='')作爲tmp按日期限制的順序5.正如A所說,在查詢本身非常輕之前,這不是一個緩慢的查詢,而是事實上,所有的緩存在同一時間到期將以指數方式強調mysql。 – zzarbi

相關問題