国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性

這篇具有很好參考價(jià)值的文章主要介紹了redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

緩存的定義

緩存(Cache),就是數(shù)據(jù)交換的緩沖區(qū),俗稱的緩存就是緩沖區(qū)內(nèi)的數(shù)據(jù),一般從數(shù)據(jù)庫中獲取,存儲(chǔ)于本地代碼。防止過高的數(shù)據(jù)訪問猛沖系統(tǒng),導(dǎo)致其操作線程無法及時(shí)處理信息而癱瘓,這在實(shí)際開發(fā)中對(duì)企業(yè)講,對(duì)產(chǎn)品口碑,用戶評(píng)價(jià)都是致命的;所以企業(yè)非常重視緩存技術(shù),redis作為最常用的緩存中間件,也是面試的高頻考點(diǎn)。

使用緩存的目的

緩存數(shù)據(jù)存儲(chǔ)于代碼中,而代碼運(yùn)行在內(nèi)存中,內(nèi)存的讀寫性能遠(yuǎn)高于磁盤,緩存可以大大降低用戶訪問并發(fā)量帶來的服務(wù)器讀寫壓力。實(shí)際開發(fā)過程中,企業(yè)的數(shù)據(jù)量,少則幾十萬,多則幾千萬,這么大數(shù)據(jù)量,如果沒有緩存,系統(tǒng)是幾乎撐不住的,所以企業(yè)會(huì)大量運(yùn)用到緩存技術(shù)。

redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性,redis,intellij-idea,java,mysql,中間件

如何使用緩存

實(shí)際開發(fā)中,會(huì)構(gòu)筑多級(jí)緩存來使系統(tǒng)運(yùn)行速度進(jìn)一步提升,例如:本地緩存與redis中的緩存并發(fā)使用

瀏覽器緩存:主要是存在于瀏覽器端的緩存

應(yīng)用層緩存:可以分為tomcat本地緩存,比如之前提到的map,或者是使用redis作為緩存

數(shù)據(jù)庫緩存:在數(shù)據(jù)庫中有一片空間是 buffer pool,增改查數(shù)據(jù)都會(huì)先加載到mysql的緩存中

CPU緩存:當(dāng)代計(jì)算機(jī)最大的問題是 cpu性能提升了,但內(nèi)存讀寫速度沒有跟上,所以為了適應(yīng)當(dāng)下的情況,增加了cpu的L1,L2,L3級(jí)的緩存

緩存商鋪信息

?商鋪信息接口具有很高的并發(fā)量,查詢數(shù)據(jù)不能每次都從數(shù)據(jù)庫查詢,要將商鋪數(shù)據(jù)緩存到redis中,來應(yīng)對(duì)高并發(fā)

@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {
    //這里是直接查詢數(shù)據(jù)庫
    return shopService.queryById(id);
}

redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性,redis,intellij-idea,java,mysql,中間件

緩存模型和思路

標(biāo)準(zhǔn)的操作方式就是查詢數(shù)據(jù)庫之前先查詢緩存,如果緩存數(shù)據(jù)存在,則直接從緩存中返回,如果緩存數(shù)據(jù)不存在,再查詢數(shù)據(jù)庫,然后將數(shù)據(jù)存入redis。

redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性,redis,intellij-idea,java,mysql,中間件

?代碼實(shí)現(xiàn)

注意此時(shí)緩存數(shù)據(jù)不設(shè)置過期時(shí)間,為了減輕數(shù)據(jù)庫壓力,緩存應(yīng)該常駐在內(nèi)存中,但也會(huì)帶來一個(gè)那就是緩存數(shù)據(jù)與數(shù)據(jù)庫數(shù)據(jù)不一致的問題,這就引出了緩沖更新策略這一問題

@Override
    public Result queryById(Long id) {
        //根據(jù)業(yè)務(wù)代碼組裝key
        String key = CACHE_SHOP_KEY + id;
        //從redis中獲取商鋪信息
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(shopJson)) {
            //將json轉(zhuǎn)化為shop對(duì)象直接返回
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return Result.ok(shop);

        }
        Shop shop = getById(id);
        if (shop == null) {
            return Result.fail("店鋪不存在");
        }
        //將數(shù)據(jù)庫查詢的數(shù)據(jù)寫入緩存
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop));
        //返回
        return Result.ok(shop);

緩存更新策略

更新策略主要根據(jù)業(yè)務(wù)來選擇,在本項(xiàng)目中采用的是主動(dòng)更新+超時(shí)剔除的更新策略,超時(shí)剔除主要是作為保底的更新策略,保證緩存在沒有觸發(fā)主動(dòng)更新的情況下,每隔一段時(shí)間就會(huì)清理緩存

緩存更新是redis為了節(jié)約內(nèi)存而設(shè)計(jì)出來的一個(gè)東西,主要是因?yàn)閮?nèi)存數(shù)據(jù)寶貴,當(dāng)我們向redis插入太多數(shù)據(jù),此時(shí)就可能會(huì)導(dǎo)致緩存中的數(shù)據(jù)過多,所以redis會(huì)對(duì)部分?jǐn)?shù)據(jù)進(jìn)行更新,或者把他叫為淘汰更合適。

內(nèi)存淘汰:redis自動(dòng)進(jìn)行,當(dāng)redis內(nèi)存達(dá)到咱們?cè)O(shè)定的max-memery的時(shí)候,會(huì)自動(dòng)觸發(fā)淘汰機(jī)制,淘汰掉一些不重要的數(shù)據(jù)(可以自己設(shè)置策略方式)

超時(shí)剔除:當(dāng)我們給redis設(shè)置了過期時(shí)間ttl之后,redis會(huì)將超時(shí)的數(shù)據(jù)進(jìn)行刪除,方便咱們繼續(xù)使用緩存

主動(dòng)更新:我們可以手動(dòng)調(diào)用方法把緩存刪掉,通常用于解決緩存和數(shù)據(jù)庫不一致問題

redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性,redis,intellij-idea,java,mysql,中間件

?數(shù)據(jù)庫緩存數(shù)據(jù)不一致解決方案

由于我們的緩存的數(shù)據(jù)源來自于數(shù)據(jù)庫,而數(shù)據(jù)庫的數(shù)據(jù)是會(huì)發(fā)生變化的,因此,如果當(dāng)數(shù)據(jù)庫中數(shù)據(jù)發(fā)生變化,而緩存卻沒有同步,此時(shí)就會(huì)有一致性問題存在,其后果是:

用戶使用緩存中的過時(shí)數(shù)據(jù),就會(huì)產(chǎn)生類似多線程數(shù)據(jù)安全問題,從而影響業(yè)務(wù),產(chǎn)品口碑等;怎么解決呢?有如下幾種方案

Cache Aside Pattern 人工編碼方式:緩存調(diào)用者在更新完數(shù)據(jù)庫后再去更新緩存,也稱之為雙寫方案

Read/Write Through Pattern : 由系統(tǒng)本身完成,數(shù)據(jù)庫與緩存的問題交由系統(tǒng)本身去處理

Write Behind Caching Pattern :調(diào)用者只操作緩存,其他線程去異步處理數(shù)據(jù)庫,實(shí)現(xiàn)最終一致

使用方案二增加了系統(tǒng)復(fù)雜度,不利于調(diào)用者排查有關(guān)問題,方案三會(huì)有一系列線程安全,造成數(shù)據(jù)庫緩存不一致的情況,經(jīng)過綜合考慮選用人工編碼的方式較為穩(wěn)妥

人工編碼步驟

  1. 刪除緩存:更新數(shù)據(jù)庫時(shí)讓緩存失效,查詢時(shí)再更新緩存,(如果是更新數(shù)據(jù)庫的同時(shí),更新緩存,會(huì)有太多更新動(dòng)作,無法保證性能)
  2. 在單體系統(tǒng)中,將緩存與數(shù)據(jù)庫操作放在一個(gè)事務(wù),保證更新數(shù)據(jù)庫成功時(shí),緩存也要添加成功,即保證兩個(gè)操作同時(shí)成功或失敗
  3. 先操作數(shù)據(jù)庫,再刪除緩存,在多線程的情況下,操作數(shù)據(jù)庫的時(shí)間要比操作redis緩存的時(shí)間多得多,出現(xiàn)數(shù)據(jù)庫寫完,緩存失效的可能性較小

實(shí)現(xiàn)商鋪和緩存與數(shù)據(jù)庫雙寫一致

  • 根據(jù)id查詢店鋪時(shí),如果緩存未命中,則查詢數(shù)據(jù)庫,將數(shù)據(jù)庫結(jié)果寫入緩存,并設(shè)置超時(shí)時(shí)間
  • 根據(jù)id修改店鋪時(shí),先修改數(shù)據(jù)庫,再刪除緩存

添加緩存時(shí)設(shè)置redis緩存時(shí)添加過期時(shí)間

@Override
    public Result queryById(Long id) {
        //根據(jù)業(yè)務(wù)代碼組裝key
        String key = CACHE_SHOP_KEY + id;
        //從redis中獲取商鋪信息
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(shopJson)) {
            //將json轉(zhuǎn)化為shop對(duì)象直接返回
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return Result.ok(shop);

        }
        Shop shop = getById(id);
        if (shop == null) {
            return Result.fail("店鋪不存在");
        }
        //將數(shù)據(jù)庫查詢的數(shù)據(jù)寫入緩存,并設(shè)置過期時(shí)間
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), 30L,TimeUnit.MINUTES);
        //返回
        return Result.ok(shop);
    }

我們確定了采用刪除策略,來解決雙寫問題,當(dāng)我們修改了數(shù)據(jù)之后,然后把緩存中的數(shù)據(jù)進(jìn)行刪除,查詢時(shí)發(fā)現(xiàn)緩存中沒有數(shù)據(jù),則會(huì)從mysql中加載最新的數(shù)據(jù),從而避免數(shù)據(jù)庫和緩存不一致的問題,此方法需要加@Transactional注解來聲明事務(wù)文章來源地址http://www.zghlxwxcb.cn/news/detail-660129.html

@Transactional
@Override
public Result update(Shop shop) {
    Long id = shop.getId();
    //判斷id是否為空,因?yàn)榭梢岳@過前端直接發(fā)送請(qǐng)求,此步必須判斷
    if (id == null) {
        return Result.fail("店鋪id不能為空");
    }
    //更新數(shù)據(jù)庫
    updateById(shop);
    //刪除緩存
    stringRedisTemplate.delete(CACHE_SHOP_KEY + id);
    return Result.ok();
}

到了這里,關(guān)于redis實(shí)戰(zhàn)-緩存數(shù)據(jù)&解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • redis的緩存更新策略以及如何保證redis與數(shù)據(jù)庫的數(shù)據(jù)一致性

    redis的緩存更新策略有這么幾種: 1、由應(yīng)用直接和redis以及數(shù)據(jù)庫相連接: ?? ??? ?查詢數(shù)據(jù)時(shí),應(yīng)用去redis中查詢,查不到的話再由應(yīng)用去數(shù)據(jù)庫中查詢,并將查詢結(jié)果放在redis; ?? ??? ?更新數(shù)據(jù)時(shí),由應(yīng)用去觸發(fā)redis數(shù)據(jù)的刪除以及數(shù)據(jù)庫的update。 2、應(yīng)用只跟redi

    2024年02月13日
    瀏覽(25)
  • Redis緩存MySQL數(shù)據(jù)庫存儲(chǔ)二者如何保證數(shù)據(jù)一致性

    在大型互聯(lián)網(wǎng)應(yīng)用中,由于數(shù)據(jù)庫讀寫頻繁、壓力大等原因,我們通常會(huì)使用緩存來減少數(shù)據(jù)庫的訪問次數(shù),提高系統(tǒng)的性能。而Redis作為一個(gè)高性能的內(nèi)存數(shù)據(jù)庫,成為了緩存的首選方案之一。但是,緩存和數(shù)據(jù)庫之間存在數(shù)據(jù)一致性的問題,如何解決這個(gè)問題呢?本文將

    2023年04月19日
    瀏覽(27)
  • redis面試題目-如何保證數(shù)據(jù)庫與緩存的數(shù)據(jù)一致性

    原視頻:https://www.bilibili.com/video/BV1Km4y1r75f?p=62vd_source=fa75329ae3880aa55609265a0e9f5d34 由于緩存和數(shù)據(jù)庫是分開的,無法做到原子性的同時(shí)進(jìn)行數(shù)據(jù)修改,可能出現(xiàn)緩存更新失敗,或者數(shù)據(jù)庫更新失敗的情況,這時(shí)候會(huì)出現(xiàn)數(shù)據(jù)不一致,影響前端業(yè)務(wù) 先更新數(shù)據(jù)庫,再更新緩存。緩

    2024年02月05日
    瀏覽(27)
  • 如何保證Redis緩存和數(shù)據(jù)庫的一致性問題

    熟練掌握Redis緩存技術(shù)? 那么請(qǐng)問Redis緩存中有幾種讀寫策略,又是如何保證與數(shù)據(jù)庫的一致性問題 今天來聊一聊常用的三種緩存讀寫策略 首先我們來思考一個(gè)問題 寫 先更新緩存 再更新數(shù)據(jù)庫 首先如果緩存更新成功但數(shù)據(jù)庫更新失敗,會(huì)導(dǎo)致數(shù)據(jù)不一致的問題 其次當(dāng)請(qǐng)求

    2024年02月14日
    瀏覽(23)
  • Redis 原理緩存過期、一致性hash、雪崩、穿透、并發(fā)、布隆、緩存更新策略、緩存數(shù)據(jù)庫一致性

    Redis 原理緩存過期、一致性hash、雪崩、穿透、并發(fā)、布隆、緩存更新策略、緩存數(shù)據(jù)庫一致性

    redis的過期策略可以通過配置文件進(jìn)行配置 redis會(huì)把設(shè)置了過期時(shí)間的key放在單獨(dú)的字典中,定時(shí)遍歷來刪除到期的key。 1).每100ms從過期字典中 隨機(jī)挑選20個(gè),把其中過期的key刪除; 2).如果過期的key占比超過1/4,重復(fù)步驟1 為了保證不會(huì)循環(huán)過度,導(dǎo)致卡頓,掃描時(shí)間上限

    2024年02月08日
    瀏覽(31)
  • MySQL數(shù)據(jù)庫和Redis緩存一致性的更新策略
  • redis和數(shù)據(jù)庫的一致性問題的解決方案

    redis和數(shù)據(jù)庫的一致性問題的解決方案

    當(dāng)前沒有框架能夠保證redis的數(shù)據(jù)和數(shù)據(jù)庫的完全一致性,所以需要 我們自己在性能和一致性上作取舍。 下圖就是兩種在redis緩存數(shù)據(jù)庫內(nèi)容時(shí)的使用。 那么如一個(gè)節(jié)點(diǎn)的兩個(gè)圖: 緩存的生成,是在首次查詢或者緩存過期時(shí)間到或者緩存被其他業(yè)務(wù)刪除,進(jìn)而需要在數(shù)據(jù)庫

    2023年04月08日
    瀏覽(18)
  • 緩存和數(shù)據(jù)庫一致性

    緩存和數(shù)據(jù)庫一致性

    項(xiàng)目的難點(diǎn)是如何保證緩存和數(shù)據(jù)庫的一致性。無論我們是先更新數(shù)據(jù)庫,后更新緩存還是先更新數(shù)據(jù)庫,然后刪除緩存,在并發(fā)場(chǎng)景之下,仍然會(huì)存在數(shù)據(jù)不一致的情況(也存在刪除失敗的情況,刪除失敗可以使用異步重試解決)。有一種解決方法是延遲雙刪的策略,先刪

    2024年01月17日
    瀏覽(24)
  • 如何保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性

    如何保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性

    若數(shù)據(jù)庫更新成功,刪除緩存操作失敗,則此后讀到的都是緩存中過期的數(shù)據(jù),造成不一致問題。 同刪除緩存策略一樣,若數(shù)據(jù)庫更新成功緩存更新失敗則會(huì)造成數(shù)據(jù)不一致問題。 若緩存更新成功數(shù)據(jù)庫更新失敗, 則此后讀到的都是未持久化的數(shù)據(jù)。因?yàn)榫彺嬷械臄?shù)據(jù)是易

    2023年04月19日
    瀏覽(39)
  • 緩存和數(shù)據(jù)庫一致性問題分析

    目錄 1、數(shù)據(jù)不一致的原因 1.1 并發(fā)操作 1.2 非原子操作 1.3 數(shù)據(jù)庫主從同步延遲 2、數(shù)據(jù)不一致的解決方案 2.1 并發(fā)操作 2.2 非原子操作 2.3 主從同步延遲 2.4 最終方案 3、不同場(chǎng)景下的特殊考慮 3.1 讀多寫少的場(chǎng)景 3.2 讀少寫多的場(chǎng)景 導(dǎo)致緩存和數(shù)據(jù)庫數(shù)據(jù)不一致的原因有三個(gè)

    2024年02月14日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包