欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis和數(shù)據(jù)庫(kù)雙寫(xiě)一致性問(wèn)題的解決方案

 更新時(shí)間:2025年08月06日 08:48:41   作者:Java自學(xué)之旅  
文章探討了Redis與數(shù)據(jù)庫(kù)雙寫(xiě)一致性問(wèn)題,提出四種解決方案:先更新數(shù)據(jù)庫(kù)再刪除緩存(推薦),延時(shí)雙刪避免并發(fā)不一致,監(jiān)聽(tīng)數(shù)據(jù)庫(kù)變更實(shí)現(xiàn)最終一致性,加分布式鎖保障強(qiáng)一致,核心原則是優(yōu)先保證數(shù)據(jù)庫(kù)正確性,緩存操作可失敗重試,強(qiáng)一致性需犧牲性能

下面我將詳細(xì)解答Redis與數(shù)據(jù)庫(kù)雙寫(xiě)一致性問(wèn)題,結(jié)合故事舉例說(shuō)明,最后用思維導(dǎo)圖總結(jié)核心解決方案。

問(wèn)題解答

核心問(wèn)題:當(dāng)同時(shí)更新Redis緩存和數(shù)據(jù)庫(kù)時(shí),由于網(wǎng)絡(luò)延遲、操作順序等問(wèn)題導(dǎo)致數(shù)據(jù)不一致。

解決方案(含故事舉例)

假設(shè)電商平臺(tái)有商品庫(kù)存系統(tǒng):

// 商品服務(wù)類
public class ProductService {
    private DB db = new MySQL();  // 數(shù)據(jù)庫(kù)
    private Cache cache = new Redis();  // 緩存
}

1. 先更新數(shù)據(jù)庫(kù),再刪除緩存(推薦方案)

public void updateProduct(Product product) {
    db.update(product);          // 1. 更新數(shù)據(jù)庫(kù)
    cache.delete(product.getId());// 2. 刪除緩存
}

故事場(chǎng)景

管理員修改商品價(jià)格(100→80元):

  • 數(shù)據(jù)庫(kù)先更新為80元 ?
  • 刪除Redis中該商品的緩存

用戶查詢時(shí):

  • 緩存未命中 → 讀數(shù)據(jù)庫(kù)(80元) ?
  • 回填緩存(80元) ?

優(yōu)勢(shì)

  • 避免"更新緩存失敗導(dǎo)致永久不一致"
  • 緩存刪除失敗可重試(通過(guò)消息隊(duì)列)

風(fēng)險(xiǎn)

并發(fā)時(shí)短暫不一致(概率低):

  • 用戶A讀緩存(空) → 讀數(shù)據(jù)庫(kù)(100元)
  • 管理員更新數(shù)據(jù)庫(kù)(100→80) → 刪緩存
  • 用戶A寫(xiě)緩存(100元) ?(舊數(shù)據(jù))
  • 解決方案:延時(shí)雙刪(下文說(shuō)明)

2. 延時(shí)雙刪策略

public void updateWithDelay(Product product) {
    cache.delete(product.getId());    // 1. 先刪緩存
    db.update(product);               // 2. 更新數(shù)據(jù)庫(kù)
    Thread.sleep(500);                // 3. 等待500ms
    cache.delete(product.getId());    // 4. 再刪緩存
}

故事場(chǎng)景

解決上述并發(fā)問(wèn)題:

  • 首次刪除:清空舊緩存
  • 更新數(shù)據(jù)庫(kù) ?
  • 等待期間可能寫(xiě)入的舊緩存被二次刪除 ?→?

3. 監(jiān)聽(tīng)數(shù)據(jù)庫(kù)變更(最終一致性)

// 使用Canal監(jiān)聽(tīng)MySQL binlog
canal.subscribe(event -> {
    if (event.isUpdate()) {
        cache.delete(event.getKey()); // 異步刪除緩存
    }
});

故事場(chǎng)景

訂單系統(tǒng)庫(kù)存變更:

  • 數(shù)據(jù)庫(kù)減庫(kù)存 ?
  • Canal捕獲變更事件
  • 自動(dòng)刪除Redis庫(kù)存緩存
  • 下次查詢回填最新值 ?

4. 加分布式鎖(強(qiáng)一致)

public void safeUpdate(Product product) {
    Lock lock = redisson.getLock("PRODUCT_" + product.getId());
    lock.lock();
    try {
        db.update(product);
        cache.update(product); // 同時(shí)更新緩存
    } finally {
        lock.unlock();
    }
}

適用場(chǎng)景

金融賬戶余額等強(qiáng)一致性要求:

  • 讀寫(xiě)操作串行化
  • 性能較低(非高并發(fā)場(chǎng)景)

總結(jié)對(duì)比

方案一致性性能復(fù)雜度適用場(chǎng)景
先DB后刪緩存最終★★★★大部分業(yè)務(wù)
延時(shí)雙刪最終★★★高并發(fā)場(chǎng)景
監(jiān)聽(tīng)binlog最終★★★★異構(gòu)系統(tǒng)同步
分布式鎖強(qiáng)一致★★金融/賬戶系統(tǒng)

核心原則

  • 優(yōu)先保證數(shù)據(jù)庫(kù)正確性
  • 緩存操作可失敗/重試
  • 強(qiáng)一致性需犧牲性能

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • redis用list做消息隊(duì)列的實(shí)現(xiàn)示例

    redis用list做消息隊(duì)列的實(shí)現(xiàn)示例

    本文主要介紹了redis用list做消息隊(duì)列的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Redis 緩存滿了如何解決

    Redis 緩存滿了如何解決

    Redis 緩存使用內(nèi)存來(lái)保存數(shù)據(jù),隨著需要緩存的數(shù)據(jù)量越來(lái)越大,有限的緩存空間不可避免地會(huì)被寫(xiě)滿,本文主要介紹了Redis 緩存滿了如何解決,感興趣的可以了解一下
    2023-08-08
  • 如何高效地向Redis插入大量的數(shù)據(jù)(推薦)

    如何高效地向Redis插入大量的數(shù)據(jù)(推薦)

    本篇文章主要介紹了如何高效地向Redis插入大量的數(shù)據(jù),現(xiàn)在分享給大家,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • 解析Redis未授權(quán)訪問(wèn)漏洞復(fù)現(xiàn)與利用危害

    解析Redis未授權(quán)訪問(wèn)漏洞復(fù)現(xiàn)與利用危害

    這篇文章主要介紹了Redis未授權(quán)訪問(wèn)漏洞復(fù)現(xiàn)與利用,介紹了redis未授權(quán)訪問(wèn)漏洞的基本概念及漏洞的危害,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • Redis實(shí)現(xiàn)優(yōu)惠券限一單限制詳解

    Redis實(shí)現(xiàn)優(yōu)惠券限一單限制詳解

    這篇文章主要介紹了Redis解決優(yōu)惠券秒殺應(yīng)用案例,本文先講了搶購(gòu)問(wèn)題,指出其中會(huì)出現(xiàn)的多線程問(wèn)題,提出解決方案采用悲觀鎖和樂(lè)觀鎖兩種方式進(jìn)行實(shí)現(xiàn),然后發(fā)現(xiàn)在搶購(gòu)過(guò)程中容易出現(xiàn)一人多單現(xiàn)象,需要的朋友可以參考下
    2022-12-12
  • 在K8s上部署Redis集群的方法步驟

    在K8s上部署Redis集群的方法步驟

    這篇文章主要介紹了在K8s上部署Redis集群的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 為啥Redis使用pipelining會(huì)更快

    為啥Redis使用pipelining會(huì)更快

    這篇文章主要介紹了為啥Redis使用pipelining會(huì)更快,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Redis主從復(fù)制分步講解使用

    Redis主從復(fù)制分步講解使用

    Redis因?yàn)槠涓咝阅芎鸵子眯栽谖覀兒蠖说姆?wù)中發(fā)揮了巨大的作用,并且很多重要功能的實(shí)現(xiàn)都會(huì)依賴redis,本篇我們來(lái)了解Redis高可用主從復(fù)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • Redis Scan命令的基本使用方法

    Redis Scan命令的基本使用方法

    這篇文章主要給大家介紹了關(guān)于Redis中Scan命令的基本使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Redis集群增加節(jié)點(diǎn)與刪除節(jié)點(diǎn)的方法詳解

    Redis集群增加節(jié)點(diǎn)與刪除節(jié)點(diǎn)的方法詳解

    這篇文章主要給大家介紹了關(guān)于Redis集群增加節(jié)點(diǎn)與刪除節(jié)點(diǎn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評(píng)論