<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis 有幾種緩存讀寫策略?

          共 7013字,需瀏覽 15分鐘

           ·

          2024-04-12 01:18

          引言:在某一天面試的時(shí)候,小 x  被問(wèn)到 Redis 三種緩存讀寫的策略,他懵了,原因是簡(jiǎn)歷上明明是寫著熟悉 Redis,因此面試官可以隨意向任何一個(gè)方向進(jìn)行開火,大家要注意從小點(diǎn)切入,除非自己是完全能夠掌握這門技術(shù)的,本文將帶你去了解三種常用的緩存讀寫策略的優(yōu)缺點(diǎn)和使用場(chǎng)景。

          題目

          Redis 三種高效緩存讀寫策略你了解嗎?

          推薦解析

          旁路緩存模式(Cache Aside Pattern)

          旁路緩存是最常見(jiàn)的緩存讀寫模式,適用于讀多寫少的使用經(jīng)常。服務(wù)端以數(shù)據(jù)庫(kù)比如 MySQL 為主,Redis 為輔,進(jìn)行存儲(chǔ)。

          寫操作流程

          1)先更新數(shù)據(jù)庫(kù)

          2)刪除 Redis 中的緩存

          讀操作流程

          1)嘗試從緩存中讀取數(shù)據(jù),讀取到數(shù)據(jù)就直接返回

          2)緩存中讀取不到,從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)

          3)讀取完畢后,將數(shù)據(jù)放入緩存

          緩存不一致可能的場(chǎng)景(先刪后更)

          假如先刪除緩存,再更新數(shù)據(jù)庫(kù),大概率會(huì)造成緩存不一致。線程 1 把 Redis 中 x 數(shù)據(jù)刪除,此時(shí)線程 2 發(fā)現(xiàn)緩存中沒(méi)有數(shù)據(jù),從數(shù)據(jù)庫(kù)讀取,而線程以此時(shí)又把數(shù)據(jù)庫(kù)中的 x 數(shù)據(jù)更新,因此線程 2 讀取到的就是舊數(shù)據(jù),造成了緩存不一致的情況。

          緩存不一致發(fā)生概率小

          被推薦的作法,就是上文講過(guò)的,先更新數(shù)據(jù)庫(kù),再刪除緩存。

          可能不一致的場(chǎng)景如下

          1)緩存中 X(數(shù)據(jù)) 不存在(數(shù)據(jù)庫(kù) X = 1) 2)線程 1 讀取數(shù)據(jù)庫(kù),得到舊值(X = 1) 3)線程 2 更新數(shù)據(jù)庫(kù)(X = 2) 4)線程 2 刪除緩存 5)線程 1 將舊值寫入緩存(X = 1) 6)最終 X 的值在緩存中是 1(舊值),在數(shù)據(jù)庫(kù)中是 2(新值),也發(fā)生不一致。

          此場(chǎng)景需要滿足:1)緩存失效 2) 讀寫請(qǐng)求同步對(duì)一個(gè)數(shù)據(jù)進(jìn)行并發(fā)操作 3)更新數(shù)據(jù)庫(kù)+刪除緩存的時(shí)間大于讀取和寫入緩存的時(shí)間,也就是說(shuō)寫操作時(shí)間大于度操作時(shí)間,因?yàn)榫彺孢@塊可以不計(jì)入,理論發(fā)生概率是很小的。

          旁路緩存優(yōu)缺點(diǎn)

          優(yōu)點(diǎn)

          1)提高數(shù)據(jù)訪問(wèn)速度

          2)減少主存訪問(wèn)

          3)提高并發(fā)性

          缺點(diǎn)

          1)存在緩存數(shù)據(jù)庫(kù)不一致情況

          2)首次請(qǐng)求數(shù)據(jù)一定不在緩存(可以緩存預(yù)熱結(jié)合定時(shí)任務(wù))

          3)寫操作頻繁會(huì)導(dǎo)致緩存被頻繁刪除,影響緩存命中率。(可以加分布式鎖,保證更新數(shù)據(jù)庫(kù)同時(shí)更新緩存。或者直接設(shè)置一個(gè)較短的過(guò)期時(shí)間)

          旁路緩存示例代碼

          import java.util.HashMap;
          import java.util.Map;

          public class CacheAsideExample {
              // 模擬緩存
              private static Map<String, String> cache = new HashMap<>();

              // 模擬數(shù)據(jù)庫(kù)或數(shù)據(jù)源
              private static Map<String, String> dataSource = new HashMap<>();

              // 從緩存中獲取數(shù)據(jù)
              public static String getDataFromCache(String key) {
                  return cache.get(key);
              }

              // 從數(shù)據(jù)源中獲取數(shù)據(jù)
              public static String getDataFromDataSource(String key) {
                  return dataSource.get(key);
              }

              // 將數(shù)據(jù)存入緩存
              public static void putDataIntoCache(String key, String value) {
                  cache.put(key, value);
              }

              // 刪除緩存中的數(shù)據(jù)
              public static void deleteDataFromCache(String key) {
                  cache.remove(key);
              }

              // 從數(shù)據(jù)源中加載數(shù)據(jù),并存入緩存
              public static String loadData(String key) {
                  String data = getDataFromDataSource(key);
                  if (data != null) {
                      putDataIntoCache(key, data);
                  }
                  return data;
              }

              public static void main(String[] args) {
                  // 設(shè)置數(shù)據(jù)源
                  dataSource.put("key1""value1");
                  dataSource.put("key2""value2");

                  // 從緩存中獲取數(shù)據(jù),如果不存在則從數(shù)據(jù)源中加載
                  String data1 = getDataFromCache("key1");
                  if (data1 == null) {
                      data1 = loadData("key1");
                  }
                  System.out.println("Data1: " + data1);

                  // 從緩存中獲取數(shù)據(jù),如果不存在則從數(shù)據(jù)源中加載
                  String data2 = getDataFromCache("key2");
                  if (data2 == null) {
                      data2 = loadData("key2");
                  }
                  System.out.println("Data2: " + data2);

                  // 刪除緩存中的數(shù)據(jù)
                  deleteDataFromCache("key1");

                  // 從緩存中獲取數(shù)據(jù),如果不存在則從數(shù)據(jù)源中加載
                  String data3 = getDataFromCache("key1");
                  if (data3 == null) {
                      data3 = loadData("key1");
                  }
                  System.out.println("Data3: " + data3);
              }
          }

          讀寫穿透(Read/Write Through Pattern)

          讀寫穿透策略將 Redis/Memcached 視為數(shù)據(jù)存儲(chǔ)的主要地方,也就是說(shuō)將緩存充當(dāng)原本的數(shù)據(jù)庫(kù),利用 Cache 服務(wù)負(fù)責(zé)將數(shù)據(jù)讀取并寫入數(shù)據(jù)庫(kù)(MySQL、Oracle等)。

          寫操作流程

          1)先查詢緩存,緩存不存在,更新數(shù)據(jù)庫(kù)

          2)緩存存在,先更新緩存,利用 Cache 服務(wù)同步更新數(shù)據(jù)庫(kù)。

          讀操作流程

          1)從緩存讀取數(shù)據(jù),讀取到返回

          2)緩存讀取不到,從數(shù)據(jù)庫(kù)加載后寫入緩存并返回。

          和旁路緩存相反,讀寫穿透,主緩存從數(shù)據(jù)庫(kù)。

          異步緩存寫入(Write Behind Pattern)

          只更新緩存,不利用 Cache 服務(wù)更新數(shù)據(jù)庫(kù),可以利用消息隊(duì)列,先存放要消費(fèi)的信息,然后可以異步批量的更新數(shù)據(jù)庫(kù),一般不使用,但數(shù)據(jù)庫(kù)的緩沖池機(jī)制是這種策略的一個(gè)實(shí)現(xiàn),

          適用場(chǎng)景:數(shù)據(jù)經(jīng)常變化,一致性要求不高(可以延時(shí)同步),比如 PV、UV、點(diǎn)贊量。

          其他補(bǔ)充

          魚聰明 AI 的回答:

          魚聰明 AI 地址:https://www.yucongming.com/

          1)旁路緩存(Cache Aside)

          1.1)優(yōu)點(diǎn)

          • 簡(jiǎn)單易實(shí)現(xiàn),適用于小規(guī)模系統(tǒng)。
          • 緩存數(shù)據(jù)不會(huì)過(guò)期,不會(huì)出現(xiàn)緩存雪崩。

          1.2)缺點(diǎn)

          • 數(shù)據(jù)一致性問(wèn)題,需要應(yīng)用程序主動(dòng)更新緩存。
          • 緩存數(shù)據(jù)可能過(guò)期,導(dǎo)致緩存擊穿。

          1.3)使用場(chǎng)景

          • 適用于讀多寫少的場(chǎng)景。
          • 數(shù)據(jù)更新頻率不高,對(duì)數(shù)據(jù)實(shí)時(shí)性要求不高的場(chǎng)景。

          2)讀寫穿透(Cache Through)

          2.1)優(yōu)點(diǎn)

          • 數(shù)據(jù)一致性較好,不會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。
          • 緩存數(shù)據(jù)不會(huì)過(guò)期,不會(huì)出現(xiàn)緩存雪崩。

          2.2)缺點(diǎn)

          • 需要保證數(shù)據(jù)源的可靠性和性能。
          • 對(duì)于大規(guī)模系統(tǒng),可能增加數(shù)據(jù)源的壓力。

          2.3)使用場(chǎng)景

          • 適用于數(shù)據(jù)源更新頻率高,對(duì)數(shù)據(jù)實(shí)時(shí)性要求高的場(chǎng)景。
          • 數(shù)據(jù)源具有較好的性能和可靠性。

          3)異步緩存寫入(Write Behind)

          3.1)優(yōu)點(diǎn)

          • 減少對(duì)數(shù)據(jù)源的頻繁寫入,提高性能。
          • 可以緩解瞬時(shí)寫入壓力,提高系統(tǒng)穩(wěn)定性。

          3.2)缺點(diǎn)

          • 數(shù)據(jù)一致性可能受影響,存在一定的數(shù)據(jù)丟失風(fēng)險(xiǎn)。
          • 需要額外的機(jī)制來(lái)處理數(shù)據(jù)更新失敗的情況。

          3.3)使用場(chǎng)景

          • 適用于寫入頻率高,對(duì)數(shù)據(jù)實(shí)時(shí)性要求不高的場(chǎng)景。
          • 對(duì)數(shù)據(jù)丟失一定容忍度的場(chǎng)景。

          在實(shí)際應(yīng)用中,根據(jù)系統(tǒng)的特點(diǎn)和需求,可以選擇合適的緩存讀寫策略來(lái)提高系統(tǒng)性能和穩(wěn)定性。

          歡迎交流

          在閱讀完本篇文章后,你應(yīng)該對(duì) Redis 的三種緩存讀寫策略有了一定了解,一般采用第一個(gè)策略進(jìn)行讀寫,其他兩種策略了解即可,在文末有三個(gè)問(wèn)題將會(huì)檢驗(yàn)本章的學(xué)習(xí),歡迎在評(píng)論區(qū)發(fā)表意見(jiàn)。

          1)旁路緩存策略中,如何解決緩存數(shù)據(jù)過(guò)期和緩存擊穿的問(wèn)題?

          2)讀寫穿透策略中,如何確保數(shù)據(jù)源的可靠性和性能,以及如何處理數(shù)據(jù)源故障的情況?

          3)在實(shí)際應(yīng)用中,如何選擇合適的緩存讀寫策略,考慮到系統(tǒng)的特點(diǎn)和需求?

          點(diǎn)燃求職熱情!每周持續(xù)更新,海量面試題等你挑戰(zhàn)!趕緊關(guān)注面試?guó)喒娞?hào),輕松備戰(zhàn)春招和暑期實(shí)習(xí)!

          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久免费视频99 | 精品福利导航在线 | 欧美性爱一级 操逼 | 韩国在线一区二区三区 | 国产精品久久视频 |