如何設計網站的緩存?

set哪些key,存儲什麼value.依據是什麼?

應該存什麼東西,資料庫的表都要有對應的緩存嗎?

例如,新浪微博的緩存存了什麼呢?wordpress 的文件緩存存什麼?


一個一個問題來回答

1.set哪些key,存儲什麼value.依據是什麼?

這個涉及到緩存的本質問題,我們為什麼需要緩存?緩存從本質上來說,是一種犧牲數據的實時性以換取效率的方式。

舉個例子,一個站點有1000個用戶,每個用戶都記錄他們的在線時長,然後在網站的某處顯示站點所有用戶的在線時長之和,你會怎麼做?第一個想到的肯定是每次都去查詢資料庫,取出所有的用戶登錄時長,再相加。

但很顯然,這個做法非常不明智,因為也許這個結果並沒有嚴格的實時性要求,我們完全可以將結果放入緩存中。步驟類似這樣:

從緩存取數據-&>(若緩存無記錄,則從資料庫查詢計算,放入緩存)-&>將緩存結果輸出

當然對於不同的業務需求,會有不同的緩存策略。其中又會涉及到「命中率」的概念,這扯起來太複雜了,簡單的說,一些緩存數據需要兼顧效率和實時性,我們取緩存的時候,會甄別這些數據是否還可以使用(是否過期,是否已經不能滿足業務需求),如果緩存里的無效數據太多,則說明我們的緩存策略有問題,這非但不能發揮緩存的作用,反而拖累整個系統的效率。

至於你問的,set哪些key,這完全取決於你這個程序員駕馭的能力,比如一個複雜的sql語句,你可以將這個sql語句本身md5之後作為這個sql運行結果的緩存的key。再比如,上面提到的那個例子,你可以取一個任意的名稱作為它的key,只要你自己能理解,只要這個名稱唯一。

2.應該存什麼東西,資料庫的表都要有對應的緩存嗎?

這個不好回答,因為要根據你的業務模型而定,如果你所有的數據都不要求實時性,緩存當然也可以。

但這個會牽涉到一個問題,你調用緩存數據就一定比你調用原來的數據快嗎?

比如你提到的wordpress,一般是以「文件」作為緩存載體,但文件讀寫存在IO瓶頸,你把所有的查詢(無論複雜或是簡單)都放到文件上,也許效率還比不上沒有緩存的時候。

除非,你的緩存載體是內存,例如你使用Memcache這樣的傢伙,所有的數據都緩存到了內存里,也許你的效率會有一個質的提高。

但這時候你又不禁要問,這樣的做法是不是太多餘了,為什麼不把Memcache當作資料庫來使用?

是的,所以你這個問題的最好解答是:還不如用nosql。

3.例如,新浪微博的緩存存了什麼呢?wordpress 的文件緩存存什麼?

新浪微博這樣業務模型過於龐大的玩意,不是一兩句說得清楚的。

wordpress一般是將不會輕易改變(一旦改變就會更新緩存)的數據混合模板存到文件里,這樣它就不需要再去查詢資料庫,只讀取模板就可以顯示出來。


  1. 存什麼要看命中率,命中率低的東西不值得存。緩存的主要目的還是快,所以要保證緩存以後的確會快。粒度問題要平衡讀取次數和存儲效率。存儲的失效策略是存什麼這個問題的難點,平衡效率和失效邏輯的複雜度往往是要考慮的主要問題。

  2. 存的東西不應該和表有什麼關係,緩存組裝好的東西比映射表結構要高效,如組合好的模型和渲染好的頁面片段甚至整個頁面。

  3. 不同類型的應用存的當然不同,這個問題不需要回答。


被緩存的數據一般具有以下特點:

1、經常被訪問 不經常被訪問的數據,即使緩存了對系統的性能吞吐也沒太大的改善,沒什麼必要做緩存,直接訪問DB、File、其他系統即可

2、改動不頻繁 如果一個數據改動很頻繁,緩存的數據很容易就過期或者失效,保證數據一致性成本很高,命中率也很難上去,緩存的效果也不會好

3、時效性不強 業務上要能容忍緩存失效前數據的不準確性

被緩存的數據也不是任何場景都可以用,比如緩存的產品價格,在產品展示的時候可以取緩存的數據,但是在結算的時候就不能用,要取資料庫的值。


key保證唯一性,value可以是任何數據

不是所有的數據表都有各自對應的緩存,通常的緩存都是直接緩存一種結果,而不是單個表的鍵值,那樣削弱了緩存的作用~

新浪微博的緩存技術沒有看到相關資料,但應該是比較複雜的分散式,畢竟是那種量級的應用,一旦緩存失效很容易引起雪崩效應~


同意樓上的觀點

第一,看你的時效性,如果對時效性有要求的話,可以考慮memcache,畢竟是在內存中的

第二,看你的容量和命中率吧


有資料庫緩存

內存緩存

文件依賴緩存:xml或者html等

瀏覽器端緩存

等。。


看你的需求了,比如你可以把最簡單常用的用戶資料做一些key value

你也可以緩存整張頁面


推薦閱讀:

求教大神瀏覽器是根據什麼決定from disk cache 與 from memory cache?
cdn的緩存數據是如何實現分片的,如何有效的實現各分片的存儲及刪除?
`a = false` 和 `if (a) { a = false; }` 哪個快?
對於平均大小在 10M 至 50M 左右的文件下載服務來說,有沒有什麼成熟的緩存方案呢?
為什麼從Intel Core i系列開始加入L3緩存,而不是使用更大的L2緩存?

TAG:網站架構 | 緩存 |