首頁>Club>
6
回覆列表
  • 1 # 會點程式碼的大叔

    快取當然不是萬能的。

    在架構中引入快取,很大程度上解決專案效能問題、緩解資料庫壓力的同時,也會面臨諸多問題,在架構設計和程式碼實現的過程中,如果有考慮不到的地方,資料庫依然會產生問題,整個專案也產生問題。

    在大多數場景下,我們經常這樣使用快取:應用伺服器訪問快取。在快取中沒有找到需要的資料,則訪問資料庫。(一些場景或極端的做法,不再訪問資料庫,這裡不考慮這種情況)資料發生變化後,需要刪除或重新整理資料庫中的資料。

    讓我們看看每一步中,都會對架構帶來什麼樣的挑戰。

    第一步,應用伺服器訪問快取。

    架構中引入快取,無疑是加重了架構的複雜性、增加了程式碼的複雜程度,這些都不細說了。我認為這一步最主要的兩個問題:

    需要保證快取的高可用性,對快取依賴程度很高的系統,快取一掛,資料庫很有可能瞬間被打爆;

    不是所有資料都適合放在快取中。

    第二步,快取中沒有找到資料需要訪問資料庫,帶來的問題會更多:

    快取穿透:如果一個key值本身就不存在,那麼每一次都會查詢資料庫,也就是常說的【快取穿透】;有些專案的做法是如果這個key在資料庫也查詢不到的話,就把“key-空”寫入到快取中,並設定一個過期時間;但如果受到惡意攻擊,每次都會模擬一個不存在的key向服務發起請求,這時每次請求依然會訪問到資料庫,這個問題可以使用布隆過濾器,將可能存在的資料Hash到一個足夠大的bitmap上,並可以確定某個key一定不存在。

    快取雪崩:大部分時候快取是要設定過期時間的,如果快取的過期時間都設定成一樣,那麼到了時間之後,全部/大部分快取過期失效,下一秒所有的請求都會訪問資料庫,那麼資料庫可能因為訪問量多大導致“崩潰”,這就是【快取雪崩】;解決這個問題的方法,就是讓過期時間不那麼一致,比如一批快取設定成一個小時候過期,或者凌晨12點過期,那麼可以在設定過期時間的時候,每條快取的過期時間在此基礎上,隨機地提前或延遲一段時間,如果隨機1-6000秒。

    第三步,資料發生變化後,需要刪除或重新整理資料庫中的資料,這也就是保持資料庫和快取的資料一致性的問題。

    資料發生變化後,對於快取的操作通常有幾種方法:等待快取自動過期、更新快取和刪除快取,但是在高併發的場景下,依然可能會有問題:

    等待快取自動過期:在快取過期之前,資料庫和快取中的資料是不一致的;

    先更新資料庫,再更新快取;或先更新資料庫,再刪快取;也是類似,高併發的時候,容易造成資料不一致;

    所以可以看出,任何架構、軟體、框架,在解決一部分問題的同時,也會帶來其他的問題;我們需要根據實際的場景和團隊的開發水平,進行合理的設計。

  • 中秋節和大豐收的關聯?
  • 那些坐牢的,後來改過自新了嗎?