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

用Lua腳本實(shí)現(xiàn)Redis原子操作的示例

 更新時(shí)間:2025年03月13日 09:26:53   作者:Cloud_.  
本文主要介紹了用Lua腳本實(shí)現(xiàn)Redis原子操作的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1. 環(huán)境準(zhǔn)備

依賴(lài):在pom.xml中添加Spring Data Redis:

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

配置RedisTemplate:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

2. 編寫(xiě)Lua腳本

以分布式鎖為例,實(shí)現(xiàn)加鎖和解鎖的原子操作:

加鎖腳本 lock.lua

local key = KEYS[1]
local value = ARGV[1]
local expire = ARGV[2]
-- 如果key不存在則設(shè)置,并添加過(guò)期時(shí)間
if redis.call('setnx', key, value) == 1 then
    redis.call('expire', key, expire)
    return 1 -- 加鎖成功
else
    return 0 -- 加鎖失敗
end

解鎖腳本 unlock.lua

local key = KEYS[1]
local value = ARGV[1]
-- 只有鎖的值匹配時(shí)才刪除
if redis.call('get', key) == value then
    return redis.call('del', key)
else
    return 0
end

3. 加載并執(zhí)行腳本

定義腳本Bean:

@Configuration
public class LuaScriptConfig {
    @Bean
    public DefaultRedisScript<Long> lockScript() {
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setLocation(new ClassPathResource("lock.lua"));
        script.setResultType(Long.class);
        return script;
    }
}

調(diào)用腳本:

@Service
public class RedisLockService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private DefaultRedisScript<Long> lockScript;

    public boolean tryLock(String key, String value, int expireSec) {
        List<String> keys = Collections.singletonList(key);
        Long result = redisTemplate.execute(
                lockScript,
                keys,
                value,
                String.valueOf(expireSec)
        );
        return result != null && result == 1;
    }
}

開(kāi)發(fā)中的常見(jiàn)問(wèn)題與解決方案

1. Lua腳本緩存問(wèn)題

  • 問(wèn)題:每次執(zhí)行腳本會(huì)傳輸整個(gè)腳本內(nèi)容,增加網(wǎng)絡(luò)開(kāi)銷(xiāo)。
  • 解決:Redis會(huì)自動(dòng)緩存腳本并返回SHA1值,Spring Data Redis的DefaultRedisScript會(huì)自動(dòng)管理SHA1。確保腳本對(duì)象是單例,避免重復(fù)加載。

2. 參數(shù)傳遞錯(cuò)誤

問(wèn)題:KEYSARGV數(shù)量或類(lèi)型不匹配,導(dǎo)致腳本執(zhí)行失敗。

解決:明確區(qū)分參數(shù)類(lèi)型:

// 正確傳參示例
List<String> keys = Arrays.asList("key1", "key2"); // KEYS數(shù)組
Object[] args = new Object[]{"arg1", "arg2"};      // ARGV數(shù)組

3. Redis集群兼容性

問(wèn)題:集群模式下,所有操作的Key必須位于同一slot。

解決:使用{}定義hash tag,強(qiáng)制Key分配到同一節(jié)點(diǎn):

String key = "{user}:lock:" + userId; // 所有包含{user}的Key分配到同一節(jié)點(diǎn)

4. 腳本性能問(wèn)題

問(wèn)題:復(fù)雜Lua腳本可能阻塞Redis,影響性能。

解決:

  • 避免在Lua中使用循環(huán)或復(fù)雜邏輯。
  • 優(yōu)先使用Redis內(nèi)置命令(如SETNX、EXPIRE)。

5. 異常處理

問(wèn)題:腳本執(zhí)行超時(shí)或返回非預(yù)期結(jié)果。

解決:捕獲異常并設(shè)計(jì)重試機(jī)制:

public boolean tryLockWithRetry(String key, int maxRetry) {
    int retry = 0;
    while (retry < maxRetry) {
        if (tryLock(key, "value", 30)) {
            return true;
        }
        retry++;
        Thread.sleep(100); // 短暫等待
    }
    return false;
}

完整示例:分布式鎖

// 加鎖
public boolean lock(String key, String value, int expireSec) {
    return redisTemplate.execute(
        lockScript,
        Collections.singletonList(key),
        value,
        String.valueOf(expireSec)
    ) == 1;
}

// 解鎖
public void unlock(String key, String value) {
    Long result = redisTemplate.execute(
        unlockScript,
        Collections.singletonList(key),
        value
    );
    if (result == null || result == 0) {
        throw new RuntimeException("解鎖失?。烘i已過(guò)期或非持有者");
    }
}

調(diào)試與優(yōu)化建議

Redis CLI調(diào)試:

# 直接在Redis服務(wù)器測(cè)試腳本
EVAL "return redis.call('setnx', KEYS[1], ARGV[1])" 1 mykey 123

日志配置:

# application.properties
logging.level.org.springframework.data.redis=DEBUG

監(jiān)控腳本執(zhí)行時(shí)間:

# Redis慢查詢(xún)?nèi)罩?
slowlog-log-slower-than 5
slowlog-max-len 128

總結(jié)

通過(guò)Lua腳本,可以輕松實(shí)現(xiàn)Redis復(fù)雜操作的原子性,解決高并發(fā)下的競(jìng)態(tài)條件問(wèn)題。在Spring Boot中,結(jié)合RedisTemplateDefaultRedisScript,能夠高效集成Lua腳本。開(kāi)發(fā)時(shí)需注意參數(shù)傳遞、集群兼容性和異常處理,避免踩坑。

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

相關(guān)文章

  • 基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例(附源碼)

    基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例(附源碼)

    手機(jī)登錄驗(yàn)證在很多網(wǎng)頁(yè)上都得到使用,本文主要介紹了基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Redis實(shí)現(xiàn)庫(kù)存扣減的示例代碼

    Redis實(shí)現(xiàn)庫(kù)存扣減的示例代碼

    在日常開(kāi)發(fā)中有很多地方都有類(lèi)似扣減庫(kù)存的操作,本文主要介紹了Redis實(shí)現(xiàn)庫(kù)存扣減的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-07-07
  • 詳解Redis 數(shù)據(jù)類(lèi)型

    詳解Redis 數(shù)據(jù)類(lèi)型

    這篇文章主要介紹了Redis 數(shù)據(jù)類(lèi)型的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • 詳解redis在微服務(wù)領(lǐng)域的貢獻(xiàn)

    詳解redis在微服務(wù)領(lǐng)域的貢獻(xiàn)

    本文以dubbo為例看下redis是如何利用自身特性來(lái)完成注冊(cè)中心的功能,對(duì)redis微服務(wù)相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-10-10
  • 關(guān)于redisson緩存序列化的幾枚大坑說(shuō)明

    關(guān)于redisson緩存序列化的幾枚大坑說(shuō)明

    這篇文章主要介紹了redisson緩存序列化幾枚大坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • redis中的配置以及密碼設(shè)置方式

    redis中的配置以及密碼設(shè)置方式

    這篇文章主要介紹了redis中的配置以及密碼設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Redis的鍵String全面詳解

    Redis的鍵String全面詳解

    這篇文章主要為大家介紹了Redis的鍵String全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Redis?List列表相關(guān)命令的用法詳解

    Redis?List列表相關(guān)命令的用法詳解

    這篇文章主要為大家詳細(xì)介紹了Redis中List列表相關(guān)命令的用法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Redis的大Key對(duì)持久化影響分析

    Redis的大Key對(duì)持久化影響分析

    為了保證數(shù)據(jù)的持久性,Redis提供了兩種持久化的方式,本文主要介紹了Redis的大Key對(duì)持久化影響分析,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • redis使用watch秒殺搶購(gòu)實(shí)現(xiàn)思路

    redis使用watch秒殺搶購(gòu)實(shí)現(xiàn)思路

    這篇文章主要為大家詳細(xì)介紹了redis使用watch秒殺搶購(gòu)的實(shí)現(xiàn)思路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02

最新評(píng)論