溫馨提示×

溫馨提示×

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

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

Redis怎么應(yīng)對并發(fā)訪問

發(fā)布時間:2022-08-01 14:03:46 來源:億速云 閱讀:137 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Redis怎么應(yīng)對并發(fā)訪問”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    原子性操作

    Redis的原子性操作是一種無鎖操作,即可以保證并發(fā)控制,還能減少系統(tǒng)對并發(fā)性能的影響,

    單命令模式

    把Redis多個操作實現(xiàn)成一個操作,即為單命令模式。

    Redis提供了INCR/DECR命令,可以對數(shù)據(jù)進(jìn)行增值/減值操作,而且它們本身就是單個命令操作,Redis單線程模式,執(zhí)行命令時具有互斥性。

    示例說明

     public Long getIncrNumber(String key,long alive) 
        {
            RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            Long incrNum = entityIdCounter.getAndIncrement();
            if (null == incrNum || incrNum.longValue()==0) 
            {
                entityIdCounter.expire(alive,TimeUnit.MILLISECONDS);
                incrNum = entityIdCounter.getAndIncrement();
            }
            return incrNum;
        }

    說明:采用Reids的INCR命令,如果不存在的key則設(shè)置過期時間,如果key存在則進(jìn)行遞增操作返回。所以如果我們執(zhí)行RMW操作進(jìn)行相關(guān)的遞增或者遞減操作時,Redis提供的INCR和DECY命令可以保證并發(fā)控制。

    多命令模式

    當(dāng)我們不是執(zhí)行簡單的加加減減操作,而是更加復(fù)雜的邏輯判斷或者其他操作時,Redis是無法保證原子性,所以需要將多個操作寫到一個Lua腳本中,Redis會把Lua腳本作為一個整體執(zhí)行,在執(zhí)行過程中不會被其他命令打斷,從而保證了操作的原子性。

    lua簡介

    Lua是一種輕量小巧的腳本語言,用標(biāo)準(zhǔn)C語言編寫并以源代碼形式開放, 其設(shè)計目的是為了嵌入應(yīng)用程序中,從而為應(yīng)用程序提供靈活的擴(kuò)展和定制功能。

    示例說明

    接口進(jìn)行限流操作,同一用戶3秒內(nèi)不能重復(fù)訪問,我們可以通過lua腳本來實現(xiàn)。

    local key = KEYS[1]
    local count = tonumber(ARGV[1])
    local time = tonumber(ARGV[2])
    local current = redis.call('get', key)
    if current and tonumber(current) > count then
        return tonumber(current)
    end
    current = redis.call('incr', key)
    if tonumber(current) == 1 then
        redis.call('expire', key, time)
    end
    return tonumber(current)

    說明:key、count、time為三個傳入?yún)?shù),分別代表Redis的key、次數(shù)和過期時間。通過get獲取key對應(yīng)的值,獲取的值為時間內(nèi)訪問接口的次數(shù),如果為第一次訪問則返回的為null,此時需要對當(dāng)前key進(jìn)行自增1操作,如果返回為數(shù)字,則需要判斷返回的數(shù)字是否已經(jīng)超過了cout值,如果超過說明已經(jīng)超過限流了,直接返回。

    建議
    • 1.編寫lua腳本不要進(jìn)行復(fù)雜耗時的計算邏輯,否則執(zhí)行l(wèi)ua時間過長,會導(dǎo)致Redis主線程阻塞。

    • 2.lua腳本盡量簡單,不要把所有的操作都放入到lua腳本中執(zhí)行,這樣會導(dǎo)致Redis執(zhí)行腳本的時間增加,同時也會降低Redis的并發(fā)性能。

    事務(wù)

    關(guān)于事務(wù)保證原子性,采用的watch命令其原理和樂觀鎖的實現(xiàn)原理類似,詳情可以參考juejin.cn/post/712582… 文章,本文就不在具體闡述。

    加鎖

    關(guān)于Redis的分布式鎖的實現(xiàn),后續(xù)的章節(jié)進(jìn)行詳情說明。高并發(fā)環(huán)境下加鎖雖然能夠保證正確性,但是也會帶來其他的問題:

    • 加鎖操作過多會降低系統(tǒng)的并發(fā)訪問性能

    • Redis客戶端要加鎖,需要使用分布式鎖,而分布式鎖實現(xiàn)復(fù)雜,增加復(fù)雜度。

    “Redis怎么應(yīng)對并發(fā)訪問”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

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

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

    AI