成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

管理員修改咖啡價格后,如何保證 Redis 與數據庫同步?

數據庫 其他數據庫
在分布式系統中,沒有完美的緩存一致性方案,只有最適合業務場景的權衡。通過理解各策略的底層原理與細節實現,結合監控與熔斷機制,方能確保每一杯“咖啡”的價格精準無誤地呈現給用戶——這正是技術保障業務價值的生動體現。

在電商、外賣、新零售等實時性要求高的系統中,商品價格是核心數據。以“咖啡商城”為例,管理員在后臺修改一款熱銷咖啡的價格后,用戶端必須立即感知到新價格。由于系統普遍采用“數據庫持久化 + Redis 緩存加速”的架構,如何確保價格變更后 Redis 緩存與數據庫嚴格一致,成為影響用戶體驗和業務準確性的關鍵挑戰。本文將深入探討幾種主流同步策略的原理、實踐細節與選型考量。

一、經典難題:緩存一致性問題剖析

當管理員提交新價格時,數據流向如下:

1. 數據庫更新:新價格寫入 MySQL 等持久化存儲。

2. 緩存失效:需清除或更新 Redis 中舊價格緩存。

3. 用戶讀取:后續請求應獲取新價格。

核心難點在于操作的時序性與分布式環境的不確定性

? 若先更新數據庫再刪緩存,刪除失敗則用戶讀到舊價格

? 若先刪緩存再更新數據庫,更新完成前并發請求可能重建舊緩存

? 網絡延遲、服務宕機等故障加劇不一致風險

二、可靠同步方案詳解與技術實現

方案一:Cache-Aside 結合延遲雙刪 (主流推薦)

流程:

1. 管理員更新數據庫中的咖啡價格

2. 立即刪除 Redis 中對應緩存(如 DEL coffee_price:latte

3. 延遲一定時間(如 500ms)后,再次刪除緩存

// Java + Spring Boot 偽代碼示例
@Service
public class CoffeePriceService {

    @Autowired
    private CoffeePriceMapper priceMapper;
    
    @Autowired
    private RedisTemplate<String, Double> redisTemplate;

    public void updatePrice(Long coffeeId, Double newPrice) {
        // 1. 更新數據庫
        priceMapper.updatePrice(coffeeId, newPrice);
        
        // 2. 首次刪除緩存
        String cacheKey = "coffee_price:" + coffeeId;
        redisTemplate.delete(cacheKey);
        
        // 3. 提交延遲任務,二次刪除
        Executors.newSingleThreadScheduledExecutor().schedule(() -> {
            redisTemplate.delete(cacheKey);
        }, 500, TimeUnit.MILLISECONDS); // 延遲時間需根據業務調整
    }
}

關鍵細節:

延遲時間計算:需大于 “數據庫主從同步時間 + 一次讀請求耗時”。例如主從延遲 200ms,業務讀平均 100ms,則延遲應 >300ms。

二次刪除必要性:防止首次刪除后、數據庫主從同步完成前,有請求從庫讀到舊數據并回填緩存。

線程池優化:使用獨立線程池避免阻塞業務線程,建議用 @Async 或消息隊列異步執行。

方案二:Write-Through 寫穿透策略

原理:所有寫操作同時更新數據庫和緩存,保持強一致性。

public void updatePriceWithWriteThrough(Long coffeeId, Double newPrice) {
    // 原子性更新:數據庫與緩存
    Transaction tx = startTransaction();
    try {
        priceMapper.updatePrice(coffeeId, newPrice);  // 寫 DB
        redisTemplate.opsForValue().set("coffee_price:" + coffeeId, newPrice); // 寫 Redis
        tx.commit();
    } catch (Exception e) {
        tx.rollback();
        throw e;
    }
}

適用場景

? 對一致性要求極高(如金融價格)

? 寫操作較少,讀操作頻繁

缺點

? 寫操作變慢(需同時寫兩個系統)

? 事務復雜性高(需跨 DB 和 Redis 的事務支持,通常用 TCC 等柔性事務)

方案三:基于 Binlog 的異步同步(如 Canal + Kafka)

架構:

MySQL → Canal 監聽 Binlog → 解析變更 → Kafka 消息 → 消費者更新 Redis

優勢:

解耦:業務代碼無需耦合緩存刪除邏輯

高可靠:通過消息隊列保證最終一致性

通用性:可支持多種數據源同步

部署步驟:

1. 部署 Canal Server,配置對接 MySQL

2. 創建 Kafka Topic(如 coffee_price_update

3. Canal 將 Binlog 轉發至 Kafka

4. 消費者監聽 Topic,更新 Redis

// Kafka 消費者示例
@KafkaListener(topics = "coffee_price_update")
public void handlePriceChange(ChangeEvent event) {
    if (event.getTable().equals("coffee_prices")) {
        String key = "coffee_price:" + event.getId();
        redisTemplate.delete(key); // 或直接 set 新值
    }
}

三、極端場景優化:應對高并發與故障

場景一:緩存擊穿(Cache Breakdown)

  • 問題:緩存失效瞬間,大量請求涌向數據庫。
  • 解法:使用 Redis 分布式鎖,僅允許一個線程重建緩存。
public Double getPriceWithLock(Long coffeeId) {
    String cacheKey = "coffee_price:" + coffeeId;
    Double price = redisTemplate.opsForValue().get(cacheKey);
    
    if (price == null) {
        String lockKey = "lock:coffee_price:" + coffeeId;
        if (redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS)) {
            try {
                // 查數據庫并回填緩存
                price = priceMapper.getPrice(coffeeId);
                redisTemplate.opsForValue().set(cacheKey, price, 30, TimeUnit.MINUTES);
            } finally {
                redisTemplate.delete(lockKey);
            }
        } else {
            // 未搶到鎖,短暫休眠后重試
            Thread.sleep(50);
            return getPriceWithLock(coffeeId);
        }
    }
    return price;
}

場景二:批量更新導致緩存雪崩

問題:管理員批量修改 1000 款咖啡價格 → 同時失效大量緩存。

解法

1. 為不同 Key 設置隨機過期時間(如 30min ± 5min)

2. 使用 Hystrix 或 Sentinel 熔斷,保護數據庫

3. 更新緩存時采用分批次策略

四、方案選型對比與壓測數據

方案

一致性強度

響應延遲

系統復雜度

適用場景

延遲雙刪

最終一致

通用,中小系統

Write-Through

強一致

金融、醫療等關鍵系統

Canal + Kafka 同步

最終一致

大型分布式系統

壓測結論(基于 4C8G 云服務器):

? 延遲雙刪:平均寫延遲 15ms,讀 QPS 12,000

? Write-Through:寫延遲升至 45ms,讀 QPS 不變

? Canal 方案:寫操作不受影響,緩存更新延遲 200ms 內

五、最佳實踐總結

1. 首選延遲雙刪:平衡一致性與性能,適合多數業務。

2. 監控與告警:對 Cache Miss 率、Redis 刪除失敗次數設置閾值告警。

3. 設置合理的過期時間:即使同步失敗,舊數據也會自動失效。

4. 兜底機制:在緩存中存儲數據版本號或時間戳,客戶端校驗有效性。

5. 避免過度設計:非核心業務可接受秒級延遲。

在分布式系統中,沒有完美的緩存一致性方案,只有最適合業務場景的權衡。通過理解各策略的底層原理與細節實現,結合監控與熔斷機制,方能確保每一杯“咖啡”的價格精準無誤地呈現給用戶——這正是技術保障業務價值的生動體現。

責任編輯:武曉燕 來源: 程序員秋天
相關推薦

2019-07-17 17:00:29

數據庫數據庫管理員DBA

2011-08-17 15:29:00

2023-03-22 09:18:53

數據庫管理架構

2009-11-06 17:39:41

2010-07-15 11:09:46

用戶帳戶數據庫管理

2009-10-26 17:29:21

Oracle管理員數據庫管理

2011-12-13 10:34:56

2011-03-15 13:25:41

Oracle數據庫管理員維護

2011-03-24 17:40:07

2011-03-15 13:06:06

Oracle數據庫管理員

2017-10-20 14:59:43

2011-05-12 09:25:04

2011-03-21 16:38:29

數據庫管理員開發人員

2011-03-15 11:34:43

Oracle數據庫管理員任務

2009-07-19 10:06:12

2009-10-27 13:20:19

Oracle默認管理員

2011-02-16 14:36:58

VMwareXenServer

2013-01-08 15:37:40

2025-04-27 08:52:21

Redis數據庫緩存

2011-07-15 15:12:54

SQL ServerDAC
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区在线播放 | 国产午夜av | 日韩精品视频免费在线观看 | 精品福利一区 | 国产精品五区 | 黄色片视频免费 | 黄色激情视频网站 | 亚洲精品视频在线播放 | 日本不卡一区 | 99re视频在线 | av一二三区| 黄色www| 久久99精品久久久久久 | 波多野结衣乳巨码无在线观看 | 中文字字幕 | 午夜精品视频 | 久久国产精品一区二区 | 中文字幕91 | 日韩视频二区 | 97色婷婷 | 欧美一区三区 | 天堂av资源 | 久久av免费观看 | 深夜视频在线观看 | 亚洲激情偷拍 | 天天综合视频 | 亚洲播放| cao视频 | 国产手机在线视频 | 黄网免费看 | 99re视频在线 | 亚洲一区二区在线播放 | 三级网站免费 | 欧美精品黄色 | 亚洲精品视频在线 | 久久成人免费视频 | 五月开心激情网 | 一级黄色录像视频 | 日本在线不卡视频 | 91一级片| 麻豆一区二区三区四区 |