走進快取的世界(二) 快取設計

2021-09-08 19:09:45 字數 1704 閱讀 8231

主要考慮三個問題:

系統優化時有一句話必須切記:「優化無止境」,所以如果快取不是必須的,請果斷去掉,要知道越是業務上覆雜的系統,對cache的使用反而越簡單,因為對於乙個複雜、多變、歷史悠久的系統,在cache方面做過度設計會讓人深陷其中;快取的資料越多,系統的維護成本就越高,所以找準需要快取的點尤為重要。一般情況下,我們只會快取給系統帶來巨大瓶頸的io操作,在普通應用裡尤其指由top sql或者慢 sql所帶來的dao查詢;找準需要優化的sql,你可以找dba幫忙。

儲存介質的選擇: 你可以直接快取在jvm記憶體裡,也可以採用阿里雲專門的快取伺服器,如tair、memcache等;

db、檔案其實也可以做快取,他們一般快取複雜計算的中間結果,一般很少用到;如果你的快取是存放在jvm本地,那麼通常是用map實現,如果快取資料更新比較頻繁且對資料正確性比較高,那麼你需要考慮為其新增併發控制和失效策略。還有一點比較重要的就是,在集群環境下想要做到資料一致性比較困難,主動更新比較麻煩而且達不到其降低資料庫io操作的效果,所以本地快取適用場景一般是在讀訪問非常高,而寫操作極少,對資料一致性要求不是特別高的場景;如果採用專門的快取伺服器則避免了很多麻煩,阿里雲的快取系統tair,是我們經常使用的快取中介軟體,它提供了很好的併發控制和失效機制,另外還提供了不同儲存引擎可以供我們選擇,如mdb,rdb,ldb;普通的快取可以選擇mdb和rdb,兩者分別有memcache和redis的影子,其響應時間和高qps的表現都非常好,但沒有提供持久化,如果要確保資料不丟失可以採用ldb引擎儲存,它提供了對資料持久化的支援,相反犧牲了一點點效能。

快取意味著同樣的資料可能有多份並存,如果你的**沒有考慮某種情況導致了兩份資料不一致就會有問題發生。解決方法很簡單,把你的業務邏輯、**觸發情況都考慮清楚,不要遺留沒有觸底的地方。

多處使用快取會導致你的**邏輯變得異常複雜,這也是為何說在非必要的時候,建議你不要用快取的原因。

快取一致性協議就是為了解決資料一致性問題而發明的。快取一致性協議有多種,大多數計算機裝置使用的都屬於「窺探(snooping)」協議。

「窺探」的基本思想是,記憶體是共享資源,所有記憶體i/o傳輸都發生在一條共享的匯流排上,所有的處理器都能看到這條匯流排,所有處理器對記憶體的訪問請求都要經過仲裁(arbitrate):同乙個指令週期中,只有乙個處理器可以讀寫記憶體中的被快取的資料。窺探協議的思想是,快取不僅僅在做記憶體傳輸的時候才和匯流排打交道,而是不停地在窺探匯流排上發生的資料交換,跟蹤其他快取在做什麼。所以當乙個快取代表它所屬的處理器去讀寫記憶體時,其他處理器都會得到通知,以此來使自己的快取保持同步。只要某個處理器執行寫操作,其他處理器馬上就知道這塊內存在它們自己的快取中對應的段已經失效。

在直寫模式下,這是很直接的,因為寫操作一旦發生,它的效果馬上會被「公布」出去。但是如果混著回寫模式就有問題了。因為有可能在寫指令執行過後很久,資料才會被真正回寫到物理記憶體中。在這段時間內,其他處理器的快取可能會去寫同一塊記憶體位址導致衝突。在回寫模型中,簡單把記憶體寫操作的資訊廣播給其他處理器是不夠的,我們需要做的是,在修改本地快取之前,就要告知其他處理器。

搞懂了細節,就找到了處理回寫模式這個問題的最簡單方案。當處理器想寫某個快取段時,如果它沒有獨占權,它必須先傳送一條「我要獨占權」的請求給匯流排,這會通知其他處理器,把它們擁有的同一快取段的拷貝失效(如果它們有的話)。只有在獲得獨占權後,處理器才能開始修改資料——並且此時,這個處理器知道,這個快取段只有乙份拷貝,在我自己的快取裡,這樣一來就可以巧妙地避免了衝突。

帶你走進快取世界(4) 快取之緩

快取二字,從字面上分為兩塊 緩 與 存 上節我們提到的快取原理,其實是在講的乙個 存 字,如何訪問。大致回顧下是key對應的hashcode,根據hashcode作為陣列下標來訪問,因為存在hash衝突,速度雖達不到o 1 但也是非常之快。今天就說下 緩 的策略。緩,便意味著 暫時 的意思,過一段時...

走進快取的世界(一) 開篇

系列文章 對於程式設計師來說多多少少都懂一點演算法,演算法是什麼?演算法是 時間 與 空間 的互換策略。我們常常研究乙個演算法的時間複雜度和空間複雜度,如果我們有絕對足夠的時間和空間,那麼演算法就不需要了,可惜這種條件是不存在的,只是在某些情況下我們會協調兩者從而達到效能上的平衡。快取是一種 用空間...

走進快取的世界(一) 開篇

對於程式設計師來說多多少少都懂一點演算法,演算法是什麼?演算法是 時間 與 空間 的互換策略。我們常常研究乙個演算法的時間複雜度和空間複雜度,如果我們有絕對足夠的時間和空間,那麼演算法就不需要了,可惜這種條件是不存在的,只是在某些情況下我們會協調兩者從而達到效能上的平衡。快取是一種 用空間換時間 的...