中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

redis分布式鎖如何優化

發布時間:2022-08-31 10:09:09 來源:億速云 閱讀:211 作者:iii 欄目:開發技術

本篇內容主要講解“redis分布式鎖如何優化”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“redis分布式鎖如何優化”吧!

優化之UUID防誤刪

redis分布式鎖如何優化

redis分布式鎖如何優化

問題:刪除操作缺乏原子性。

場景:

index1執行刪除時,查詢到的lock值確實和uuid相等

uuid=v1

set(lock,uuid);

redis分布式鎖如何優化

index1執行刪除前,lock剛好過期時間已到,被redis自動釋放,在redis中沒有了lock,沒有了鎖。

redis分布式鎖如何優化

index2獲取了lock

index2線程獲取到了cpu的資源,開始執行方法

uuid=v2

set(lock,uuid);

index1執行刪除,此時會把index2的lock刪除

index1 因為已經在方法中了,所以不需要重新上鎖。index1有執行的權限。index1已經比較完成了,這個時候,開始執行

redis分布式鎖如何優化

刪除的index2的鎖!

優化之LUA腳本保證刪除的原子性

@GetMapping("testLockLua")
public void testLockLua() {
    //1 聲明一個uuid ,將做為一個value 放入我們的key所對應的值中
    String uuid = UUID.randomUUID().toString();
    //2 定義一個鎖:lua 腳本可以使用同一把鎖,來實現刪除!
    String skuId = "25"; // 訪問skuId 為25號的商品 100008348542
    String locKey = "lock:" + skuId; // 鎖住的是每個商品的數據
   // 3 獲取鎖
    Boolean lock = redisTemplate.opsForValue().setIfAbsent(locKey, uuid, 3, TimeUnit.SECONDS);
    // 第一種: lock 與過期時間中間不寫任何的代碼。
    // redisTemplate.expire("lock",10, TimeUnit.SECONDS);//設置過期時間
    // 如果true
    if (lock) {
        // 執行的業務邏輯開始
        // 獲取緩存中的num 數據
        Object value = redisTemplate.opsForValue().get("num");
        // 如果是空直接返回
        if (StringUtils.isEmpty(value)) {
            return;
        }
        // 不是空 如果說在這出現了異常! 那么delete 就刪除失敗! 也就是說鎖永遠存在!
        int num = Integer.parseInt(value + "");
        // 使num 每次+1 放入緩存
        redisTemplate.opsForValue().set("num", String.valueOf(++num));
        /*使用lua腳本來鎖*/
        // 定義lua 腳本
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        // 使用redis執行lua執行
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(script);
        // 設置一下返回值類型 為Long
        // 因為刪除判斷的時候,返回的0,給其封裝為數據類型。如果不封裝那么默認返回String 類型,
        // 那么返回字符串與0 會有發生錯誤。
        redisScript.setResultType(Long.class);
        // 第一個要是script 腳本 ,第二個需要判斷的key,第三個就是key所對應的值。
        redisTemplate.execute(redisScript, Arrays.asList(locKey), uuid);
    } else {
        // 其他線程等待
        try {
            // 睡眠
            Thread.sleep(1000);
            // 睡醒了之后,調用方法。
            testLockLua();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Lua 腳本詳解:

redis分布式鎖如何優化

項目中正確使用

定義key,key應該是為每個sku定義的,也就是每個sku有一把鎖。

String locKey ="lock:"+skuId; // 鎖住的是每個商品的數據
Boolean lock = redisTemplate.opsForValue().setIfAbsent(locKey, uuid,3,TimeUnit.SECONDS);

redis分布式鎖如何優化

總結

加鎖

redis分布式鎖如何優化

使用lua釋放鎖

redis分布式鎖如何優化

重試

redis分布式鎖如何優化

為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件:

- 互斥性。在任意時刻,只有一個客戶端能持有鎖。

- 不會發生死鎖。即使有一個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保證后續其他客戶端能加鎖。

- 解鈴還須系鈴人。加鎖和解鎖必須是同一個客戶端,客戶端自己不能把別人加的鎖給解了。

- 加鎖和解鎖必須具有原子性

到此,相信大家對“redis分布式鎖如何優化”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天祝| 都昌县| 婺源县| 墨玉县| 吴川市| 黔西县| 邢台市| 佛山市| 长白| 十堰市| 华蓥市| 清徐县| 鹤山市| 沾益县| 射阳县| 平利县| 乡城县| 陇西县| 峡江县| 漳州市| 新丰县| 舒城县| 双辽市| 定襄县| 阿图什市| 东阿县| 来宾市| 九龙城区| 化德县| 莱西市| 女性| 新龙县| 阿拉善盟| 五峰| 五大连池市| 柳江县| 蓝田县| 崇仁县| 唐河县| 萨嘎县| 安国市|