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

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

 更新時(shí)間:2025年04月16日 08:25:21   作者:今天多喝熱水  
本文主要介紹了Redis分布式鎖的幾種實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Redis基本命令:

// 設(shè)置鍵myKey的值為myValue,并且該鍵在10秒后過(guò)期
SET myKey myValue EX 10
// 設(shè)置鍵myKey的值為myValue,并且該鍵在1000毫秒(1秒)后過(guò)期
SET myKey myValue PX 1000
// 指定key過(guò)期時(shí)間,單位是秒,過(guò)期后自動(dòng)刪除
EXPIRE key_name second_num
// 指定key過(guò)期時(shí)間,單位是毫秒,過(guò)期后自動(dòng)刪除
PEXPIRE key_name millisecond_num

// 返回key過(guò)期時(shí)間
TTL key_name 

SET key value	 //設(shè)置鍵key的值為value
SETNX key value	 //只有在鍵key不存在的情況下,將key的值設(shè)置為value
SETEX key seconds value	 //將鍵key的值設(shè)置為value,并且超時(shí)時(shí)間為seconds秒
PSETEX key milliseconds value  //將鍵key的值設(shè)置為value,并且超時(shí)時(shí)間為milliseconds毫秒

一、基礎(chǔ)方案:SETNX命令實(shí)現(xiàn)

public class SimpleRedisLock {
    private Jedis jedis;
    private String lockKey;

    public SimpleRedisLock(Jedis jedis, String lockKey) {
        this.jedis = jedis;
        this.lockKey = lockKey;
    }
    public boolean tryLock() {
        Long result = jedis.setnx(lockKey, "locked");
        if (result == 1) {
            jedis.expire(lockKey, 30); // 設(shè)置過(guò)期時(shí)間
            return true;
        }
        return false;
    }
    public void unlock() {
        jedis.del(lockKey);
    }
}

// 使用示例
Jedis jedis = new Jedis("localhost");
SimpleRedisLock lock = new SimpleRedisLock(jedis, "order_lock");
try{
    if(lock.tryLock()){
    // 業(yè)務(wù)邏輯
    }
} finally {
    lock.unlock();
}

問(wèn)題分析:

  • 非原子操作:setnx和expire非原子操作,可能產(chǎn)生死鎖
  • 鎖誤刪:任何客戶端都可以刪除鎖
  • 不可重入:同一線程重復(fù)獲取會(huì)失敗

二、改進(jìn)方案:原子SET命令

public class AtomicRedisLock {
    private Jedis jedis;
    private String lockKey;
    private String clientId;

    public SimpleRedisLock(Jedis jedis, String lockKey) {
        this.jedis = jedis;
        this.lockKey = lockKey;
        this.clientId = UUID.randomUUID().toString();
    }
    public boolean tryLock(int expireSeconds) {
        String result = jedis.set(lockKey, clientId, SetParams.setParams().nx().ex(expireSeconds));
        return "OK".equals(result);
    }
    public boolean unlock() {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(clientId));
        return result.equals(1L);
    }
}

// 使用示例
Jedis jedis = new Jedis("localhost");
AtomicRedisLock lock = new AtomicRedisLock(jedis, "payment_lock");
try{
    if(lock.tryLock(30)){
    // 業(yè)務(wù)邏輯
    }
} finally {
    lock.unlock();
}

核心改進(jìn):

  • 使用原子SET命令:SET key value NX EX
  • Lua腳本保證刪除原子性
  • 客戶端唯一標(biāo)識(shí)防止誤刪

仍然存在的問(wèn)題:

  • 鎖續(xù)期困難
  • 單點(diǎn)故障風(fēng)險(xiǎn)
  • 業(yè)務(wù)超時(shí)可能導(dǎo)致鎖失效

三、高可用方案:RedLock算法

public class RedLock {
    pprivate List<Jedis> jedisList;
    private String lockKey;
    private String clientId;
    private int quorum;

    public RedLock(List<Jedis> jedisList, String lockKey) {
        this.jedisList = jedisList;
        this.lockKey = lockKey;
        this.clientId = UUID.randomUUID().toString();
        this.quorum = jedisList.size() / 2 + 1;
    }
    public boolean tryLock(int expireMillis) {
        long startTime = System.currentTimeMillis();
        // 第一階段:嘗試獲取多數(shù)節(jié)點(diǎn)鎖
        int successCount = 0;
        for (Jedis jedis : jedisList) {
            if (tryAcquire(jedis, expireMillis)) {
                successCount++;
            }
            if ((System.currentTimeMillis() - startTime) > expireMillis) {
                break;
            }
        }
        // 第二階段:驗(yàn)證鎖有效性
        if (successCount >= quorum) {
            long validityTime = expireMillis - (System.currentTimeMillis() - startTime);
            return validityTime > 0;
        }
        // 第三階段:釋放已獲得的鎖
        for (Jedis jedis : jedisList) {
            release(jedis);
        }
        return false;
    }
    private boolean tryAcquire(Jedis jedis, long expireMillis) {
        try {
            String result = jedis.set(lockKey, clientId, SetParams.setParams().nx().px(expireMillis));
            return "OK".equals(result);
        } catch (Exception e) {
            return false;
        }
    }
    private void release(Jedis jedis) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) else return 0 end";
        jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(clientId));
    }
}

部署要求:

  • 至少5個(gè)獨(dú)立Redis實(shí)例
  • 節(jié)點(diǎn)間時(shí)鐘同步
  • 需要配置合理的超時(shí)時(shí)間

適用場(chǎng)景:

  • 金融交易等對(duì)可靠性要求極高的場(chǎng)景
  • 需要跨機(jī)房部署的分布式系統(tǒng)

四、生產(chǎn)級(jí)方案:Redisson實(shí)現(xiàn)

// 配置Redisson客戶端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 獲取鎖對(duì)象
RLock lock = redisson.getLock("orderLock");
try {
    // 嘗試加鎖,最多等待100秒,鎖定后30秒自動(dòng)解鎖
    boolean isLock = lock.tryLock(100, 30, TimeUnit.SECONDS);
    if (isLock) {
        // 處理業(yè)務(wù)
    }
} finally {
    lock.unlock();
}

// 關(guān)閉客戶端
redisson.shutdown();
// 自動(dòng)續(xù)期機(jī)制(Watchdog),Watchdog實(shí)現(xiàn)原理(簡(jiǎn)化版)
private void renewExpiration() {
    Timeout task = commandExecutor.schedule(() -> {
        if (redisClient.eval(...)){ // 檢查是否仍持有鎖
            expireAsync(); // 續(xù)期
            renewExpiration(); // 遞歸調(diào)用
        }
    }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
}

核心特性:

  • 支持可重入鎖
  • 提供公平鎖、聯(lián)鎖(MultiLock)、紅鎖(RedLock)實(shí)現(xiàn)
  • 完善的故障處理機(jī)制

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

相關(guān)文章

  • 解決redis在linux上的部署的問(wèn)題

    解決redis在linux上的部署的問(wèn)題

    這篇文章主要介紹了redis在linux上的部署,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Redis Tag 字段詳解與最佳實(shí)踐

    Redis Tag 字段詳解與最佳實(shí)踐

    本文將深入介紹Tag 字段的工作原理、創(chuàng)建方式、查詢語(yǔ)法,以及常見(jiàn)場(chǎng)景下的最佳實(shí)踐與注意事項(xiàng),對(duì)Redis Tag字段相關(guān)知識(shí)感興趣的朋友一起看看吧
    2025-07-07
  • Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例

    Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例

    Redis提供了一些機(jī)制來(lái)保護(hù)敏感數(shù)據(jù)和限制對(duì)Redis服務(wù)器的訪問(wèn),本文主要介紹了Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • redis緩存預(yù)熱的實(shí)現(xiàn)示例

    redis緩存預(yù)熱的實(shí)現(xiàn)示例

    本文主要介紹了Java中實(shí)現(xiàn)緩存預(yù)熱的多種策略,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • 利用redis實(shí)現(xiàn)分布式鎖,快速解決高并發(fā)時(shí)的線程安全問(wèn)題

    利用redis實(shí)現(xiàn)分布式鎖,快速解決高并發(fā)時(shí)的線程安全問(wèn)題

    這篇文章主要介紹了利用redis實(shí)現(xiàn)分布式鎖,快速解決高并發(fā)時(shí)的線程安全問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Redis?使用?List?實(shí)現(xiàn)消息隊(duì)列的優(yōu)缺點(diǎn)

    Redis?使用?List?實(shí)現(xiàn)消息隊(duì)列的優(yōu)缺點(diǎn)

    這篇文章主要介紹了Redis?使用?List?實(shí)現(xiàn)消息隊(duì)列有哪些利弊,小編結(jié)合消息隊(duì)列的特點(diǎn)一步步帶大家分析使用?Redis?的?List?作為消息隊(duì)列的實(shí)現(xiàn)原理,并分享如何把?SpringBoot?與?Redission?整合運(yùn)用到項(xiàng)目中,需要的朋友可以參考下
    2022-01-01
  • 查看Redis內(nèi)存信息的命令

    查看Redis內(nèi)存信息的命令

    Redis 是一個(gè)開(kāi)源、高性能的Key-Value數(shù)據(jù)庫(kù),被廣泛應(yīng)用在服務(wù)器各種場(chǎng)景中。本文介紹幾個(gè)查看Redis內(nèi)存信息的命令,包括常用的info memory、info keyspace、bigkeys等。
    2020-09-09
  • Redis生成全局唯一ID的實(shí)現(xiàn)方法

    Redis生成全局唯一ID的實(shí)現(xiàn)方法

    全局唯一ID生成器是一種在分布式系統(tǒng)下用來(lái)生成全局唯一ID的工具,本文主要介紹了Redis生成全局唯一ID的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-06-06
  • redis中bind配置的詳細(xì)步驟

    redis中bind配置的詳細(xì)步驟

    本文主要介紹了redis中bind配置的詳細(xì)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • redis中key的設(shè)置方法步驟

    redis中key的設(shè)置方法步驟

    在本篇文章里小編給大家分享了關(guān)于redis中key的設(shè)置方法步驟以及相關(guān)知識(shí)點(diǎn),有興趣的朋友們學(xué)習(xí)參考下。
    2019-07-07

最新評(píng)論

乌鲁木齐市| 西乌珠穆沁旗| 永寿县| 太康县| 缙云县| 光泽县| 灵川县| 兴化市| 陆丰市| 龙岩市| 汉源县| 龙井市| 亚东县| 乌拉特前旗| 灵宝市| 申扎县| 讷河市| 安阳县| 炉霍县| 华亭县| 张北县| 霞浦县| 尤溪县| 丽水市| 洞头县| 仙桃市| 光泽县| 闵行区| 虎林市| 迁安市| 武功县| 韶关市| 始兴县| 新巴尔虎右旗| 益阳市| 澄城县| 浦北县| 长乐市| 丽水市| 静宁县| 安丘市|