欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis使用SETNX命令實現(xiàn)分布式鎖

 更新時間:2025年01月16日 08:20:06   作者:ppo92  
分布式鎖是一種用于在分布式系統(tǒng)中控制多個節(jié)點對共享資源進行訪問的機制,本文主要為大家詳細介紹了Redis如何使用SETNX命令實現(xiàn)分布式鎖,需要的可以參考下

什么是分布式鎖

分布式鎖是一種用于在分布式系統(tǒng)中控制多個節(jié)點對共享資源進行訪問的機制。在分布式系統(tǒng)中,由于多個節(jié)點可能同時訪問和修改同一個資源,因此需要一種方法來確保在任意時刻只有一個節(jié)點能夠?qū)Y源進行操作,以避免數(shù)據(jù)不一致或沖突。分布式鎖就是用來實現(xiàn)這種互斥訪問的工具。

為什么 Redis 的 SETNX 可以實現(xiàn)分布式鎖

Redis 的 SETNX 命令(即 SET if Not eXists)可以用來實現(xiàn)分布式鎖,原因如下:

  • 原子性SETNX 是一個原子操作,這意味著在同一時間只有一個客戶端能夠成功設(shè)置鍵值對。如果鍵已經(jīng)存在,SETNX 將不會執(zhí)行任何操作。這種原子性確保了鎖的獲取和釋放是線程安全的。
  • 唯一性SETNX 確保了鎖的唯一性。只有第一個嘗試設(shè)置鍵的客戶端能夠成功,其他客戶端在嘗試設(shè)置相同的鍵時會失敗。這模擬了鎖的“獲取”和“釋放”行為。
  • 過期時間:通過結(jié)合 EXPIRE 命令或使用 SET 命令的 EX 選項,可以為鎖設(shè)置一個過期時間。這防止了鎖被永久占用,即使客戶端在持有鎖期間崩潰或未能正確釋放鎖。
  • 分布式環(huán)境:Redis 是一個分布式內(nèi)存數(shù)據(jù)庫,可以在多個節(jié)點之間共享數(shù)據(jù)。因此,使用 Redis 實現(xiàn)的鎖可以在分布式系統(tǒng)中的多個節(jié)點之間共享,從而實現(xiàn)分布式鎖。
  • 高性能:Redis 是一個高性能的數(shù)據(jù)庫,能夠處理大量的并發(fā)請求。這使得 Redis 非常適合作為分布式鎖的實現(xiàn)基礎(chǔ)。

準(zhǔn)備工作

創(chuàng)建一個Spring Boot項目,并引入相關(guān)依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.yml文件中配置 Redis 連接信息:

server:
  port: 8080
spring:
  redis:
    host: xxx.xxx.xxx.xxx
    port: 6379
    password: xxxxxx

具體實現(xiàn)

創(chuàng)建分布式鎖工具類

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class DistributedLock {

    private final StringRedisTemplate redisTemplate;

    // 通過構(gòu)造函數(shù)注入 StringRedisTemplate
    public DistributedLock(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 嘗試獲取分布式鎖
     *
     * @param lockKey    鎖的鍵
     * @param requestId  請求標(biāo)識,用于區(qū)分不同的鎖持有者
     * @param expireTime 鎖的過期時間,單位為毫秒
     * @return 如果成功獲取鎖,返回 true;否則返回 false
     */
    public boolean acquireLock(String lockKey, String requestId, long expireTime) {
        // 使用 setIfAbsent 方法嘗試設(shè)置鍵值對,如果鍵不存在則設(shè)置成功并返回 true,否則返回 false
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS);
        return result != null && result;
    }

    /**
     * 釋放分布式鎖
     *
     * @param lockKey   鎖的鍵
     * @param requestId 請求標(biāo)識,用于確保只有鎖的持有者才能釋放鎖
     * @return 如果成功釋放鎖,返回 true;否則返回 false
     */
    public boolean releaseLock(String lockKey, String requestId) {
        // 獲取當(dāng)前鎖的值
        String currentValue = redisTemplate.opsForValue().get(lockKey);
        // 檢查當(dāng)前鎖的值是否等于請求標(biāo)識,確保只有鎖的持有者才能釋放鎖
        if (currentValue != null && currentValue.equals(requestId)) {
            // 刪除鎖鍵
            return redisTemplate.delete(lockKey);
        }
        return false;
    }
}

創(chuàng)建業(yè)務(wù)類用來測試

import com.wh.demo01.demos.web.utils.DistributedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class MyRedisService {

    private final DistributedLock distributedLock;

    // 通過構(gòu)造函數(shù)注入 DistributedLock
    @Autowired
    public MyRedisService(DistributedLock distributedLock) {
        this.distributedLock = distributedLock;
    }

    /**
     * 模擬需要同步執(zhí)行的方法
     */
    public void someMethod() {
        String lockKey = "myLockKey";
        String requestId = "uniqueRequestId";
        long expireTime = 10000; // 10 seconds

        try {
            // 嘗試獲取鎖
            if (distributedLock.acquireLock(lockKey, requestId, expireTime)) {
                // 獲取到鎖,執(zhí)行需要同步的操作
                System.out.println(new Date() + "獲取鎖成功");
                // 模擬業(yè)務(wù)操作
                Thread.sleep(5000);
            } else {
                System.out.println(new Date() + "獲取鎖失敗");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 確保鎖在操作完成后被釋放
            distributedLock.releaseLock(lockKey, requestId);
        }
    }
}

創(chuàng)建Controller

import com.wh.demo01.demos.web.service.MyRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired
    private MyRedisService service;

    @GetMapping("/test")
    public void TestRedis(){
        service.someMethod();
    }
}

整個項目結(jié)構(gòu)如下:

使用idea的復(fù)制配置功能將該服務(wù)復(fù)制一份,并指定端口為8081,模擬分布式服務(wù):

使用接口調(diào)試工具分別向80808081端口發(fā)送請求:

結(jié)果如下:

可見在分布式鎖的影響下,someMethod方法在10秒內(nèi)只能被調(diào)用一次。

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

相關(guān)文章

  • Redis的KEYS 命令千萬不能亂用

    Redis的KEYS 命令千萬不能亂用

    這篇文章主要介紹了Redis的KEYS 命令千萬不能亂用,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Redis數(shù)據(jù)庫的安裝配置方法

    Redis數(shù)據(jù)庫的安裝配置方法

    redis 是一個高性能的key-value數(shù)據(jù)庫。 redis的出現(xiàn),很大程度補償了memcached這類keyvalue存儲的不足,在部 分場合可以對關(guān)系數(shù)據(jù)庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便
    2014-06-06
  • Redisson分布式限流器RRateLimiter的使用及原理小結(jié)

    Redisson分布式限流器RRateLimiter的使用及原理小結(jié)

    本文主要介紹了Redisson分布式限流器RRateLimiter的使用及原理小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Redis Key過期監(jiān)聽的配置詳解

    Redis Key過期監(jiān)聽的配置詳解

    這篇文章主要介紹了Redis Key過期監(jiān)聽配置,默認(rèn)情況下在Windows系統(tǒng)中雙擊redis-server.exe用的是內(nèi)置的配置文件,文中通過代碼示例和圖文講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • Redis數(shù)據(jù)結(jié)構(gòu)原理淺析

    Redis數(shù)據(jù)結(jié)構(gòu)原理淺析

    這篇文章主要為大家介紹了Redis數(shù)據(jù)結(jié)構(gòu)原理淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Redis秒殺實現(xiàn)方案講解

    Redis秒殺實現(xiàn)方案講解

    這篇文章主要介紹了Redis秒殺實現(xiàn)方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • Redis數(shù)據(jù)過期策略的實現(xiàn)詳解

    Redis數(shù)據(jù)過期策略的實現(xiàn)詳解

    最近項目當(dāng)中遇到一個需求場景,需要清空一些存放在Redis的數(shù)據(jù),本文對Redis的過期機制簡單的講解一下,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Redis中統(tǒng)計各種數(shù)據(jù)大小的方法

    Redis中統(tǒng)計各種數(shù)據(jù)大小的方法

    這篇文章主要介紹了Redis中統(tǒng)計各種數(shù)據(jù)大小的方法,本文使用PHP實現(xiàn)統(tǒng)計Redis內(nèi)存占用比較大的鍵,需要的朋友可以參考下
    2015-03-03
  • Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例

    Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例

    本文主要介紹了 Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Redis實現(xiàn)分布式鎖詳解

    Redis實現(xiàn)分布式鎖詳解

    這篇文章主要介紹了redis如何實現(xiàn)分布式鎖,文章中有詳細的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-04-04

最新評論