2010-09-29 58 views
5

我目前正在開發應用程序的基礎,並尋找優化性能的方法。我的設置基於the CakePHP framework,但我相信我的問題與任何技術棧有關,因爲它涉及到數據緩存。用於緩存相關數據的模式

我們來看一個典型的作者後關係,它由我的db中的2個表格表示。當我查詢特定博客文章的數據庫時,同時CakePHP中的內置ORM功能還獲取帖子的作者,帖子的評論等。所有這些都作爲一個大屁股嵌套數組返回,我使用該博客文章的唯一標識存儲在緩存中。

在更新博客文章時,它是通過子播放銷燬帖子的緩存,並使用下一個請求重新生成緩存。

但是,如果不是主實體(本例中爲博客文章)得到更新,而是更新了一些相關數據,會發生什麼?例如,評論可以被刪除,或作者可以更新他的頭像。是否有任何方法(模式)可以考慮用於跟蹤相關數據的更新,並相應地將更新應用於緩存?

我很好奇聽到您是否遇到過類似的挑戰,以及您如何設法克服障礙。隨意提供一個抽象的視角,如果你在你的末端使用另一個堆棧。無論如何,您的意見非常感謝,非常感謝!

回答

2

這是相當簡單的,緩存條目可

  • 添加
  • 破壞

相關時,您應該小心破壞緩存條目的數據變化(所以除了應用層更新數據時,您應該在更新某些表時銷燬某些類型的緩存條目;通過對其進行硬編碼來跟蹤依賴關係)。

如果您想要做出明智的決定,您可以讓緩存對象聲明其依賴關係,並緩存數據庫表的上次更新時間。

然後,你可以

  • 取緩存數據,檢查依賴性,
  • 的相關數據庫表中獲得更新的時間和情況
  • 記錄是陳舊的(一個表,你的大屁股的更新時間緩存項取決於稍後是緩存項的時間)將其刪除並從數據庫獲取新數據。

你甚至可以將上述內容整合到你的持久層中。

編輯:
當然,以上是當你想要有一致的緩存。有時候,對於某些數據,您可以放鬆一致性要求,並且有些情況下簡單的TTL會足夠好(例如,如果您有1秒的ttl,那麼您應該主要在用戶面前解決問題,並且可以提供幫助數據處理;以及更高的時間,你可能仍然可以 - 例如,假設你正在緩存國家ISO代碼列表;你的應用程序可能是完全可以,如果你說我們緩存這個86400秒)。

此外,您還可以跟蹤的呈現給用戶的信息的時間,例如

  • 假設用戶已經從緩存中看到數據A和我們知道這個數據的創建/在時間t1
  • 修改
  • 用戶對數據A進行更改(並使數據B)並提交更改
  • 然後應用層可以檢查數據A是否仍然在數據庫中(如果用戶做出決定的高速緩存數據和/或變化確實是新鮮的)
  • 如果它是新鮮那麼有衝突,用戶應該確認更改

這有來自DB數據A的額外的讀的成本,但它只是在寫發生。 此外,衝突的發生不僅是因爲緩存,還因爲多個用戶試圖更改數據(即與鎖定策略有關)。

+0

我擔心這是唯一的出路,但是要感謝您確認,因爲您設法使它聽起來更「可行」:-) 所以缺點是每個視圖有很多自定義代碼,但是好處在於,這仍然可以輕鬆切換緩存後端。 Thx也爲鎖定功能提供了額外的見解,這將用於v2 :-) – Shahways 2010-09-30 18:22:02

+0

對於更復雜的概念性概述和一些實際問題,我發現這個閱讀很有趣http://highscalability.com/blog/2010/9/ 30 /實和 - 位點的故障引起的逐復弱interact.html – Unreason 2010-09-30 21:39:27

1

memcached的一種方法是使用標籤(http://code.google.com/p/memcached-tag/)。例如,你有你的Post「大屁股嵌套數組」可以說,它包含了autor信息,帖子本身,並顯示在首頁和邊欄中的某個框中。因此,如果有人更改了「作者信息」,您可以使用標記{author-id}刷新每個緩存條目,現在可以獲取標籤:frontpage,{auhothor-id},側邊欄,{post-id}。但那只是一個解決方案,並且只適用於支持標籤的緩存後端,例如不支持APC(afaik)。希望這給了你一個例子。

+0

Hannes,thx爲了指出這一點。我看過memcached,但沒有意識到這個選項存在。 – Shahways 2010-09-30 18:19:48