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

Redis SETNX的實(shí)現(xiàn)示例

 更新時(shí)間:2024年12月27日 11:04:28   作者:飛滕人生TYF  
SETNX是Redis提供的原子操作,用于在指定鍵不存在時(shí)設(shè)置鍵值,并返回操作結(jié)果,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

SETNX 是 Redis 提供的一種原子操作,全稱是 “SET if Not eXists”,用于在指定的鍵不存在時(shí)設(shè)置鍵值,并返回操作結(jié)果。它是實(shí)現(xiàn)分布式鎖冪等性控制的核心工具之一。

1. SETNX 的基本功能

語(yǔ)法

SETNX key value
  • key:需要設(shè)置的鍵。
  • value:需要設(shè)置的值。

返回值

  • 1:如果鍵不存在,設(shè)置成功。
  • 0:如果鍵已經(jīng)存在,不執(zhí)行任何操作。

使用示例

SETNX lock_key "123"

執(zhí)行結(jié)果

  • 如果 lock_key 不存在,則設(shè)置鍵值為 "123",并返回 1。
  • 如果 lock_key 已存在,則不執(zhí)行任何操作,返回 0

2. SETNX 的特性

  • 原子性

    • SETNX 是 Redis 的原子操作,多個(gè)客戶端并發(fā)訪問時(shí),只會(huì)有一個(gè)操作成功。
  • 冪等性

    • 如果鍵已存在,則后續(xù)的 SETNX 調(diào)用不會(huì)影響當(dāng)前值。
  • 輕量級(jí)鎖

    • SETNX 常用于實(shí)現(xiàn)分布式鎖,通過確保某個(gè)鍵唯一存在來鎖定資源。

3. 結(jié)合 EXPIRE 的分布式鎖

SETNX 本身不能設(shè)置過期時(shí)間,因此為了避免死鎖問題(如客戶端異常未釋放鎖),可以結(jié)合 EXPIRE 設(shè)置鎖的自動(dòng)過期時(shí)間。

問題

  • 如果一個(gè)客戶端使用 SETNX 獲取鎖,卻因異常無(wú)法釋放鎖,其他客戶端可能會(huì)永遠(yuǎn)無(wú)法獲取鎖。

解決方案 1:SETNX + EXPIRE

  • 使用 SETNX 設(shè)置鎖。
  • 如果鎖設(shè)置成功,立即設(shè)置過期時(shí)間。
if redis.call("SETNX", KEYS[1], ARGV[1]) == 1 then
    redis.call("EXPIRE", KEYS[1], ARGV[2])
    return 1
else
    return 0
end

缺點(diǎn)

  • SETNX 和 EXPIRE 是兩個(gè)獨(dú)立操作,在高并發(fā)情況下可能出現(xiàn)非原子性問題。

解決方案 2:SETNX 改用 SET(推薦)

Redis 提供了改進(jìn)版本的 SET 命令,可以直接設(shè)置鍵值并附加過期時(shí)間:

SET key value NX EX seconds
  • NX:表示僅當(dāng)鍵不存在時(shí)才執(zhí)行設(shè)置操作(相當(dāng)于 SETNX)。
  • EX seconds:設(shè)置過期時(shí)間,單位為秒。

示例

SET lock_key "123" NX EX 10
  • 如果 lock_key 不存在,設(shè)置值為 "123",且鍵將在 10 秒后過期。

優(yōu)點(diǎn)

  • 原子操作,無(wú)需再單獨(dú)調(diào)用 EXPIRE

4. 使用 SETNX 實(shí)現(xiàn)分布式鎖

SETNX 的一個(gè)典型應(yīng)用是分布式鎖,保證在分布式系統(tǒng)中對(duì)共享資源的互斥訪問。

4.1 基本實(shí)現(xiàn)

  • 獲取鎖

    • 使用 SETNX 嘗試設(shè)置一個(gè)鍵。
    • 設(shè)置成功,表示成功獲取鎖。
  • 釋放鎖

    • 檢查當(dāng)前鎖是否屬于自己(通過唯一標(biāo)識(shí)區(qū)分),如果是,則刪除鎖。

實(shí)現(xiàn)邏輯

String lockKey = "lock_key";
String requestId = UUID.randomUUID().toString();
int expireTime = 10;

// 獲取鎖
if (redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS)) {
    try {
        // 處理業(yè)務(wù)邏輯
    } finally {
        // 釋放鎖
        if (requestId.equals(redisTemplate.opsForValue().get(lockKey))) {
            redisTemplate.delete(lockKey);
        }
    }
} else {
    // 獲取鎖失敗
    System.out.println("Lock is already held by another process.");
}

4.2 Lua 腳本保證原子性

為了確保釋放鎖的操作是原子的,可以使用 Lua 腳本完成判斷和刪除:

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

調(diào)用示例

String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else return 0 end";
redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), 
                      Collections.singletonList(lockKey), requestId);

5. SETNX 的典型應(yīng)用場(chǎng)景

5.1 分布式鎖

  • 確保資源互斥訪問,防止并發(fā)修改造成數(shù)據(jù)錯(cuò)誤。

5.2 請(qǐng)求去重

  • 對(duì)同一用戶的重復(fù)請(qǐng)求設(shè)置唯一標(biāo)識(shí),防止重復(fù)處理。
  • 示例:使用 SETNX 設(shè)置請(qǐng)求 ID,只有第一次請(qǐng)求會(huì)被處理。

5.3 冪等性控制

  • 確保某些操作(如支付、扣款)不會(huì)因重復(fù)請(qǐng)求而執(zhí)行多次。

6. SETNX 的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)缺點(diǎn)
原子性強(qiáng),適合高并發(fā)場(chǎng)景無(wú)法直接設(shè)置過期時(shí)間
實(shí)現(xiàn)簡(jiǎn)單,易于集成到業(yè)務(wù)邏輯中需要結(jié)合 EXPIRE 或改用 SET 命令
性能高,Redis 本身支持高吞吐量需要額外處理死鎖或鎖釋放的邊界條件

7. SETNX 的改進(jìn)建議

  • 盡量使用 SET key value NX EX seconds 替代 SETNX

    • 提供了原生的過期時(shí)間設(shè)置,簡(jiǎn)化了分布式鎖的實(shí)現(xiàn)。
  • 結(jié)合 Lua 腳本

    • 使用 Lua 腳本處理復(fù)雜邏輯,保證操作的原子性。
  • 監(jiān)控鎖的狀態(tài)

    • 對(duì)于長(zhǎng)期持有鎖的操作,應(yīng)增加心跳機(jī)制,防止鎖意外釋放。
  • 鎖爭(zhēng)搶優(yōu)化

    • 避免高并發(fā)環(huán)境下大量線程重復(fù)嘗試獲取鎖,可以結(jié)合延時(shí)隊(duì)列或限流機(jī)制。

8. 總結(jié)

  • SETNX 是 Redis 中一種簡(jiǎn)單、高效的原子操作,主要用于確保鍵不存在時(shí)的設(shè)置操作。
  • 它是實(shí)現(xiàn)分布式鎖的基礎(chǔ),但需要與 EXPIRE 或其他命令結(jié)合使用,避免死鎖問題。
  • 在現(xiàn)代應(yīng)用中,建議優(yōu)先使用 Redis 的 SET NX EX 命令,進(jìn)一步提升功能的原子性和易用性。
  • 合理利用 SETNX,可以在分布式場(chǎng)景中有效解決資源爭(zhēng)搶、重復(fù)請(qǐng)求和冪等性問題。

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

相關(guān)文章

  • 安裝redis(windows和Ubuntu)詳解

    安裝redis(windows和Ubuntu)詳解

    這篇文章主要介紹了Redis在Ubuntu和Windows下的安裝,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • redis緩存的簡(jiǎn)單操作(get、put)

    redis緩存的簡(jiǎn)單操作(get、put)

    這篇文章主要介紹了redis緩存的簡(jiǎn)單操作,包括引入jedisjar包、配置redis、RedisDao需要的一些工具等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 如何在SpringBoot中使用Redis實(shí)現(xiàn)分布式鎖

    如何在SpringBoot中使用Redis實(shí)現(xiàn)分布式鎖

    這篇文章主要介紹了如何在SpringBoot中使用Redis實(shí)現(xiàn)分布式鎖,在實(shí)際開發(fā)中有可能會(huì)遇到多個(gè)線程同時(shí)訪問同一個(gè)共享變量,那么上鎖就很重要了,需要的朋友可以參考下
    2023-03-03
  • Redis使用命令行與多數(shù)據(jù)庫(kù)配置

    Redis使用命令行與多數(shù)據(jù)庫(kù)配置

    本文詳細(xì)講解了Redis使用命令行與多數(shù)據(jù)庫(kù)配置的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • Redis的持久化方式

    Redis的持久化方式

    Redis提供了兩種主要的持久化方式:RDB和AOF,RDB通過定時(shí)快照的方式保存數(shù)據(jù)狀態(tài),而AOF記錄每個(gè)寫操作以便于重啟時(shí)重放,兩者可以結(jié)合使用,且在重啟時(shí)AOF文件會(huì)被優(yōu)先用于數(shù)據(jù)恢復(fù),RDB快照具有速度快、節(jié)省磁盤空間的優(yōu)點(diǎn),但可能會(huì)丟失最近的數(shù)據(jù)
    2024-10-10
  • 了解Redis常見應(yīng)用場(chǎng)景

    了解Redis常見應(yīng)用場(chǎng)景

    Redis是一個(gè)key-value存儲(chǔ)系統(tǒng),現(xiàn)在在各種系統(tǒng)中的使用越來越多,大部分情況下是因?yàn)槠涓咝阅艿奶匦?,被?dāng)做緩存使用,這里介紹下Redis經(jīng)常遇到的使用場(chǎng)景
    2021-06-06
  • Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存并用log4j2進(jìn)行日志記錄的過程分享

    Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存并用log4j2進(jìn)行日志記錄的過程分享

    這篇文章主要介紹了Linux服務(wù)器使用Redis作為數(shù)據(jù)緩存并用log4j2日志記錄,關(guān)于SpringBoot項(xiàng)目配置Redis與log4j2是查詢官方文檔,本文中的Redis配置類、Redis工具類以及l(fā)og4j2.xml配置文件來自網(wǎng)絡(luò),查證源自何處比較麻煩,所以在此感謝所有人的分享
    2023-09-09
  • 關(guān)于redigo中PubSub的一點(diǎn)小坑分析

    關(guān)于redigo中PubSub的一點(diǎn)小坑分析

    這篇文章主要給大家介紹了關(guān)于redigo中PubSub的一點(diǎn)小坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 基于Redis實(shí)現(xiàn)API接口訪問次數(shù)限制

    基于Redis實(shí)現(xiàn)API接口訪問次數(shù)限制

    日常開發(fā)中會(huì)有一個(gè)常見的需求,需要限制接口在單位時(shí)間內(nèi)的訪問次數(shù),比如說某個(gè)免費(fèi)的接口限制單個(gè)IP一分鐘內(nèi)只能訪問5次,該怎么實(shí)現(xiàn)呢,本文小編給大家介紹了如何基于Redis實(shí)現(xiàn)API接口訪問次數(shù)限制,需要的朋友可以參考下
    2024-11-11
  • Redis分布式鎖一定要避開的兩個(gè)坑

    Redis分布式鎖一定要避開的兩個(gè)坑

    這篇文章主要為大家詳細(xì)介紹了Redis中分布式鎖一定要避開的兩個(gè)坑以及對(duì)應(yīng)的解決方法,文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助
    2023-04-04

最新評(píng)論