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是內存數據庫,一旦出現掉電或宕機,內存中的數據就會丟失。
所以,根據業務應用對數據可靠性和緩存性能的不同要求,會有兩種策略,分別是同步直寫和異步寫回。
- 同步直寫,優先保證數據可靠性:寫請求發給緩存,同時也會發給后端數據庫進行處理,等到緩存和數據庫都寫完數據,才給客戶端返回。
- 異步寫回,優先提供快速響應:所有寫請求都先在緩存中處理,等到這些增改的數據要被緩存淘汰時,緩存再寫回后端數據庫。
只讀緩存和讀寫緩存的選擇
- 如果需要對寫請求進行回事,選擇讀寫緩存。
- 如果寫請求很少,或者是只需要提升讀請求的響應速度的話,選擇只讀緩存。
只讀緩存和使用直寫策略的讀寫緩存有什么區別?
使用只讀緩存時,是先把修改寫到后端數據中,再把緩存中的數據刪除。下次訪問時,再從后端數據庫讀取。
- 優點:數據庫和緩存完全一致,緩存中永遠保留的是經常訪問的熱點數據。
- 缺點:數據刪除后訪問會觸發一次緩存缺失,從后端數據庫加載數據到緩存中,這個過程訪問延時會變大。
使用讀寫緩存時,是同時修改數據庫和緩存中的值。
- 優點:被修改后的數據永遠在緩存中存在,下次訪問直接命中緩存。
- 缺點:在高並發場景下,可能會導致緩存和數據庫的不一致
當數據庫或緩存修改失敗時:
- 只讀緩存:數據庫和緩存中的數據保持一致
- 讀寫緩存:可能導致緩存和數據庫的不一致
總結一下:只讀緩存犧牲一定性能,優先保證數據庫和緩存的一致性,更適合對於一致性要求比較高的業務場景。對於數據庫和緩存一致性要求不高,或者不存在並發修改同一個值的情況,使用讀寫緩存比較合適,保證更好的性能。