目錄
一、更新策略
二、讀寫快取
1、同步直寫策略
2、非同步緩寫策略
三、雙檢加鎖策略
四、資料庫與快取一致性的更新策略
1、先更新資料庫,再更新Redis
2、先更新緩存,再更新資料庫
首頁 資料庫 mysql教程 MySQL資料庫和Redis快取一致性的更新策略是什麼

MySQL資料庫和Redis快取一致性的更新策略是什麼

May 27, 2023 pm 03:11 PM
mysql redis

    一、更新策略

    1、如果Redis中有數據,需要和資料庫中的值相同。

    2、如果Redis中無數據,資料庫中的最新值要對Redis進行同步更新。

    二、讀寫快取

    1、同步直寫策略

    寫入資料庫也同步寫Redis緩存,快取和資料庫中的資料一致;對於讀寫緩存來說,要確保快取和資料庫中的資料一致,就要確保同步直寫策略。

    2、非同步緩寫策略

    某些業務運作中,MySQL資料更新之後,允許在一定時間後再進行Redis資料同步,例如物流系統。

    當出現異常情況時,必須將失敗的動作重新修補,需要藉助rabbitmq或kafka進行重寫。

    三、雙檢加鎖策略

    多個執行緒同時去查詢資料庫的這條數據,那麼我們可以在第一個查詢資料的請求上使用一個互斥鎖來鎖住它。

    其他的執行緒走到這一步拿不到鎖就等著,等第一個執行緒查詢到了數據,然後做快取。

    後面的執行緒進來發現已經有快取了,就直接走快取。

    public String get(String key){
        // 从Redis缓存中读取
        String value = redisTemplate.get(key);
    
        if(value != null){
            return value;
        }
    
        synchronized (RedisTest.class){
            // 重新尝试从Redis缓存中读取
            value = redisTemplate.get(key);
            if(value != null){
                return value;
            }
    
            // 从MySQL数据库中查询
            value = studentDao.get(key);
            // 写入Redis缓存
            redisTemplate.setnx(key,value,time);
            return value;
        }
    }
    登入後複製

    四、資料庫與快取一致性的更新策略

    1、先更新資料庫,再更新Redis

    依照常理出牌的話,應該都是如此吧?那麼,這種情況下,會有啥問題呢?

    如果更新資料庫成功後,更新Redis之前異常了,會出現什麼情況呢?

    資料庫與Redis內快取資料不一致。

    2、先更新緩存,再更新資料庫

    多執行緒情況下,會有問題。

    例如

    • 線程1更新redis = 200;

    • 執行緒2更新redis = 100;





    1. 執行緒2更新MySQL = 100;
    2. #執行緒1更新MySQL = 200;

    結果呢,Redis= 100、MySQL=200;我擦!

    3、先刪除緩存,再更新資料庫

    線程1刪除了Redis的快取數據,然後去更新MySQL資料庫;
      還沒等MySQL更新完畢,線程2殺來,讀取快取資料;
    1. 但是,此時MySQL資料庫還沒更新,執行緒2讀取了MySQL中的舊值,然後執行緒2,也會將舊值寫入Redis作為資料快取;

      執行緒1更新完MySQL資料後,發現Redis中已經有資料了,之前都刪過了,那我就不更新了;

      完蛋了。 。
    2. 延時雙刪

      延時雙刪可以解決上面的問題,只要sleep的時間大於執行緒2讀取資料再寫入快取的時間就可以了,也就是執行緒1的二次清除快取操作要在執行緒2寫入快取之後,這樣才能確保Redis快取中的資料是最新的。
    3. /**
       * 延时双删
       * @autor 哪吒编程
       */
      public void deleteRedisData(Student stu){
          // 删除Redis中的缓存数据
          jedis.del(stu);
      
          // 更新MySQL数据库数据
          studentDao.update(stu);
      
          // 休息两秒
          try {
              TimeUnit.SECONDS.sleep(2);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      
          // 删除Redis中的缓存数据
          jedis.del(stu);
      }
      登入後複製
    4. 延遲雙刪最大的問題就是sleep,在效率為王的今天,sleep能不用還是不用為好。

      你不睡我都嫌你慢,你還睡上了…
    5. 4、先更新資料庫,再刪除快取

    6. ##線程1先更新資料庫,再刪除Redis快取;
    7. 執行緒2在執行緒1刪除Redis快取之前發起請求,得到了未刪除的Redis快取;
    8. ##線程1此時才刪除Redis快取資料;
    9. 問題還是有,這翻來覆去的,沒完沒了。

      這種情況要如何解決呢?


      引入訊息中間件解決戰鬥,再一次詳細的複盤一下。

      更新資料庫;

      MySQL資料庫和Redis快取一致性的更新策略是什麼

      資料庫將操作資訊寫入binlog日誌;

      訂閱程序提取出key和資料;

      嘗試刪除快取操作,發現刪除失敗;

      #########將這些資料資訊傳送到訊息中介軟體中; ############從訊息中間件取得該數據,重新操作;#############5、總結######哪吒推薦使用第四種方式,先更新資料庫,再刪除快取。 ######方式①和方式②缺點太過明顯,不考慮;###方式③中的sleep,總是讓人頭疼;###方式④是一個比較全面的方案,但是增加了學習成本、維護成本,因為增加了訊息中間件。 ######五、MySQL主從複製工作原理###############1、當master 主伺服器上的資料改變時,則將其變更寫入二進位事件在日誌檔案中;######2、salve 從伺服器會在一定時間間隔內對master 主伺服器上的二進位日誌進行探測,探測其是否發生過改變,######如果偵測到master 主伺服器的二進位事件日誌發生了改變,則開始一個I/O Thread 請求master 二進位事件日誌;######3、同時master 主伺服器為每個I/O Thread 啟動一個dump Thread,用於向其傳送二進位事件日誌;######4、slave 從伺服器將接收到的二進位事件日誌儲存到自己本機的中繼日誌檔案;###

      5、salve 從伺服器將啟動SQL Thread 從中繼日誌中讀取二進位日誌,在本機重播,使得其資料和主伺服器保持一致;

      ##6、最後I/O Thread 和SQL Thread 將進入睡眠狀態,等待下一次被喚醒。

      以上是MySQL資料庫和Redis快取一致性的更新策略是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

    Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

    解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

    在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

    laravel框架安裝方法 laravel框架安裝方法 Apr 18, 2025 pm 12:54 PM

    文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

    MySQL與其他編程語言:一種比較 MySQL與其他編程語言:一種比較 Apr 19, 2025 am 12:22 AM

    MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

    MySQL和PhpMyAdmin:核心功能和功能 MySQL和PhpMyAdmin:核心功能和功能 Apr 22, 2025 am 12:12 AM

    MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

    如何利用Redis緩存方案高效實現產品排行榜列表的需求? 如何利用Redis緩存方案高效實現產品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

    Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

    MySQL:結構化數據和關係數據庫 MySQL:結構化數據和關係數據庫 Apr 18, 2025 am 12:22 AM

    MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

    laravel8 的優化點 laravel8 的優化點 Apr 18, 2025 pm 12:24 PM

    Laravel 8 針對性能優化提供了以下選項:緩存配置:使用 Redis 緩存驅動、緩存門面、緩存視圖和頁面片段。數據庫優化:建立索引、使用查詢範圍、使用 Eloquent 關係。 JavaScript 和 CSS 優化:使用版本控制、合併和縮小資產、使用 CDN。代碼優化:使用 Composer 安裝包、使用 Laravel 助手函數、遵循 PSR 標準。監控和分析:使用 Laravel Scout、使用 Telescope、監控應用程序指標。

    See all articles