2013-01-17 60 views
0

我們有一個消息傳遞應用程序,它維護一個未讀/讀計數器。目前,我們將此值緩存一個小時,如果用戶點擊應用程序並且緩存過期,則會在數據庫表上進行計數以刷新緩存的值。在鍵/值存儲和db計數中維護計數器值的技巧

問題是,當大量的用戶一次到來並且過期的緩存時,這實際上非常常見,這給數據庫帶來了巨大的壓力,無法同時進行所有活動。

我想找到一種方法來在緩存中主動維護此計數器,因爲我們添加或刪除消息,以便用戶只會觸及緩存的值並且永不過期。新問題變成確保計數值保持同步,因爲添加或移除會觸發緩存更新的消息的系統可能會錯過一對,所以這兩個數字將不再同步。

一些,我想出的選項:

  • 做一個強制刷新每隔X更新。這對活動用戶來說很好,但活動用戶較少的人可能會有不準確的計數,並且沒有緩存過期,該計數仍會持續很長時間。

  • 有一個更新計數的後臺作業。這具有將數據庫資源花費在非活動用戶上的問題,這是低效且耗時的。

有沒有人有此類計數維護的一般建議?

+0

你應該提到你正在使用的數據庫。 – Philipp

+0

數據庫是MongoDB,緩存是Redis。然而,我主要是在尋找一般想法,而不是針對這兩家商店。 –

回答

2

我不是100%肯定你的應用程序,但如果我假設你有類似的東西,你有收到的消息和發送的消息數數的郵件客戶端,然後我有一些想法:

  1. 查看Thundering Herd的緩存思路:http://en.wikipedia.org/wiki/Thundering_herd_problem這個想法是,你並不總是使用相同的緩存過期值。介紹一些隨機性。有些將在1小時內過期,大約在58分鐘內,大約在1小時2分鐘內過期。這可以防止很多事情同時過期。

  2. 考慮使寫入端的緩存無效。換句話說,假設我向某人發送消息。當我在UI中發送它時,代碼應該使其他用戶緩存無效(它們的接收計數剛剛增加1),然後重新填充該值。換句話說,不要僅僅通過一個應用程序調用使緩存失效。使其無效將新值主動放入緩存中。

  3. 您可以按計劃播種高速緩存,但就像您所說的那樣,您將在做不必要的工作。

  4. 我注意到很多大公司正在考慮這樣的問題並將它們推送到用戶界面。您可以在一段時間內允許稍微不一致的數據,或者您做一些小技巧。例如,當他們發送一條消息時,如果你想讓它感覺「快」,只需用JavaScript(假設一個web應用程序)將它們的「發送」計數器加1即使計數器尚未保存到數據庫。

換句話說,在UI和fudge中給出即時反饋,然後異步地寫入數據並等待它完成寫入/緩存更新。

+0

很高興寫下感謝。 –