緩存技術是用來提升程序運行性能的常見手段,如你所見, 阿里巴巴、新浪微博、美團網等互聯網龍頭企業都是用緩存技術來提升自己家網站的性能。然而,任何事物都有兩面性, 緩存技術使用得當帶來的好處自然不言而喻, 但是如果使用不當, 產生的副作用也夠讓人喝一壺的。
我們寫服務器程序時,使用緩存的目的無非就是減少數據庫訪問次數降低數據庫的壓力和提升程序的響應時間, 然而根據具體的使用場景又可以派生出無數種情況, 比如說
程序頻繁讀取數據庫, 但是查詢獲得的結果卻總是相同的,這部分相同的結果是不是可以放入緩存 ?
獲得查詢結果要進行復雜的運算,非常消耗時間, 運算結果是不是可以放入緩存 ?
有一些在網站每個頁面都需要使用的數據, 比如說用戶數據, 是不是可以放入緩存 ?
還有另外不勝枚舉等等各種情況,概括起來就是那些變化不那么頻繁, 從源頭讀取又顯得耗費資源和性能的數據, 是不是都應該放入緩存 ?
既然身為行業技術風向標的淘寶、美團、新浪里面的技術大牛們都在使用緩存技術, 那么咱們自然也得跟上他們的腳步。 然而不知道大家有沒有聽到有這樣一種流傳甚廣說法:“在選擇一樣東西前,請先問一下自己,我喜歡嗎? 我適合嗎?我需要嗎?”, 具體到我們在工作中選擇使用某種技術,喜歡其實不應該是左右我們選擇某項技術的關鍵, 而合適和需要才是我們應該詳細考慮的。 這個道理自然也適合於是否使用緩存技術上面。
通常來講,狹義上的緩存僅指一些緩存軟件, 如memcached或redis; 而廣義上緩存不僅包括緩存軟件, 程序的內存空間、static變量、磁盤文件、甚至數據庫自身, 只要能用來放置臨時數據提升程序性能的都可以稱之為緩存。
我們在使用緩存技術提高程序性能時應該不僅僅把緩存的范圍局限於狹義的緩存技術, 而應該從廣義的緩存技術集合中, 結合自身程序的特點選擇一種合適的緩存模式。 比如說用戶信息數據,就算全都放session之中也未嘗不可, 難不成用戶數據會有幾十上百兆不成;比如說復雜的查詢結果臨時放置的位置,新建一個表存放或存儲在磁盤文件中亦可;比如說需要頻繁讀取的結果 , 如果是使用Java之類的語言, 那么放在一個static變量中也可以解決問題;以上這些都是緩存技術的應用實踐。
有的同學可能會提出質疑,為什么我們非要搞這么多的花樣?直接使用緩存軟件不是都能解決上面這些問題嗎? 然而並不是, 因為我們在享受緩存軟件帶來的好處的同時,卻往往忽略它帶來的副作用,而這些副作用在程序的開發的初期階段往往是不會顯現出來的, 到了開發后期或者部署上線至生產環境時,問題才有可能暴露出來。 舉一個例子來側面說明下
假如我們開發一個非常簡單的網站應用程序,只有少量的簡單數據需要存儲,那么應該選擇什么作為我們存儲數據的介質? 關系數據庫或者xml文件? 答案很顯然, xml文件存儲方案顯然要優於關系數據庫。 我們使用數據庫存儲數據, 那么勢必需要在服務器安裝數據庫軟件, 新建訪問用戶, 而且同樣的事情在開發環境和生產環境都需要做一遍, 跟環境相關的東西如數據庫地址、用戶名、密碼之類都還都需要存儲在某個配置文件中, 一來二去問題就變得相對復雜了。 而存儲在xml中就簡單的多了, 直接在項目中建個目錄存儲文件就行了, 至於xml的編程接口那是任何一種技術的標准配置,根本不用自己去實現。 這樣把程序部署至線上環境會方便的多, 不用考慮各種環境依賴問題。 而使用關系數據庫, 對於這類簡單的項目就是拿着牛刀去殺雞,真正的威力發揮不出來, 還把問題搞的復雜 。
在某些情況下, 緩存軟件和上面例子中的關系數據庫其實扮演的是同一個角色 ,緩存軟件真正的威力沒有發揮出來, 卻把程序搞的相對復雜,這不是得不償失的做法嗎?
因此, 在決定使用緩存軟件前, 一定先確定上面所提的廣義的緩存都沒有辦法滿足需求了,屆時再使用緩存軟件才能將它能發揮的價值最大化,或可抵消使用它帶來的副作用。