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

redis緩存擊穿,redisson分布式鎖,redis邏輯過(guò)期

這篇具有很好參考價(jià)值的文章主要介紹了redis緩存擊穿,redisson分布式鎖,redis邏輯過(guò)期。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

什么是緩存擊穿:

緩存擊穿是指在高并發(fā)環(huán)境下,某個(gè)熱點(diǎn)數(shù)據(jù)的緩存過(guò)期,導(dǎo)致大量請(qǐng)求同時(shí)訪問(wèn)后端存儲(chǔ)系統(tǒng),引起系統(tǒng)性能下降和后端存儲(chǔ)壓力過(guò)大的現(xiàn)象。

解決方案:
1. redisson分布式鎖

本質(zhì)上是緩存重建的過(guò)程中,大量的請(qǐng)求訪問(wèn)到后端的數(shù)據(jù)庫(kù)導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大
那么可以使用redisson分布式鎖來(lái)對(duì)緩存重建的過(guò)程加鎖
其它的線程只有緩存重建完畢之后才可以訪問(wèn)
缺點(diǎn):所有的請(qǐng)求都要等待拿到鎖的線程來(lái)進(jìn)行緩存重建
優(yōu)點(diǎn):數(shù)據(jù)擁有高一致性,適用于某些涉及“錢”的業(yè)務(wù),或者要求數(shù)據(jù)的強(qiáng)一致性的。

  1. 新建redisson子工程單獨(dú)作為微服務(wù)名字叫redisson-starter
  2. 引入redisson相關(guān)依賴
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.17.5</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>
  1. 項(xiàng)目結(jié)構(gòu)
    redis緩存擊穿,redisson分布式鎖,redis邏輯過(guò)期,面試題,緩存,redis,分布式
    RedissonConfigProperties:一些redisson需要的配置項(xiàng),如果是集群此處不能用這種方式
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redisson-lock")
public class RedissonConfigProperties {

    private String redisHost;

    private String redisPort;

}

RedissonConfig:配置RedissonClient,并且加入了一些自動(dòng)裝配的配置

import com.yonchao.redisson.service.RedissonLockService;
import lombok.Data;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Data
@Configuration
@EnableConfigurationProperties({RedissonConfigProperties.class})
//當(dāng)引入Service接口時(shí)
@ConditionalOnClass(RedissonLockService.class)
public class RedissonConfig {


    @Autowired
    private RedissonConfigProperties redissonConfigProperties;

    /**
     * 對(duì) Redisson 的使用都是通過(guò) RedissonClient 對(duì)象
     * @return
     */
    @Bean(destroyMethod="shutdown") // 服務(wù)停止后調(diào)用 shutdown 方法。
    public RedissonClient redisson() {
        // 1.創(chuàng)建配置
        Config config = new Config();
        // 集群模式
        // config.useClusterServers().addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");
        // 2.根據(jù) Config 創(chuàng)建出 RedissonClient 示例。
        config.useSingleServer().setAddress("redis://"+redissonConfigProperties.getRedisHost()+":"+redissonConfigProperties.getRedisPort());
        return Redisson.create(config);
    }
}

spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.yonchao.redisson.service.RedissonLockService

業(yè)務(wù)類:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-736528.html

import com.yonchao.redisson.service.RedissonLockService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedissonLockServiceImpl implements RedissonLockService {
    @Autowired
    private RedissonClient redissonClient;
    /**
     * 加鎖
     * @param lockKey
     * @return
     */
    public boolean acquireLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }
    /**
     * 釋放鎖
     * @param lockKey
     * @return
     */
    public void releaseLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }
}
  1. 其它微服務(wù)通過(guò)pom引入redisson-starter微服務(wù)
    redis緩存擊穿,redisson分布式鎖,redis邏輯過(guò)期,面試題,緩存,redis,分布式
  2. 重建緩存過(guò)程中使用分布式鎖
    首先注入RedissonClient
    接著判斷布隆過(guò)濾器
    接著從緩存中讀數(shù)據(jù)
    讀不到的話需要重建緩存
    重建緩存:
    首先獲取分布式鎖
    獲取成功了就查詢數(shù)據(jù)庫(kù)并且重建緩存返回?cái)?shù)據(jù)最后釋放鎖
    獲取分布式鎖失敗就等待1秒接著遞歸這個(gè)方法,直到有一個(gè)線程重建緩存成功。
    /**
     * 使用邏輯過(guò)期的方式
     * @param id
     * @return
     */
    @Override
    public ResponseResult selectArticleLogicalExpiration(Long id) {
        // 首先經(jīng)過(guò)布隆過(guò)濾器
        // 判斷這個(gè)id是不是在布隆過(guò)濾器中
        boolean mightContain = bloomFilter.mightContain(id);

        // 不存在直接返回
        if (!mightContain) {
            return ResponseResult.okResult();
        }
        
        // 首先從緩存中獲取數(shù)據(jù)
        Object articleObj = redisTemplate.opsForValue().get(ARTICLE_KEY + id);
        
        if (Objects.nonNull(articleObj)){

            String articleJSON = (String) articleObj;

            JSONObject jsonObject = JSON.parseObject(articleJSON);

            Long expired = jsonObject.getLong("expired");
            // 舊的文章對(duì)象
            ApArticle article = JSON.parseObject(articleJSON, ApArticle.class);
            if (Objects.nonNull(expired)){
                // 未過(guò)期直接返回
                if (expired - System.currentTimeMillis() > 0) {

                    return ResponseResult.okResult(article);
                }

                // 過(guò)期了進(jìn)行緩存的重建
                boolean acquiredLock = redissonLockService.acquireLock(lockKeyRedisson);
                // 拿到鎖了就 新開(kāi)一個(gè)線程 進(jìn)行緩存的重建 此處使用分布式鎖,只會(huì)有一個(gè)線程搶占到緩存重建所以不用使用線程池
                if (acquiredLock) {
                    try {
                        new Thread(() -> {
                            // 直接重建緩存,不關(guān)心返回值
                            rebuildCache(id);
                        }).start();

                    } finally {
                        // 最后釋放鎖
                        redissonLockService.releaseLock(lockKeyRedisson);
                    }
                }
                // 開(kāi)啟多線程后直接返回舊的數(shù)據(jù)
                return ResponseResult.okResult(article);
            }

        }
        // 緩存中根本沒(méi)有,那么需要直接加鎖重建緩存,此時(shí)不能多線程的去重建緩存,只能通過(guò)分布式鎖的方式,
        boolean lockAcquired = redissonLockService.acquireLock(lockKeyLogicalExpiration);
        if (lockAcquired){
            try {
                ApArticle apArticle = rebuildCache(id);
                if (Objects.isNull(apArticle)){
                    // 數(shù)據(jù)不存在就直接返回
                    return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
                }
                // 返回獲得的文章數(shù)據(jù)
                return ResponseResult.okResult(apArticle);

            } finally {
                // 最后釋放鎖
                redissonLockService.releaseLock(lockKeyLogicalExpiration);
            }
        } else {
            // 沒(méi)有獲取到鎖就等待一段時(shí)間然后再次嘗試獲取鎖
            try {
                Thread.sleep(1000);
            }catch (Exception e){
                log.error(e.getMessage());
            }
            // 等待一段時(shí)間重新校驗(yàn)有沒(méi)有緩存
            return selectArticleLogicalExpiration(id);
        }
    }


    public ApArticle rebuildCache(Long id){
        // 重建緩存
        ApArticle articleDatabase = getById(id);
        // 重建緩存
        if (Objects.nonNull(articleDatabase)) {
            // 設(shè)置邏輯過(guò)期時(shí)間
            // 轉(zhuǎn)為jsonString
            String articleJsonString = JSON.toJSONString(articleDatabase);
            // 轉(zhuǎn)為JSONObject
            JSONObject articleJsonObject = JSON.parseObject(articleJsonString);
            // 當(dāng)前時(shí)間戳加上 設(shè)置的過(guò)期時(shí)間*1000 因?yàn)闀r(shí)間戳是毫秒
            articleJsonObject.put("expired", System.currentTimeMillis() + ARTICLE_EXPIRED * 1000);
            redisTemplate.opsForValue().set(ARTICLE_KEY + id, JSON.toJSONString(articleJsonObject));
            // 布隆過(guò)濾器過(guò)濾過(guò)的,這個(gè)肯定存在
            return articleDatabase;
        }
        return null;
    }

到了這里,關(guān)于redis緩存擊穿,redisson分布式鎖,redis邏輯過(guò)期的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(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的分布式事務(wù)-redisson

    redis的分布式事務(wù)-redisson

    Redisson分布式鎖是一種基于redis實(shí)現(xiàn)的分布式鎖,它利用redis的setnx命令實(shí)現(xiàn)分布式鎖的互斥訪問(wèn)。同時(shí)還支持鎖的自動(dòng)續(xù)期功能,可以避免因?yàn)槟硞€(gè)進(jìn)程崩潰或者網(wǎng)絡(luò)故障導(dǎo)致鎖無(wú)法釋放的情況。 只要線程一加鎖成功,就會(huì)啟動(dòng)一個(gè)watch dog看門狗,它是一個(gè)后臺(tái)線程,會(huì)每隔

    2024年02月13日
    瀏覽(31)
  • Redis實(shí)戰(zhàn)——Redisson分布式鎖

    Redis實(shí)戰(zhàn)——Redisson分布式鎖

    目錄 1 基于Redis中setnx方法的分布式鎖的問(wèn)題 2 Redisson ????????2.1 什么是Redisson ????????2.2 Redisson實(shí)現(xiàn)分布式鎖快速入門 ????????2.3 Redisson 可重入鎖原理 ????????????????什么是可重入鎖? ????????????????Redisson中又是如何實(shí)現(xiàn)的呢? ????????2

    2024年02月15日
    瀏覽(19)
  • 高并發(fā)下的緩存擊穿、雪崩、穿透和分布式鎖(三)

    概念: 去查詢緩存和數(shù)據(jù)庫(kù)都不存在的數(shù)據(jù),然后大量請(qǐng)求不存在的數(shù)據(jù),導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大崩潰。 解決方案: 把不存在的數(shù)據(jù)null存入緩存,并給個(gè)短期的過(guò)期時(shí)間。 概念: 緩存采用相同的過(guò)期時(shí)間,然后在某一時(shí)刻會(huì)同時(shí)過(guò)期,然后請(qǐng)求全部訪問(wèn)數(shù)據(jù)庫(kù),導(dǎo)致數(shù)據(jù)庫(kù)

    2024年02月07日
    瀏覽(16)
  • 【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day6 - 防止緩存擊穿

    【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day1 - 實(shí)現(xiàn)LRU算法 【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day2 - 單機(jī)并發(fā)緩存 【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day3 - HTTP 服務(wù)端 【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day4 - 一致性哈希(hash) 【go項(xiàng)目-geecache】動(dòng)手寫分布式緩存 - day5 - 分布

    2023年04月20日
    瀏覽(25)
  • redis實(shí)戰(zhàn)-redis實(shí)現(xiàn)分布式鎖&redisson快速入門

    redis實(shí)戰(zhàn)-redis實(shí)現(xiàn)分布式鎖&redisson快速入門

    前言 集群環(huán)境下的并發(fā)問(wèn)題 ?分布式鎖 定義 需要滿足的條件 常見(jiàn)的分布式鎖 redis實(shí)現(xiàn)分布式鎖 核心思路 代碼實(shí)現(xiàn) 誤刪情況 邏輯說(shuō)明 解決方案 代碼實(shí)現(xiàn) 更為極端的誤刪情況 Lua腳本解決原子性問(wèn)題 分布式鎖-redission redisson的概念 快速入門 總結(jié) 在前面我們已經(jīng)實(shí)現(xiàn)了單機(jī)

    2024年02月09日
    瀏覽(26)
  • Redis分布式鎖及Redisson的實(shí)現(xiàn)原理

    Redis分布式鎖及Redisson的實(shí)現(xiàn)原理

    Redis分布式鎖 在討論分布式鎖之前我們回顧一下一些單機(jī)鎖,比如synchronized、Lock 等 鎖的基本特性: 1.互斥性:同一時(shí)刻只能有一個(gè)節(jié)點(diǎn)訪問(wèn)共享資源,比如一個(gè)代碼塊,或者同一個(gè)訂單同一時(shí)刻只能有一個(gè)線程去支付等。 2.可重入性: 允許一個(gè)已經(jīng)獲得鎖的線程,在沒(méi)有釋

    2024年02月06日
    瀏覽(23)
  • Redis 分布式緩存

    Redis 分布式緩存

    單點(diǎn) Redis 的問(wèn)題及解決 數(shù)據(jù)丟失:實(shí)現(xiàn)Redis數(shù)據(jù)持久化 并發(fā)能力:搭建主從集群,實(shí)現(xiàn)讀寫分離 存儲(chǔ)能力:搭建分片集群,利用插槽機(jī)制實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)容 故障恢復(fù)能力:利用哨兵機(jī)制,實(shí)現(xiàn)健康檢測(cè)和自動(dòng)恢復(fù) RDB RDB全稱Redis Database Backup file (Redis數(shù)據(jù)備份文件),也被叫做

    2024年02月10日
    瀏覽(24)
  • Redis分布式緩存

    Redis分布式緩存

    -- 基于Redis集群解決單機(jī)Redis存在的問(wèn)題 單機(jī)的Redis存在四大問(wèn)題: Redis有兩種持久化方案: RDB持久化 AOF持久化 ? ? ? ?RDB全稱Redis Database Backup file(Redis數(shù)據(jù)備份文件),也被叫做 Redis數(shù)據(jù)快照 。簡(jiǎn)單來(lái)說(shuō)就是把 內(nèi)存中的所有數(shù)據(jù)都記錄到磁盤 中。當(dāng)Redis實(shí)例故障重啟后,

    2024年02月12日
    瀏覽(19)
  • 【實(shí)踐篇】Redis最強(qiáng)Java客戶端(三)之Redisson 7種分布式鎖使用指南

    【實(shí)踐篇】Redis最強(qiáng)Java客戶端(三)之Redisson 7種分布式鎖使用指南

    前兩章我們了解了《【實(shí)踐篇】Redis最強(qiáng)Java客戶端(一)之Redisson入門介紹》和《【實(shí)踐篇】Redis最強(qiáng)Java客戶端(二)之Redisson基礎(chǔ)概念》本章第三章主要介紹Redisson的七種分布式鎖,分別是簡(jiǎn)單鎖、公平鎖、可重入鎖、紅鎖、讀寫鎖、信號(hào)量和閉鎖。下面是每種鎖的基本概念、使用

    2024年02月09日
    瀏覽(25)
  • 【業(yè)務(wù)功能100】補(bǔ)充代碼【業(yè)務(wù)功能88】微服務(wù)-springcloud-分布式鎖-redis-redisson-springcache

    采用redisson做分布式鎖,完成數(shù)據(jù)的查詢接口功能getCatelog2JSONRedis 原先從mysql數(shù)據(jù)庫(kù)查詢的效率較低,現(xiàn)在將部分固定數(shù)據(jù)展示比如頁(yè)面的樹(shù)形欄目信息等,存儲(chǔ)到 redis緩存 ,然后基于分布式集群,需要結(jié)合本地鎖(synchronized )與分布式鎖(redissonClient.getLock(“catelog2JSON-lock”

    2024年02月09日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包