Redis提供了高效能的資料存取功能,所以廣泛應用在快取場景中,既能有效地提升業務應用的響應速度,還可以避免把高併發壓力傳送到資料庫層。
因為Redis用作快取的普遍性以及它在業務應用中的重要作用,所以需要系統地掌握快取的一系列內容,包括工作原理、替換策略、異常處理和擴充套件機制。
今天我們瞭解快取的特徵和Redis快取的工作機制。
快取特徵
主要有兩個特徵:
一是在一個層次化的系統中,快取一定是一個快速子系統,資料存在快取中時,能避免每次從慢速子系統中存取資料。
二是快取系統的容量大小總是小於後端慢速系統的,我們不可能把所有資料都放在快取系統中。
Redis快取處理請求的兩種情況
把Redis用作快取時,會把Redis部署在資料庫的前端,業務應用在訪問資料時,會先查詢Redis中是否儲存了相應的資料。此時,根據資料是否存在快取中,會有兩種情況:
- 快取命中:Redis中有相應資料,就直接讀取Redis,效能非常快。
- 快取失敗:Redis中沒有相應資料,就從後端資料庫中讀取資料,效能就會變慢。
因為Redis是獨立的系統軟體,和業務應用程式是兩個軟體,因此使用Redis快取時,要在應用程式中增加三方面程式碼:
- 當應用程式需要讀取資料時,需要在程式碼中顯式呼叫Redis的GET操作介面,進行查詢;
- 如果快取缺失了,應用程式需要再和資料庫連線,從資料庫中讀取資料;
- 當快取中的資料需要更新時,也需要在應用程式中顯式地呼叫SET操作介面,把更新的資料寫入快取。
下面是一段示例程式碼:
String cacheKey = “productid_11010003”; String cacheValue = redisCache.get(cacheKey); //快取命中 if ( cacheValue != NULL) return cacheValue; //快取缺失 else cacheValue = getProductFromDB(); redisCache.put(cacheValue) //快取更新
快取的型別
按照Redis快取是否接受寫請求,可以分為只讀快取和讀寫快取。
只讀快取
只讀快取指讀請求會先經過Redis,寫操作不會經過Redis,但是會刪除相應的資料。當再次讀取資料時,會發生快取缺失,然後從資料庫中讀取並寫入快取。
讀寫快取
讀寫快取指除了讀請求會發到快取處理,寫請求也會發到快取處理。
和只讀快取不一樣的是,在使用讀寫快取時,最新的資料是在Redis中,而Redis是記憶體資料庫,一旦出現掉電或當機,記憶體中的資料就會丟失。
所以,根據業務應用對資料可靠性和快取效能的不同要求,會有兩種策略,分別是同步直寫和非同步寫回。
- 同步直寫,優先保證資料可靠性:寫請求發給快取,同時也會發給後端資料庫進行處理,等到快取和資料庫都寫完資料,才給客戶端返回。
- 非同步寫回,優先提供快速響應:所有寫請求都先在快取中處理,等到這些增改的資料要被快取淘汰時,快取再寫回後端資料庫。
只讀快取和讀寫快取的選擇
- 如果需要對寫請求進行回事,選擇讀寫快取。
- 如果寫請求很少,或者是隻需要提升讀請求的響應速度的話,選擇只讀快取。
只讀快取和使用直寫策略的讀寫快取有什麼區別?
使用只讀快取時,是先把修改寫到後端資料中,再把快取中的資料刪除。下次訪問時,再從後端資料庫讀取。
- 優點:資料庫和快取完全一致,快取中永遠保留的是經常訪問的熱點資料。
- 缺點:資料刪除後訪問會觸發一次快取缺失,從後端資料庫載入資料到快取中,這個過程訪問延時會變大。
使用讀寫快取時,是同時修改資料庫和快取中的值。
- 優點:被修改後的資料永遠在快取中存在,下次訪問直接命中快取。
- 缺點:在高併發場景下,可能會導致快取和資料庫的不一致
當資料庫或快取修改失敗時:
- 只讀快取:資料庫和快取中的資料保持一致
- 讀寫快取:可能導致快取和資料庫的不一致
總結一下:只讀快取犧牲一定效能,優先保證資料庫和快取的一致性,更適合對於一致性要求比較高的業務場景。對於資料庫和快取一致性要求不高,或者不存在併發修改同一個值的情況,使用讀寫快取比較合適,保證更好的效能。