最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redisson實(shí)現(xiàn)Redis分布式鎖的幾種方式

 更新時(shí)間:2021年08月05日 10:48:50   作者:阿飛的博客  
本文在講解如何使用Redisson實(shí)現(xiàn)Redis普通分布式鎖,以及Redlock算法分布式鎖的幾種方式的同時(shí),也附帶解答這些同學(xué)的一些疑問,感興趣的可以了解一下

前幾天發(fā)的一篇文章《Redlock:Redis分布式鎖最牛逼的實(shí)現(xiàn)》,引起了一些同學(xué)的討論,也有一些同學(xué)提出了一些疑問,這是好事兒。本文在講解如何使用Redisson實(shí)現(xiàn)Redis普通分布式鎖,以及Redlock算法分布式鎖的幾種方式的同時(shí),也附帶解答這些同學(xué)的一些疑問。

Redis幾種架構(gòu)

Redis發(fā)展到現(xiàn)在,幾種常見的部署架構(gòu)有:

  • 單機(jī)模式;
  • 主從模式;
  • 哨兵模式;
  • 集群模式;

我們首先基于這些架構(gòu)講解Redisson普通分布式鎖實(shí)現(xiàn),需要注意的是,只有充分了解普通分布式鎖是如何實(shí)現(xiàn)的,才能更好的了解Redlock分布式鎖的實(shí)現(xiàn),因?yàn)镽edlock分布式鎖的實(shí)現(xiàn)完全基于普通分布式鎖。

普通分布式鎖

Redis普通分布式鎖這個(gè)大家基本上只了解,本文不打算過多的介紹,上一篇文章《Redlock:Redis分布式鎖最牛逼的實(shí)現(xiàn)》也講的很細(xì),并且也說到了幾個(gè)重要的注意點(diǎn)。

所以直接show you the code,畢竟talk is cheap。

redisson版本

本次測試選擇redisson 2.14.1版本。

單機(jī)模式

源碼如下:

// 構(gòu)造redisson實(shí)現(xiàn)分布式鎖必要的Config
Config config = new Config();
config.useSingleServer().setAddress("redis://172.29.1.180:5379").setPassword("a123456").setDatabase(0);
// 構(gòu)造RedissonClient
RedissonClient redissonClient = Redisson.create(config);
// 設(shè)置鎖定資源名稱
RLock disLock = redissonClient.getLock("DISLOCK");
boolean isLock;
try {
    //嘗試獲取分布式鎖
    isLock = disLock.tryLock(500, 15000, TimeUnit.MILLISECONDS);
    if (isLock) {
        //TODO if get lock success, do something;
        Thread.sleep(15000);
    }
} catch (Exception e) {
} finally {
    // 無論如何, 最后都要解鎖
    disLock.unlock();
}

通過代碼可知,經(jīng)過Redisson的封裝,實(shí)現(xiàn)Redis分布式鎖非常方便,我們再看一下Redis中的value是啥,和前文分析一樣,hash結(jié)構(gòu),key就是資源名稱,field就是UUID+threadId,value就是重入值,在分布式鎖時(shí),這個(gè)值為1(Redisson還可以實(shí)現(xiàn)重入鎖,那么這個(gè)值就取決于重入次數(shù)了):

172.29.1.180:5379> hgetall DISLOCK
1) "01a6d806-d282-4715-9bec-f51b9aa98110:1"
2) "1"

哨兵模式

即sentinel模式,實(shí)現(xiàn)代碼和單機(jī)模式幾乎一樣,唯一的不同就是Config的構(gòu)造:

Config config = new Config();
config.useSentinelServers().addSentinelAddress(
        "redis://172.29.3.245:26378","redis://172.29.3.245:26379", "redis://172.29.3.245:26380")
        .setMasterName("mymaster")
        .setPassword("a123456").setDatabase(0);


集群模式

集群模式構(gòu)造Config如下:

Config config = new Config();
config.useClusterServers().addNodeAddress(
        "redis://172.29.3.245:6375","redis://172.29.3.245:6376", "redis://172.29.3.245:6377",
        "redis://172.29.3.245:6378","redis://172.29.3.245:6379", "redis://172.29.3.245:6380")
        .setPassword("a123456").setScanInterval(5000);

總結(jié)

普通分布式實(shí)現(xiàn)非常簡單,無論是那種架構(gòu),向Redis通過EVAL命令執(zhí)行LUA腳本即可。

Redlock分布式鎖

那么Redlock分布式鎖如何實(shí)現(xiàn)呢?以單機(jī)模式Redis架構(gòu)為例,直接看實(shí)現(xiàn)代碼:

Config config1 = new Config();
config1.useSingleServer().setAddress("redis://172.29.1.180:5378")
        .setPassword("a123456").setDatabase(0);
RedissonClient redissonClient1 = Redisson.create(config1);

Config config2 = new Config();
config2.useSingleServer().setAddress("redis://172.29.1.180:5379")
        .setPassword("a123456").setDatabase(0);
RedissonClient redissonClient2 = Redisson.create(config2);

Config config3 = new Config();
config3.useSingleServer().setAddress("redis://172.29.1.180:5380")
        .setPassword("a123456").setDatabase(0);
RedissonClient redissonClient3 = Redisson.create(config3);

String resourceName = "REDLOCK";
RLock lock1 = redissonClient1.getLock(resourceName);
RLock lock2 = redissonClient2.getLock(resourceName);
RLock lock3 = redissonClient3.getLock(resourceName);

RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
boolean isLock;
try {
    isLock = redLock.tryLock(500, 30000, TimeUnit.MILLISECONDS);
    System.out.println("isLock = "+isLock);
    if (isLock) {
        //TODO if get lock success, do something;
        Thread.sleep(30000);
    }
} catch (Exception e) {
} finally {
    // 無論如何, 最后都要解鎖
    System.out.println("");
    redLock.unlock();
}

最核心的變化就是RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);,因?yàn)槲疫@里是以三個(gè)節(jié)點(diǎn)為例。

那么如果是哨兵模式呢?需要搭建3個(gè),或者5個(gè)sentinel模式集群(具體多少個(gè),取決于你)。
那么如果是集群模式呢?需要搭建3個(gè),或者5個(gè)cluster模式集群(具體多少個(gè),取決于你)。

實(shí)現(xiàn)原理

既然核心變化是使用了RedissonRedLock,那么我們看一下它的源碼有什么不同。這個(gè)類是RedissonMultiLock的子類,所以調(diào)用tryLock方法時(shí),事實(shí)上調(diào)用了RedissonMultiLock的tryLock方法,精簡源碼如下:

public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
    // 實(shí)現(xiàn)要點(diǎn)之允許加鎖失敗節(jié)點(diǎn)限制
    int failedLocksLimit = failedLocksLimit();
    List<RLock> acquiredLocks = new ArrayList<RLock>(locks.size());
    // 實(shí)現(xiàn)要點(diǎn)之遍歷所有節(jié)點(diǎn)通過EVAL命令執(zhí)行l(wèi)ua加鎖
    for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext();) {
        RLock lock = iterator.next();
        boolean lockAcquired;
        try {
            // 對節(jié)點(diǎn)嘗試加鎖
            lockAcquired = lock.tryLock(awaitTime, newLeaseTime, TimeUnit.MILLISECONDS);
        } catch (RedisConnectionClosedException|RedisResponseTimeoutException e) {
            // 如果拋出這類異常,為了防止加鎖成功,但是響應(yīng)失敗,需要解鎖
            unlockInner(Arrays.asList(lock));
            lockAcquired = false;
        } catch (Exception e) {
            // 拋出異常表示獲取鎖失敗
            lockAcquired = false;
        }
        
        if (lockAcquired) {
            // 成功獲取鎖集合
            acquiredLocks.add(lock);
        } else {
            // 如果達(dá)到了允許加鎖失敗節(jié)點(diǎn)限制,那么break,即此次Redlock加鎖失敗
            if (locks.size() - acquiredLocks.size() == failedLocksLimit()) {
                break;
            }               
        }
    }
    return true;
}

很明顯,這段源碼就是上一篇文章《Redlock:Redis分布式鎖最牛逼的實(shí)現(xiàn)》提到的Redlock算法的完全實(shí)現(xiàn)。

以sentinel模式架構(gòu)為例,如下圖所示,有sentinel-1,sentinel-2,sentinel-3總計(jì)3個(gè)sentinel模式集群,如果要獲取分布式鎖,那么需要向這3個(gè)sentinel集群通過EVAL命令執(zhí)行LUA腳本,需要3/2+1=2,即至少2個(gè)sentinel集群響應(yīng)成功,才算成功的以Redlock算法獲取到分布式鎖:


問題合集

根據(jù)上面實(shí)現(xiàn)原理的分析,這位同學(xué)應(yīng)該是對Redlock算法實(shí)現(xiàn)有一點(diǎn)點(diǎn)誤解,假設(shè)我們用5個(gè)節(jié)點(diǎn)實(shí)現(xiàn)Redlock算法的分布式鎖。那么要么是5個(gè)redis單實(shí)例,要么是5個(gè)sentinel集群,要么是5個(gè)cluster集群。而不是一個(gè)有5個(gè)主節(jié)點(diǎn)的cluster集群,然后向每個(gè)節(jié)點(diǎn)通過EVAL命令執(zhí)行LUA腳本嘗試獲取分布式鎖,如上圖所示。

失效時(shí)間如何設(shè)置
這個(gè)問題的場景是,假設(shè)設(shè)置失效時(shí)間10秒,如果由于某些原因?qū)е?0秒還沒執(zhí)行完任務(wù),這時(shí)候鎖自動(dòng)失效,導(dǎo)致其他線程也會(huì)拿到分布式鎖。

這確實(shí)是Redis分布式最大的問題,不管是普通分布式鎖,還是Redlock算法分布式鎖,都沒有解決這個(gè)問題。也有一些文章提出了對失效時(shí)間續(xù)租,即延長失效時(shí)間,很明顯這又提升了分布式鎖的復(fù)雜度。另外就筆者了解,沒有現(xiàn)成的框架有實(shí)現(xiàn),如果有哪位知道,可以告訴我,萬分感謝。

redis分布式鎖的高可用
關(guān)于Redis分布式鎖的安全性問題,在分布式系統(tǒng)專家Martin Kleppmann和Redis的作者antirez之間已經(jīng)發(fā)生過一場爭論。有興趣的同學(xué),搜索"基于Redis的分布式鎖到底安全嗎"就能得到你想要的答案,需要注意的是,有上下兩篇(這應(yīng)該就是傳說中的神仙打架吧,哈)。

zookeeper or redis
沒有絕對的好壞,只有更適合自己的業(yè)務(wù)。就性能而言,redis很明顯優(yōu)于zookeeper;就分布式鎖實(shí)現(xiàn)的健壯性而言,zookeeper很明顯優(yōu)于redis。如何選擇,取決于你的業(yè)務(wù)!

到此這篇關(guān)于Redisson實(shí)現(xiàn)Redis分布式鎖的幾種方式的文章就介紹到這了,更多相關(guān)Redisson實(shí)現(xiàn)Redis分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis鎖的過期時(shí)間小于業(yè)務(wù)的執(zhí)行時(shí)間如何續(xù)期

    Redis鎖的過期時(shí)間小于業(yè)務(wù)的執(zhí)行時(shí)間如何續(xù)期

    本文主要介紹了Redis鎖的過期時(shí)間小于業(yè)務(wù)的執(zhí)行時(shí)間如何續(xù)期,Redisson它能給Redis分布式鎖實(shí)現(xiàn)過期時(shí)間自動(dòng)續(xù)期,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Redis之Key過期策略的用法解讀

    Redis之Key過期策略的用法解讀

    這篇文章主要介紹了Redis之Key過期策略的用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Linux下redis5.0.5的安裝過程與配置方法

    Linux下redis5.0.5的安裝過程與配置方法

    這篇文章主要介紹了Linux下redis5.0.5的安裝過程與配置方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Redis集群的實(shí)現(xiàn)全過程

    Redis集群的實(shí)現(xiàn)全過程

    Redis集群的實(shí)現(xiàn)方案主要有客戶端分片、代理模式和Cluster模式,其中,Cluster模式是Redis官方推薦的實(shí)現(xiàn)方案,它具有高可用性、高性能和自動(dòng)分片等優(yōu)點(diǎn)
    2024-12-12
  • Redis存儲斷點(diǎn)續(xù)傳文件狀態(tài)的最佳實(shí)踐

    Redis存儲斷點(diǎn)續(xù)傳文件狀態(tài)的最佳實(shí)踐

    在斷點(diǎn)續(xù)傳系統(tǒng)中,如何高效地存儲和更新文件上傳狀態(tài)是關(guān)鍵,得益于 Redis 高效的內(nèi)存操作和多種數(shù)據(jù)結(jié)構(gòu)的支持,它非常適合用于存儲上傳過程中的臨時(shí)狀態(tài)信息,下面,我們將探討如何利用 Redis 實(shí)現(xiàn)文件上傳狀態(tài)的存儲,需要的朋友可以參考下
    2024-12-12
  • 詳解redis分布式鎖的這些坑

    詳解redis分布式鎖的這些坑

    在很多互聯(lián)網(wǎng)產(chǎn)品應(yīng)用中,有些場景需要加鎖處理,比如:秒殺,全局遞增ID等等。大部分的解決方案是基于DB實(shí)現(xiàn)的,Redis為單進(jìn)程單線程模式,采用隊(duì)列模式將并發(fā)訪問變成串行訪問,且多客戶端對Redis的連接并不存在競爭關(guān)系。
    2021-05-05
  • Redis鍵遷移(move、dump、restore、migrate)的三種實(shí)現(xiàn)

    Redis鍵遷移(move、dump、restore、migrate)的三種實(shí)現(xiàn)

    鍵遷移就是把數(shù)據(jù)由一個(gè)Redis遷移到另一個(gè)Redis,本文主要介紹了Redis鍵遷移(move、dump、restore、migrate)的三種實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • 淺談redis加鎖常用幾種方式

    淺談redis加鎖常用幾種方式

    這篇文章主要介紹了淺談redis加鎖常用幾種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Redis數(shù)組和鏈表深入詳解

    Redis數(shù)組和鏈表深入詳解

    這篇文章主要介紹了Redis數(shù)組和鏈表深入詳解,這是redis的基礎(chǔ)的知識點(diǎn),有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03
  • 無法啟動(dòng)Redis打開redis-server閃退的問題解決辦法

    無法啟動(dòng)Redis打開redis-server閃退的問題解決辦法

    正常開啟redis服務(wù),首先要啟動(dòng)redis-server.exe,但是閃退,導(dǎo)致無法開啟redis服務(wù),這篇文章主要給大家介紹了關(guān)于無法啟動(dòng)Redis打開redis-server閃退問題的解決辦法,需要的朋友可以參考下
    2024-07-07

最新評論

潢川县| 措勤县| 临猗县| 屏东市| 本溪| 平武县| 大庆市| 余干县| 涪陵区| 咸阳市| 绥化市| 盐城市| 平度市| 临清市| 景谷| 东丰县| 海宁市| 鱼台县| 辽中县| 金沙县| 伊通| 桐梓县| 双柏县| 克拉玛依市| 自贡市| 潮安县| 枣阳市| 上高县| 军事| 广水市| 中超| 黄山市| 库车县| 安徽省| 正安县| 阿图什市| 江川县| 阿尔山市| 峨眉山市| 建宁县| 南乐县|