我們試圖在寫入數據庫時更新memcached對象,以避免在插入/更新後必須從數據庫讀取它們。Memcached,鎖定和競爭條件
對於我們的論壇帖子對象,我們有一個包含查看帖子次數的ViewCount字段。
我們擔心我們正在通過更新memcached對象來引入競爭條件,因爲可以在服務器場的另一臺服務器上同時查看同一帖子。
任何想法如何處理這些類型的問題 - 似乎需要某種鎖定,但如何在服務器場中的服務器之間可靠地執行此操作?
我們試圖在寫入數據庫時更新memcached對象,以避免在插入/更新後必須從數據庫讀取它們。Memcached,鎖定和競爭條件
對於我們的論壇帖子對象,我們有一個包含查看帖子次數的ViewCount字段。
我們擔心我們正在通過更新memcached對象來引入競爭條件,因爲可以在服務器場的另一臺服務器上同時查看同一帖子。
任何想法如何處理這些類型的問題 - 似乎需要某種鎖定,但如何在服務器場中的服務器之間可靠地執行此操作?
如果您處理的數據不一定是需要需要實時更新,而對於我來說,查看計數就是其中之一,那麼您可以將expires字段添加到存儲在memcache中的對象。
一旦到期發生,它將返回到數據庫並讀取新的值,但在此之前它將保持獨立。
當然,對於您可能希望更新頻率更新的新帖子,您可以對此進行編碼。
Memcache只在其實例中存儲了一個對象的副本,而不是其中的很多副本,所以我不擔心對象鎖定或任何事情。這是爲了處理數據庫,而不是緩存。
編輯:
Memcache中並沒有保證,當你得到,並從您的數據將不會打一頓豐盛的服務器上設置這一點。
從內存緩存文檔:
比賽條件和陳舊的數據
有一點要記住,你設計你的應用程序緩存數據,是如何處理競爭條件和偶爾的陳舊數據。
假設您緩存最新的五條評論,以便在應用程序的側邊欄上顯示。您決定只需每分鐘刷新一次數據。但是,您忽略了記住此邊欄顯示每秒渲染50次!因此,一旦60秒週轉並且高速緩存到期,突然有10多個進程運行相同的SQL查詢來重新填充該高速緩存。每次緩存過期時,都會導致突發的SQL通信量突然增加。
更糟糕的是,您有多個進程更新相同的數據,而錯誤的進程約會緩存。那麼你有過時的,過時的數據浮動。
一個人應該留意填充或重新填充緩存時可能出現的問題。請記住,檢查memcached,獲取SQL以及存儲到memcached中的過程根本不是原子!
memcached操作是原子操作。服務器進程將排隊請求並在進入下一個請求之前完全服務每個請求,因此不需要鎖定。
編輯: memcached有一個增量命令,其中是原子。您只需將計數器作爲單獨的值存儲在緩存中即可。
真的,但我這種情況下,我們將獲得該項目,增加ViewCount和再次將它,並作爲內森也說,這不是一個原子操作 – Micael 2009-10-23 06:52:47
我在想 - 解決方案可以單獨存儲Postcount從Post對象,然後做一個INCR。當然這需要在顯示信息時從memcached讀取2個獨立的值。
我們在我們的系統中遇到過這個問題。我們改性得到這麼
當我們實現這個時,我們的數據庫負載下降了100倍。
function get($key) {
$value=$m->get($key);
if ($value===false) $m->set($key, 'g', $ttl=8);
else while ($value==='g') {
sleep(1);
$value=$m->get($key);
}
return $value;
}
更好地使用cas()插入set() http:// php達網絡/手動/ RU/memcached.cas.php – Hett 2015-08-20 12:03:30
問題是,我們希望視圖計數(在這種情況下,但有其他情況下有同樣的問題)需要實時更新 - 您單擊帖子,視圖計數增加。我們也希望緩存對象儘可能長時間生活,當然這是出於性能方面的考慮。 – Micael 2009-10-22 18:29:20
你不能保證你想要做的事情。 memcache爲您提供的是可伸縮性,而非原始性能。 – Nathan 2009-10-22 18:43:42