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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

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

數(shù)據(jù)分析與開發(fā) ? 來源:數(shù)據(jù)分析與開發(fā) ? 作者:撿田螺的小男孩 ? 2020-10-30 11:09 ? 次閱讀

來源:撿田螺的小男孩

前言

在分布式系統(tǒng)中,緩存和數(shù)據(jù)庫同時存在時,如果有寫操作,先操作數(shù)據(jù)庫還是先操作緩存呢?本文將分5種方案展開闡述對比,謝謝閱讀~

緩存維護方案一

如果是一讀(線程B)一寫(線程A)操作,「先操作緩存,再操作數(shù)據(jù)庫」。流程圖如下所示:

1.線程A發(fā)起一個寫操作,第一步del cache

2.線程A第二步寫入新數(shù)據(jù)到DB

3.線程B發(fā)起一個讀操作,cache miss緩存失效了。

4.線程B從DB獲取最新數(shù)據(jù)

5.線程B執(zhí)行set cache,把從DB讀到的數(shù)據(jù),更新到緩存。

「這樣看,沒啥問題」。我們再看第二個流程圖,如下:

1.線程A發(fā)起一個寫操作,第一步del cache

2.此時線程B發(fā)起一個讀操作,cache miss

3.線程B繼續(xù)讀DB,讀出來一個老數(shù)據(jù)

4.然后老數(shù)據(jù)設置入cache

5.線程A寫入DB最新的數(shù)據(jù)

OK,醬紫,就有問題了吧,老數(shù)據(jù)入到緩存了,「每次讀都是老數(shù)據(jù)啦,緩存與數(shù)據(jù)與數(shù)據(jù)庫數(shù)據(jù)不一致了」。

緩存維護方案二

上個方案是一讀一寫,如果是雙寫操作,「先操作緩存,在操作數(shù)據(jù)庫」,會怎么樣呢?

1.線程A發(fā)起一個寫操作,第一步set cache

2.線程A第二步寫入新數(shù)據(jù)到DB

3.線程B發(fā)起一個寫操作,set cache

4.線程B第二步寫入新數(shù)據(jù)到DB

「這樣看,也沒啥問題?!?,但是有時候可能事與愿違,我們再看第二個流程圖,如下:

1.線程A發(fā)起一個寫操作,第一步set cache

2.線程B發(fā)起一個寫操作,第一步set cache

3.線程B寫入數(shù)據(jù)庫到DB

4.線程A寫入數(shù)據(jù)庫到DB

執(zhí)行完后,緩存保存的是B操作后的數(shù)據(jù),數(shù)據(jù)庫是A操作后的數(shù)據(jù),「緩存和數(shù)據(jù)庫數(shù)據(jù)不一致了」。

緩存維護方案三

一寫(線程A)一讀(線程B)操作,「先操作數(shù)據(jù)庫,再操作緩存」。

1.線程A發(fā)起一個寫操作,第一步write DB

2.線程A第二步del cache

3.線程B發(fā)起一個讀操作,cache miss

4.線程B從DB獲取最新數(shù)據(jù)

5.線程B同時set cache

有些朋友可能認為,在第2步刪除緩存之前,線程B讀過來呢?這時候,讀到的是緩存老數(shù)據(jù),這個可以認為是正常業(yè)務邏輯呀,下次再讀取就是正確數(shù)據(jù)了。

這種方案「沒有明顯的并發(fā)問題」,但是呢,「步驟二刪除緩存失敗」,還是個問題。不過概率比較小,「優(yōu)于方案一和方案二」,平時工作中也是使用方案三。

綜上對比,我們一般采用方案三,但是有沒有完美全解決方案三的弊端的方法呢?

緩存維護方案四

這個是方案三的改進方案,都是先操作數(shù)據(jù)庫再操作緩存,我們來看一下流程圖:

通過數(shù)據(jù)庫的「binlog」來「異步淘汰key」,以mysql為例 可以「使用阿里的canal將binlog日志采集發(fā)送到MQ隊列」里面,然后「通過ACK機制 確認處理」這條更新消息,刪除緩存,保證數(shù)據(jù)緩存一致性。

但是呢還有個問題,「如果是主從數(shù)據(jù)庫呢」?

緩存維護方案五

主從DB問題:因為主從DB同步存在延時時間。如果刪除緩存之后,數(shù)據(jù)同步到備庫之前已經(jīng)有請求過來時,「會從備庫中讀到臟數(shù)據(jù)」,如何解決呢?解決方案如下流程圖:

緩存維護總結

綜上所述,在分布式系統(tǒng)中,緩存和數(shù)據(jù)庫同時存在時,如果有寫操作的時候,「先操作數(shù)據(jù)庫,再操作緩存」。如下:

1.讀取緩存中是否有相關數(shù)據(jù)

2.如果緩存中有相關數(shù)據(jù)value,則返回

3.如果緩存中沒有相關數(shù)據(jù),則從數(shù)據(jù)庫讀取相關數(shù)據(jù)放入緩存中key->value,再返回

4.如果有更新寫數(shù)據(jù),則先操作數(shù)據(jù)庫,再操作緩存

5.為了保證第四步更新緩存成功,使用binlog異步通知操作

6.如果是主從數(shù)據(jù)庫,binglog取自于從庫

7.如果是一主多從,每個從庫都要采集binlog,然后消費端收到最后一臺binlog數(shù)據(jù)才刪除緩存

原文標題:并發(fā)環(huán)境下,先操作數(shù)據(jù)庫還是先操作緩存?

文章出處:【微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

責任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 緩存
    +關注

    關注

    1

    文章

    240

    瀏覽量

    26699
  • 數(shù)據(jù)庫

    關注

    7

    文章

    3822

    瀏覽量

    64506

原文標題:并發(fā)環(huán)境下,先操作數(shù)據(jù)庫還是先操作緩存?

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    數(shù)據(jù)庫是哪種數(shù)據(jù)庫類型?

    數(shù)據(jù)庫是一種部署在虛擬計算環(huán)境中的數(shù)據(jù)庫,它融合了云計算的彈性和可擴展性,為用戶提供高效、靈活的數(shù)據(jù)庫服務。云數(shù)據(jù)庫主要分為兩大類:關系型數(shù)據(jù)庫
    的頭像 發(fā)表于 01-07 10:22 ?77次閱讀

    數(shù)據(jù)庫事件觸發(fā)的設置和應用

    數(shù)據(jù)庫無論對于生產(chǎn)管理還是很多的實際應用都非常重要。小編這次聊一下數(shù)據(jù)庫事件觸發(fā)的應用。示例使用了postgresql和Python。
    的頭像 發(fā)表于 12-13 15:14 ?159次閱讀

    云托管可以操作數(shù)據(jù)庫嗎?安全性如何

    云托管可以操作數(shù)據(jù)庫。在云托管環(huán)境中,開發(fā)者可以通過使用云服務提供商提供的API或SDK來連接并操作數(shù)據(jù)庫。云托管提供了多種安全性措施來保護數(shù)據(jù)
    的頭像 發(fā)表于 12-11 13:35 ?95次閱讀

    數(shù)據(jù)庫數(shù)據(jù)恢復—MYSQL數(shù)據(jù)庫ibdata1文件損壞的數(shù)據(jù)恢復案例

    mysql數(shù)據(jù)庫故障: mysql數(shù)據(jù)庫文件ibdata1、MYI、MYD損壞。 故障表現(xiàn):1、數(shù)據(jù)庫無法進行查詢等操作;2、使用mysqlcheck和myisamchk無法修復
    的頭像 發(fā)表于 12-09 11:05 ?179次閱讀

    數(shù)據(jù)庫數(shù)據(jù)恢復—通過拼接數(shù)據(jù)庫碎片恢復SQLserver數(shù)據(jù)庫

    一個運行在存儲上的SQLServer數(shù)據(jù)庫,有1000多個文件,大小幾十TB。數(shù)據(jù)庫每10天生成一個NDF文件,每個NDF幾百GB大小。數(shù)據(jù)庫包含兩個LDF文件。 存儲損壞,數(shù)據(jù)庫
    的頭像 發(fā)表于 10-31 13:21 ?265次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復—通過拼接<b class='flag-5'>數(shù)據(jù)庫</b>碎片恢復SQLserver<b class='flag-5'>數(shù)據(jù)庫</b>

    數(shù)據(jù)庫數(shù)據(jù)恢復—SQL Server數(shù)據(jù)庫出現(xiàn)823錯誤的數(shù)據(jù)恢復案例

    SQL Server數(shù)據(jù)庫故障: SQL Server附加數(shù)據(jù)庫出現(xiàn)錯誤823,附加數(shù)據(jù)庫失敗。數(shù)據(jù)庫沒有備份,無法通過備份恢復數(shù)據(jù)庫。
    的頭像 發(fā)表于 09-20 11:46 ?372次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復—SQL Server<b class='flag-5'>數(shù)據(jù)庫</b>出現(xiàn)823錯誤的<b class='flag-5'>數(shù)據(jù)</b>恢復案例

    華納云:MySQL初始化操作如何創(chuàng)建新的數(shù)據(jù)庫

    要在MySQL中創(chuàng)建一個新的數(shù)據(jù)庫,可以按照以下步驟進行操作: 登錄到MySQL數(shù)據(jù)庫管理系統(tǒng)中。可以使用MySQL命令行客戶端或者圖形化工具,如phpMyAdmin。 使用CREATE
    的頭像 發(fā)表于 09-04 14:30 ?279次閱讀

    數(shù)據(jù)庫數(shù)據(jù)恢復—SQL Server數(shù)據(jù)庫所在分區(qū)空間不足報錯的數(shù)據(jù)恢復案例

    SQL Server數(shù)據(jù)庫數(shù)據(jù)恢復環(huán)境: 某品牌服務器存儲中有兩組raid5磁盤陣列。操作系統(tǒng)層面跑著SQL Server數(shù)據(jù)庫,SQL Server
    的頭像 發(fā)表于 07-10 13:54 ?523次閱讀

    數(shù)據(jù)倉庫與數(shù)據(jù)庫的主要區(qū)別

    區(qū)別。 1. 定義 數(shù)據(jù)庫(Database) : 數(shù)據(jù)庫是一種存儲和管理數(shù)據(jù)的系統(tǒng),它允許用戶存儲、檢索和管理數(shù)據(jù)數(shù)據(jù)庫通常用于
    的頭像 發(fā)表于 07-05 14:57 ?540次閱讀

    對于中斷,執(zhí)行中斷服務函數(shù)還是清理中斷標志?

    對于中斷,執(zhí)行中斷服務函數(shù)還是清理中斷標志?開始學習固件的時候,差不多是先進入服務函數(shù)在清理中斷標志。最近在用CubeMX,是清理中
    發(fā)表于 05-22 07:20

    數(shù)據(jù)庫數(shù)據(jù)恢復—raid5陣列上層Sql Server數(shù)據(jù)庫數(shù)據(jù)恢復案例

    數(shù)據(jù)庫數(shù)據(jù)恢復環(huán)境: 5塊硬盤組建一組RAID5陣列,劃分LUN供windows系統(tǒng)服務器使用。windows系統(tǒng)服務器內(nèi)運行了Sql Server數(shù)據(jù)庫,存儲空間在操作系統(tǒng)層面劃分
    的頭像 發(fā)表于 05-08 11:43 ?524次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復—raid5陣列上層Sql Server<b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復案例

    MongoDB數(shù)據(jù)恢復—MongoDB數(shù)據(jù)庫文件損壞的數(shù)據(jù)恢復案例

    服務器數(shù)據(jù)恢復環(huán)境: 一臺Windows Server操作系統(tǒng)服務器,服務器上部署MongoDB數(shù)據(jù)庫。 MongoDB數(shù)據(jù)庫故障&檢測: 工作人員在未關閉MongoDB
    的頭像 發(fā)表于 04-23 14:48 ?422次閱讀
    MongoDB<b class='flag-5'>數(shù)據(jù)</b>恢復—MongoDB<b class='flag-5'>數(shù)據(jù)庫</b>文件損壞的<b class='flag-5'>數(shù)據(jù)</b>恢復案例

    選擇 KV 數(shù)據(jù)庫最重要的是什么?

    經(jīng)常有客戶提到 KV 數(shù)據(jù)庫,但卻偏偏“不要 Redis”。比如有個做安全威脅分析平臺的客戶,他們明確表示自己對可靠性要求非常高,需要的不是開源 Redis 這種內(nèi)存緩存,而是 KV 數(shù)據(jù)庫
    的頭像 發(fā)表于 03-28 22:11 ?714次閱讀
    選擇 KV <b class='flag-5'>數(shù)據(jù)庫</b>最重要的是什么?

    ?通過Modbus讀寫數(shù)據(jù)庫中的數(shù)據(jù)

    狀態(tài)通過‘$RDSS()’方法寫入到Modbus緩存(狀態(tài)大于0時正常執(zhí)行查詢),上位機通過Modbus協(xié)議即可讀取到數(shù)據(jù)庫數(shù)據(jù)以及查詢結果。 第3組是從智能網(wǎng)關的Modbus緩存區(qū)
    發(fā)表于 03-14 13:44

    傳感器之外—兩個數(shù)據(jù)庫之間的“連接”查詢

    年后的小編在寫一些代碼,沒有及時更新我們的公眾號,干脆,先把其中涉及到數(shù)據(jù)庫的的一些操作,尤其是不同數(shù)據(jù)庫,多個表的“連接”查詢的操作過程小結一下供各位參考。畢竟今天這個
    的頭像 發(fā)表于 03-12 14:54 ?527次閱讀
    傳感器之外—兩個<b class='flag-5'>數(shù)據(jù)庫</b>之間的“連接”查詢