色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

先操作緩存還是先操作數(shù)據(jù)庫?

jf_78858299 ? 來源:蟬沐風(fēng)的碼場 ? 作者:蟬沐風(fēng) ? 2023-03-03 10:28 ? 次閱讀

在數(shù)據(jù)讀多寫少的情況下作為緩存來使用,恐怕是Redis使用最普遍的場景了。當(dāng)使用Redis作為緩存的時(shí)候,一般流程是這樣的。

  • 如果緩存在Redis中存在,即緩存命中,則直接返回?cái)?shù)據(jù)

圖片

  • 如果Redis中沒有對應(yīng)緩存,則需要直接查詢數(shù)據(jù)庫,然后存入Redis,最后把數(shù)據(jù)返回

圖片

通常情況下,我們會為某個(gè)緩存設(shè)置一個(gè)key值,并針對key值設(shè)置一個(gè)過期時(shí)間,如果被查詢的數(shù)據(jù)對應(yīng)的key過期了,則直接查詢數(shù)據(jù)庫,并將查詢得到的數(shù)據(jù)存入Redis,然后重置過期時(shí)間,最后將數(shù)據(jù)返回,偽代碼如下:

/**
 * 根據(jù)用戶名獲取用戶詳細(xì)信息
 * @author 公眾號【電子發(fā)燒友】
 */
public User getUserInfo(String userName) {
      User user = redisCache.getName("user:" + userName);
      if (user != null) {
          return user;
      }

      // 從數(shù)據(jù)庫中直接搜索
      user = selectUserByUserName(userName);
      // 將數(shù)據(jù)寫入Redis,并設(shè)置過期時(shí)間
      redisCache.set("user:" + userName, user, 30000);
      // 返回?cái)?shù)據(jù)
      return user;
}

一致性問題

但是,在Redis的key值未過期的情況下,用戶修改了個(gè)人信息,我們此時(shí)既要操作數(shù)據(jù)庫數(shù)據(jù),也要操作Redis數(shù)據(jù)。現(xiàn)在我們面臨了兩種選擇:

  1. 先操作Redis的數(shù)據(jù),再操作數(shù)據(jù)庫的數(shù)據(jù)
  2. 先操作數(shù)據(jù)庫的數(shù)據(jù),再操作Redis的數(shù)據(jù)

如論選擇哪種方法,最理想的情況下,兩個(gè)操作要么同時(shí)成功,要么同時(shí)失敗,否則就會出現(xiàn)Redis和數(shù)據(jù)庫數(shù)據(jù)不一致的情況。

遺憾的是,目前沒有什么框架能夠保證Redis的數(shù)據(jù)和數(shù)據(jù)庫的數(shù)據(jù)的完全一致性。我們只能根據(jù)場景和所需要付出的代碼來采取一定的措施降低數(shù)據(jù)不一致出現(xiàn)的概率,在一致性和性能之間取得一個(gè)折中。

下面我們來討論一下關(guān)于Redis和數(shù)據(jù)庫之間數(shù)據(jù)一致性的一些方案。

方案選擇

是刪除緩存還是更新緩存?

當(dāng)數(shù)據(jù)庫數(shù)據(jù)發(fā)生變化的時(shí)候,Redis的數(shù)據(jù)也需要進(jìn)行相應(yīng)的操作,那么這個(gè)「操作」到底是用「更新」還是用「刪除」呢?

「更新」的話調(diào)用Redis的set方法,新值替換舊值;「刪除」直接刪除原來的緩存,下次查詢的時(shí)候重新讀取數(shù)據(jù)庫,然后再更新Redis。

結(jié)論:推薦直接使用「刪除」操作

因?yàn)槭褂谩父隆共僮鞯脑挘銜媾R兩種選擇

  1. 先更新緩存,再更新數(shù)據(jù)庫
  2. 先更新數(shù)據(jù)庫,再更新緩存

第1種不用考慮了,下面討論一下「先更新數(shù)據(jù)庫,再更新緩存」這種方案。

圖片

如果線程1和線程2同時(shí)進(jìn)行更新操作,但是每個(gè)線程的執(zhí)行順序如上圖所示,此時(shí)就會導(dǎo)致數(shù)據(jù)不一致,因此從這個(gè)角度上我們推薦直接使用刪除緩存的方式。

此外,推薦使用「刪除緩存」還有兩點(diǎn)原因。

  1. 如果寫數(shù)據(jù)庫的場景比讀數(shù)據(jù)場景多,采用這種方案就會導(dǎo)致緩存就被頻繁寫入,浪費(fèi)性能;
  2. 如果緩存要經(jīng)過一系列復(fù)雜的計(jì)算才能得到,那么每次寫入數(shù)據(jù)庫后,都再次計(jì)算寫入的緩存無疑也是浪費(fèi)性能的。

明確這個(gè)問題之后,擺在我們面前的就只有兩個(gè)選擇了:

  • 先更新數(shù)據(jù)庫,再刪除緩存
  • 先刪除緩存,再更新數(shù)據(jù)庫

先更新數(shù)據(jù)庫,再刪除緩存

這種方式可能存在以下兩種異常情況

  1. 更新數(shù)據(jù)庫失敗,這時(shí)可以通過程序捕獲異常,直接返回結(jié)果,不再繼續(xù)刪除緩存,所以不會出現(xiàn)數(shù)據(jù)不一致的問題
  2. 更新數(shù)據(jù)庫成功,刪除緩存失敗。導(dǎo)致數(shù)據(jù)庫是最新數(shù)據(jù),緩存中的是舊數(shù)據(jù),數(shù)據(jù)不一致

第2種情況應(yīng)該怎么辦呢?我們有兩種方式:失敗重試異步更新

失敗重試

如果刪除緩存失敗,我們可以捕獲這個(gè)異常,把需要刪除的 key 發(fā)送到消息隊(duì)列。自己創(chuàng)建一個(gè)消費(fèi)者消費(fèi),嘗試再次刪除這個(gè) key,直到刪除成功為止。

圖片

這種方式有個(gè)缺點(diǎn),首先會對業(yè)務(wù)代碼造成入侵,其次引入了消息隊(duì)列,增加了系統(tǒng)的不確定性。

異步更新緩存

因?yàn)楦聰?shù)據(jù)庫時(shí)會往 binlog 中寫入日志,所以我們可以啟動一個(gè)監(jiān)聽 binlog變化的服務(wù)(比如使用阿里的 canal開源組件),然后在客戶端完成刪除 key 的操作。如果刪除失敗的話,再發(fā)送到消息隊(duì)列。

總結(jié)

總之,對于刪除緩存失敗的情況,我們的做法是不斷地重試刪除操作,直到成功。無論是重試還是異步刪除,都是最終一致性的思想。

先刪除緩存,再更新數(shù)據(jù)庫

這種方式可能存在以下兩種異常情況

  1. 刪除緩存失敗,這時(shí)可以通過程序捕獲異常,直接返回結(jié)果,不再繼續(xù)更新數(shù)據(jù)庫,所以不會出現(xiàn)數(shù)據(jù)不一致的問題
  2. 刪除緩存成功,更新數(shù)據(jù)庫失敗。在多線程下可能會出現(xiàn)數(shù)據(jù)不一致的問題

圖片

這時(shí),Redis中存儲的舊數(shù)據(jù),數(shù)據(jù)庫的值是新數(shù)據(jù),導(dǎo)致數(shù)據(jù)不一致。這時(shí)我們可以采用延時(shí)雙刪的策略,即更新數(shù)據(jù)庫數(shù)據(jù)之后,再刪除一次緩存。

圖片

用偽代碼表示就是:

/**
 * 延時(shí)雙刪
 * @author 公眾號【蟬沐風(fēng)】
 */
public void update(String key, Object data) {
    // 首先刪除緩存
    redisCache.delKey(key);
    // 更新數(shù)據(jù)庫
    db.updateData(data);
    // 休眠一段時(shí)間,時(shí)間依據(jù)數(shù)據(jù)的讀取耗費(fèi)的時(shí)間而定
    Thread.sleep(500);
    // 再次刪除緩存
    redisCache.delKey(key);
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7134

    瀏覽量

    89401
  • 緩存
    +關(guān)注

    關(guān)注

    1

    文章

    241

    瀏覽量

    26725
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3845

    瀏覽量

    64594
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    378

    瀏覽量

    10907
收藏 人收藏

    評論

    相關(guān)推薦

    使用ADO操作數(shù)據(jù)庫

    使用ADO操作數(shù)據(jù)庫要運(yùn)行程序必須將數(shù)據(jù)庫文件demo.mdb與可執(zhí)行文件放在一起,如果在vc開發(fā)環(huán)境中運(yùn)行,則需要將該數(shù)據(jù)庫文件放在工程目錄下
    發(fā)表于 10-15 11:41

    使用OLE DB操作數(shù)據(jù)庫

    使用OLE DB操作數(shù)據(jù)庫 要運(yùn)行程序必須將數(shù)據(jù)庫文件students.mdb與可執(zhí)行文件放在一起,如果在vc開發(fā)環(huán)境中運(yùn)行,則需要將該數(shù)據(jù)庫文件放在工程目錄下
    發(fā)表于 10-15 11:41

    使用DAO操作數(shù)據(jù)庫

    使用DAO操作數(shù)據(jù)庫要運(yùn)行程序必須將數(shù)據(jù)庫文件course.mdb與可執(zhí)行文件放在一起,如果在vc開發(fā)環(huán)境中運(yùn)行,則需要將該數(shù)據(jù)庫文件放在工程目錄下
    發(fā)表于 10-15 11:42

    labview遠(yuǎn)程訪問數(shù)據(jù)庫操作數(shù)據(jù)庫

    各位高手:多指教,小弟請教一個(gè)問題:數(shù)據(jù)庫的基本操作現(xiàn)在已經(jīng)實(shí)現(xiàn)。我現(xiàn)在想這樣做,想遠(yuǎn)程連接數(shù)據(jù)庫并且操作數(shù)據(jù)庫文件,就是在同一局域網(wǎng)內(nèi)的
    發(fā)表于 07-28 12:17

    《Dot.NET數(shù)據(jù)庫開發(fā)技術(shù)》操作數(shù)據(jù)庫.pdf

    《Dot.NET數(shù)據(jù)庫開發(fā)技術(shù)》操作數(shù)據(jù)庫.pdf[hide][/hide]
    發(fā)表于 06-23 16:27

    pymysql怎么簡單的操作數(shù)據(jù)庫

    pymysql簡單操作數(shù)據(jù)庫
    發(fā)表于 05-01 07:33

    python的操作數(shù)據(jù)庫

    python操作數(shù)據(jù)庫
    發(fā)表于 05-20 12:11

    Labsql不能操作數(shù)據(jù)庫連接池嗎

    如圖,好像連接字符串也只能指定provider才行,指定了max pool還是不會報(bào)錯(cuò)。C#里for循環(huán)是會報(bào)錯(cuò)的。還有一個(gè)問題,我要多線程操作數(shù)據(jù)庫,應(yīng)該怎么玩?數(shù)據(jù)庫會錯(cuò)亂嗎?有好多個(gè)工位會在不定時(shí)間里讀寫。請問應(yīng)該怎么
    發(fā)表于 09-09 14:44

    使用SQL語句操作數(shù)據(jù)庫

    第一步:Linux開發(fā)環(huán)境搭建第二步:安裝sqlite數(shù)據(jù)庫第三步:sqlite數(shù)據(jù)庫使用1.sqlite部分命令2.使用SQL語句操作數(shù)據(jù)庫(1)創(chuàng)建一個(gè)數(shù)據(jù)表:student(2)
    發(fā)表于 11-04 06:23

    《Dot.NET數(shù)據(jù)庫開發(fā)技術(shù)》操作數(shù)據(jù)庫

    《Dot.NET數(shù)據(jù)庫開發(fā)技術(shù)》操作數(shù)據(jù)庫
    發(fā)表于 02-07 15:11 ?0次下載

    PHP的使用教程之操作數(shù)據(jù)庫的詳細(xì)資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是PHP的使用教程之操作數(shù)據(jù)庫的詳細(xì)資料說明包括了:1.掌握PHP連接數(shù)據(jù)庫的方法,2.掌握PHP創(chuàng)建一個(gè)數(shù)據(jù)庫以及表的方法,3.掌握PHP插入和讀取數(shù)據(jù)的方
    發(fā)表于 05-29 16:51 ?12次下載
    PHP的使用教程之<b class='flag-5'>操作數(shù)據(jù)庫</b>的詳細(xì)資料說明

    分布式系統(tǒng)中的數(shù)據(jù)庫緩存操作順序

    在分布式系統(tǒng)中,緩存數(shù)據(jù)庫同時(shí)存在時(shí),如果有寫操作的時(shí)候,操作數(shù)據(jù)庫還是
    的頭像 發(fā)表于 05-03 14:36 ?2252次閱讀
    分布式系統(tǒng)中的<b class='flag-5'>數(shù)據(jù)庫</b>和<b class='flag-5'>緩存</b><b class='flag-5'>操作</b>順序

    操作數(shù)據(jù)庫還是操作緩存

    來源:撿田螺的小男孩 前言 在分布式系統(tǒng)中,緩存數(shù)據(jù)庫同時(shí)存在時(shí),如果有寫操作操作數(shù)據(jù)庫還是
    的頭像 發(fā)表于 10-30 11:09 ?2028次閱讀
    <b class='flag-5'>先</b><b class='flag-5'>操作數(shù)據(jù)庫</b><b class='flag-5'>還是</b><b class='flag-5'>先</b><b class='flag-5'>操作</b><b class='flag-5'>緩存</b>?

    分布式系統(tǒng)中操作數(shù)據(jù)庫還是操作緩存

    前言 在分布式系統(tǒng)中,緩存數(shù)據(jù)庫同時(shí)存在時(shí),如果有寫操作操作數(shù)據(jù)庫還是
    的頭像 發(fā)表于 09-30 14:46 ?1626次閱讀

    掃描操作數(shù)的信號上升沿

    使用“掃描操作數(shù)的信號上升沿”指令,可以確定所指定操作數(shù))的信號狀態(tài)是否從“0”變?yōu)椤?”。
    的頭像 發(fā)表于 06-27 09:39 ?2754次閱讀
    掃描<b class='flag-5'>操作數(shù)</b>的信號上升沿
    主站蜘蛛池模板: 国产精品欧美亚洲 | 日本一在线中文字幕 | 色欲人妻无码AV专区 | 狂野欧美性猛XXXX乱大交 | 亚洲 自拍 偷拍 另类综合图区 | 精品无码国产污污污免费网站2 | 成人影片大全 | 闺蜜撬开我的腿用黄瓜折磨我 | 亚洲 成人网 | 中国农村真实bbwbbwbbw | 欧美激情精品久久久久 | 亚欧视频在线观看 | 国产成人h在线视频 | 亚洲精品卡2卡3卡4卡5卡区 | 亚洲欧洲日本天天堂在线观看 | 国产91青青成人a在线 | 99精品国产福利在线观看 | 91素人约啪| 99热久久这里只有精品 | 亚洲欧美一区二区成人片 | 美女激清床上戏大全 | 午夜视频在线网站 | 国产Av影片麻豆精品传媒 | 无毒成人社区 | 囯产精品久久久久久久久免费蜜桃 | 国产爱豆果冻传媒在线观看视频 | 成人毛片在线播放 | 99国内精品 | 视频一区国产在线第一页 | 国内精品久久久久影院网站 | 迅雷成人论坛 | 国产亚洲国际精品福利 | 中文字幕在线视频观看 | 国产精品99久久久久久WWW | 97精品少妇偷拍蜜桃AV | 肉色欧美久久久久久久蜜桃 | 性插图动态图无遮挡 | 国产色精品VR一区二区 | 国产AV精品久久久毛片 | cctv官网| 国产黄片毛片 |