溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

redisson特性如何實(shí)現(xiàn)

發(fā)布時(shí)間:2022-11-03 09:24:13 來(lái)源:億速云 閱讀:118 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“redisson特性如何實(shí)現(xiàn)”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“redisson特性如何實(shí)現(xiàn)”文章能幫助大家解決問(wèn)題。

    redisson的幾大特性

    相信看了這個(gè)標(biāo)題的同學(xué),對(duì)這個(gè)問(wèn)題以已經(jīng)非常不陌生了,信手拈來(lái)redisson的幾大特性:

    可重入性

    【多個(gè)業(yè)務(wù)線(xiàn)同一時(shí)刻n條扣款,如果用setnx,我怎么監(jiān)控的加鎖解鎖線(xiàn)程?死鎖不得發(fā)生吶?】

    redisson使用hash結(jié)構(gòu),業(yè)務(wù)名稱(chēng)作為key,uuid+線(xiàn)程id作為field,加鎖次數(shù)作為value,這不就解決上述問(wèn)題了嗎

    阻塞能力

    【加鎖有兩個(gè)策略,一是互斥,二是阻塞?;コ獗热缯f(shuō)定時(shí)任務(wù),同一時(shí)刻我需要只執(zhí)行一次就行。阻塞的話(huà)-例如多個(gè)業(yè)務(wù)線(xiàn)同一時(shí)刻n條扣款,我不能互斥掉吧,那不得被噴死。我得寫(xiě)個(gè)while死循環(huán)【標(biāo)準(zhǔn)用語(yǔ)就是自旋】一段時(shí)間在獲取一次,保證系統(tǒng)都能處理這些請(qǐng)求】

    續(xù)約

    加鎖過(guò)期時(shí)間短-加鎖邏輯還沒(méi)執(zhí)行完就解鎖了是不是很尷尬,過(guò)長(zhǎng)的話(huà)-宕機(jī)恢復(fù)時(shí)間又變長(zhǎng)

    redisson默認(rèn)30秒給你執(zhí)行,30秒沒(méi)執(zhí)行完就續(xù)約30s,宕機(jī)的話(huà)恢復(fù)時(shí)間也不會(huì)太長(zhǎng)。

    原理呢就是使用了netty的時(shí)間輪實(shí)現(xiàn)。簡(jiǎn)單點(diǎn)說(shuō)就是環(huán)形數(shù)組。

    直通車(chē):

    RedissonLock --> renewExpiration -->TimerTask
    Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
        @Override
        public void run(Timeout timeout) throws Exception {
            ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
            if (ent == null) {
                return;
            }
            Long threadId = ent.getFirstThreadId();
            if (threadId == null) {
                return;
            }
            RFuture<Boolean> future = renewExpirationAsync(threadId);
            future.onComplete((res, e) -> {
                if (e != null) {
                    log.error("Can't update lock " + getName() + " expiration", e);
                    return;
                }
                if (res) {
                    // reschedule itself
                    renewExpiration();
                }
            });
        }
    }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
    // internalLockLeaseTime默認(rèn)30s,因此這里默認(rèn)延遲10s后執(zhí)行
    // 其中TimerTask引用的就是netty中的TimerTask

    初始化timer的代碼

    protected void initTimer(MasterSlaveServersConfig config) {
        int[] timeouts = new int[]{config.getRetryInterval(), config.getTimeout()};
        Arrays.sort(timeouts);
        int minTimeout = timeouts[0];
        if (minTimeout % 100 != 0) {
            minTimeout = (minTimeout % 100) / 2;
        } else if (minTimeout == 100) {
            minTimeout = 50;
        } else {
            minTimeout = 100;
        }
        // 就是分成了1024個(gè)格子,每個(gè)格子默認(rèn)100ms
        timer = new HashedWheelTimer(new DefaultThreadFactory("redisson-timer"), minTimeout, TimeUnit.MILLISECONDS, 1024, false);
        connectionWatcher = new IdleConnectionWatcher(this, config);
        subscribeService = new PublishSubscribeService(this, config);
    }

    大白話(huà)講就是:例如將一個(gè)圓分成4等分,1,2,3,4,從1到2需要100ms,那么我需要計(jì)算延遲500ms需要走幾步,下標(biāo)是多少?

    既然是時(shí)間總要跳動(dòng)嘛,沒(méi)猜錯(cuò)就是sleep????

    • 紅鎖

    如果redis節(jié)點(diǎn)宕機(jī)大部分節(jié)點(diǎn)同意獲取鎖,才能獲取到鎖。

    • 聯(lián)鎖

    全部節(jié)點(diǎn)加鎖成功才算加鎖成功。

    • 加鎖流程

    lua判斷鎖是否存在

    --> 不存在創(chuàng)建hash,當(dāng)前業(yè)務(wù)key,uuid+線(xiàn)程id為field,value =1 ,設(shè)置過(guò)期時(shí)間并返回

    --> 存在檢查uuid+線(xiàn)程id是否一致,一致遞增value更新過(guò)期時(shí)間返回。存在鎖檢查uuid+線(xiàn)程id不一致,判斷是否到期,沒(méi)到期我就幫你續(xù)期,自己加鎖也沒(méi)有成功,就以當(dāng)前業(yè)務(wù)key發(fā)布消息訂閱pubsub,等收到解鎖消息在重試

    • 解鎖邏輯

    lua判斷鎖是否存在

    -->不存在則直接發(fā)布解鎖消息并返回

    -->存在就檢查uuid+線(xiàn)程id是否一致,不一致就報(bào)錯(cuò),因?yàn)榧渔i線(xiàn)程不一致。如果一致,就遞減value,判斷是否大于0,如果等于0,刪除key并發(fā)布解鎖消息

    關(guān)于“redisson特性如何實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI