應用中引入緩存層後,緩存和持久化層數據一致性的思考

来源:https://www.cnblogs.com/wy123/archive/2019/12/18/12059868.html
-Advertisement-
Play Games

一個應用中決定加緩存(Redis,memcached)之前,要考慮的第一個問題就是,引進了緩存之後,會帶來哪些收益(利),付出哪些代價,引起哪些額外的問題(弊)? 任何新的中間件引進,收益和成本都是伴隨的,只有當利大於弊的情況下,能夠容忍其弊端(徹底解決?沒有額外代價又沒有負面影響,是不可能的,那就 ...


  一個應用中決定加緩存(Redis,memcached)之前,要考慮的第一個問題就是,引進了緩存之後,會帶來哪些收益(利),付出哪些代價,引起哪些額外的問題(弊)? 任何新的中間件引進,收益和成本都是伴隨的,只有當利大於弊的情況下,能夠容忍其弊端(徹底解決?沒有額外代價又沒有負面影響,是不可能的,那就是不用就行了),才值得引進。   以Redis作為緩存為例,引進之後,其利和弊也是伴隨的。 帶來的收益:加速讀寫,提高併發性,降低後端持久化層資料庫的負載 付出的代價:增加代碼複雜,緩存本身的運維,潛在的數據不一致造成的影響。   數據不一致的存在 引進Redis(或者其他緩存)之後,應用程式和數據持久化層多了一個中間層,部分數據存儲由原來的單一持久化層,變為緩存層和持久化層兩份。 這兩部分數據在相互同步的過程中,在某些時間點上的維度來看,可能會潛在不一致的情況。 其中,潛在的數據不一致,是任何一個引進緩存層之後最面臨的最大的一個問題(當然兩者最終的數據是要保持一致的,這一點是底線)。 首先需要衡量的就是,這種潛在的不一致,會引發什麼樣的問題,帶來的問題是否可以接受範圍之內,或者是否會對應用程式邏輯引起致命的問題。 緩存和持久化層存儲可能會不一致,往往是緩存和持久化層未同步刷新引起的,
具體舉例說明: 第一種情況,比如點贊次數,瀏覽次數等等(讀多寫少的場景,寫MySQL,讀Redis,寫入了資料庫但是尚未同步到緩存層這個間隙)。 不會對業務產生嚴重的邏輯錯誤,這種暫時性的數據不一致是可以忍受的,另外就是,通過刷新等手段,兩者數據最終會達成一致。 第二種情況,比如銀行卡取款取超,導致餘額為負數,緩存和持久化層存儲的不一致造成嚴重的邏輯錯誤,這種是無法忍受的。
就需要考慮這種緩存層本身的設計是否合理?   輕量級做法,代碼邏輯實現 如果對於緩存的合理性沒有問題,且業務邏輯上要求緩存和持久化層強一致,那麼久要實現資料庫的一致性操作。 對於緩存和持久化層數據的一致性實現,個人的話,思路有以下兩種, 輕量級的做法如下: 對於引起數據變化的邏輯,一般都是“寫操作”,比如對數據的update或者delete或者insert操作, 1,首先去delete緩存中對應的數據(而不是去對應的update、delete、insert,為什麼?因為只要delete成功,緩存被清理之後,就消除了不一致的可能性,而非delete就做不到) 2,如果1執行成功,再去操作持久化層的資料庫, 3,最後將寫入成功之後的持久化層數據回寫緩存層(這一步可選,或者其它手段同步)

重量級分散式鎖實現,雙寫實現強一致
雙寫的安全性一般要通過分散式鎖來實現,分散式鎖可以通過zookeeper或者redis實現。
一旦考慮使用分散式鎖,又要考慮分散式鎖的載體的安全性,也即不管是用zookeeper或者redis,要考慮zookeeper或者redis的安全性(集群)。
這樣下去,問題會變得非常複雜,純粹變為解決問題-->引入新的問題-->解決問題的死迴圈。
如果要保持一致,當然雙寫也是一種選擇,不過通過雙寫來確保數據的絕對一致,不但會對整體效率產生負面的影響,實現也是比較困難的,暫時不討論這種方案。

如果是分散式鎖,任何寫入性操作,比如update,delete等,如下: 1,直接鎖定相關key值 2,依次操作緩存層和持久化層,同時做好每一層的回滾操作,一旦任何一步失敗,都要回滾 3,最終不管成功或者失敗,都釋放Key 分散式鎖這種方式的話,實現起來,原代碼中業務侵入性較多,比較複雜   重量級隊列化請求 如果是使用隊列,將可能導致不一致性的訪問,隊列化執行,其實這種方式,也是比分散式鎖更加重量級的,基本上會顛覆原始的邏輯實現,一般很少採用。  

但是不管怎麼樣,緩存層和持久化層,最終的數據是要保持一致的,這一點是底線。
整體來看,引不引入緩存層,是從整體性能、業務邏輯、實現代價、數據一致性的容忍程度等多個方面決定的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.官網中文安裝參考手冊 https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/#prerequisites 2、yum安裝gcc相關 1)CentOS7能上外網 2)安裝gcc [root@localhost ~ ...
  • 一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁碟,即使%util是100%,因為磁碟的併發能力,所以磁碟使用未必就到了瓶頸)。 ...
  • -n 參數,他有6個不同的開關:DEV | EDEV | NFS | NFSD | SOCK | ALL 。DEV顯示網路介面信息,EDEV顯示關於網路錯誤的統計數據,NFS統計活動的NFS客戶端的信息,NFSD統計NFS伺服器的信息,SOCK顯示套 接字信息,ALL顯示所有5個開關。它們可以單獨或... ...
  • VMware Workstation 14打開虛擬機黑屏解決方法 聽語音 瀏覽:0 | 更新:2017-11-21 16:56 | 標簽:操作系統 虛擬機 VMWARE 1 2 3 4 分步閱讀 最近VMware Workstation 14版本,很多人使用之後發現虛擬機裡面的系統打開之後黑屏,通過 ...
  • Linux下一切都被抽象成了file,哪些進程可以訪問哪些file,不可以訪問哪些file,就是許可權管理。 每個file都有許可權屬性,可以用 查看file的許可權屬性。 3對rwx分別代表,用戶,組,其他人的rwx。 file通過自己的許可權屬性來保護自己,讓符合自己許可權屬性的進程訪問,讓不符合自己許可權 ...
  • 單片機內核Cortex-M3的八個知識點1.指令集 32位ARM指令集:對應ARM狀態 16位Thumb指令集:對應Thumb狀態(是ARM指令集的一個子集)​ 指令集演進圖 2.BKP備份寄存器(42個16位寄存器組成),用來存儲用戶應用程式數據。在Vdd掉電時由Vbat供電。。在待機複位、系統復 ...
  • 對應用程式來講是(-/+ buffers/cach).buffers/cached 是等同可用的,因為buffer/cached是為了提高程式執行的性能,當程式使用記憶體時,buffer/cached會很快地被使用。所以,從應用來看看,以(-/+ buffers/cache)的free和used為主.... ...
  • 1永久增加ip地址和路由 網卡永久添加ip地址 註釋:ens192為管理地址網卡,請根據實際情況進行修改,網關以192.168.160.1為例 複製一份網卡配置文件命名為ifcfg-ens192:1 cd /etc/sysconfig/network-scripts/ cp ifcfg-ens192 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...