App下載

Redisson實(shí)現(xiàn)分布式鎖:保證多節(jié)點(diǎn)環(huán)境下的數(shù)據(jù)一致性

幼兒園的高材生 2024-02-06 10:29:55 瀏覽數(shù) (1908)
反饋

在分布式系統(tǒng)中,為了保證多個(gè)節(jié)點(diǎn)之間對(duì)共享資源的訪問(wèn)的互斥性和線程安全性,常常需要使用分布式鎖。Redisson是一個(gè)基于Redis的Java庫(kù),提供了簡(jiǎn)單易用的API,可以幫助開(kāi)發(fā)人員實(shí)現(xiàn)分布式鎖。本文將介紹Redisson的分布式鎖的原理及使用方法,以及在多節(jié)點(diǎn)環(huán)境下實(shí)現(xiàn)數(shù)據(jù)一致性的方法。

Redisson簡(jiǎn)介

Redisson是一個(gè)基于Redis的開(kāi)源Java庫(kù),提供了一系列分布式對(duì)象和服務(wù),如分布式鎖、分布式集合、分布式映射、分布式消息隊(duì)列等。它封裝了Redis的底層通信協(xié)議和操作,提供了簡(jiǎn)單易用的API,使得開(kāi)發(fā)人員可以方便地使用Redis實(shí)現(xiàn)分布式系統(tǒng)。

redisson_h95_2

Redisson分布式鎖的原理

Redisson的分布式鎖基于Redis的單線程特性和原子操作實(shí)現(xiàn)。它通過(guò)在Redis中存儲(chǔ)一個(gè)特定的鍵值對(duì),來(lái)表示鎖的狀態(tài)。當(dāng)某個(gè)節(jié)點(diǎn)需要獲取鎖時(shí),它會(huì)嘗試在Redis中設(shè)置該鍵值對(duì),如果設(shè)置成功,則表示獲取到了鎖;否則,表示鎖已被其他節(jié)點(diǎn)持有,當(dāng)前節(jié)點(diǎn)需要等待。

為了避免死鎖和資源浪費(fèi),Redisson的分布式鎖還提供了超時(shí)機(jī)制和自動(dòng)釋放功能。當(dāng)獲取到鎖的節(jié)點(diǎn)執(zhí)行完業(yè)務(wù)邏輯后,會(huì)在規(guī)定的時(shí)間內(nèi)釋放鎖,以便其他節(jié)點(diǎn)可以獲取到鎖并執(zhí)行相關(guān)操作。

使用Redisson實(shí)現(xiàn)分布式鎖

1、添加 Redisson 框架支持

如果是 Spring Boot 項(xiàng)目,直接添加 Redisson 為 Spring Boot 寫(xiě)的如下依賴:

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson-spring-boot-starter</artifactId>
  <version>3.25.2</version> <!-- 請(qǐng)根據(jù)實(shí)際情況使用最新版本 -->
</dependency>

2、配置 RedissonClient 對(duì)象

將 RedissonClient 重寫(xiě),存放到 IoC 容器,并且配置連接的 Redis 服務(wù)器信息。

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        // 也可以將 redis 配置信息保存到配置文件
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

3、創(chuàng)建分布式鎖

Redisson 分布式鎖的操作和 Java 中的 ReentrantLock(可重入鎖)的操作很像,都是先使用 tryLock 嘗試獲取(非公平)鎖,最后再通過(guò) unlock 釋放鎖,具體實(shí)現(xiàn)如下:

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class LockController {
    @Autowired
    private RedissonClient redissonClient;
    @GetMapping("/lock")
    public String lockResource() throws InterruptedException {
        String lockKey = "myLock";
        // 獲取 RLock 對(duì)象
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 嘗試獲取鎖(嘗試加鎖)(鎖超時(shí)時(shí)間是 30 秒)
            boolean isLocked = lock.tryLock(30, TimeUnit.SECONDS);
            if (isLocked) {
                // 成功獲取到鎖
                try {
                    // 模擬業(yè)務(wù)處理
                    TimeUnit.SECONDS.sleep(5);
                    return "成功獲取鎖,并執(zhí)行業(yè)務(wù)代碼";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // 釋放鎖
                    lock.unlock();
                }
            } else {
                // 獲取鎖失敗
                return "獲取鎖失敗";
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "獲取鎖成功";
    }
}
實(shí)現(xiàn)公平鎖

Redisson 默認(rèn)創(chuàng)建的分布式鎖是非公平鎖(出于性能的考慮),想要把它變成公平鎖可使用以下代碼實(shí)現(xiàn):

RLock lock = redissonClient.getFairLock(lockKey);  // 獲取公平鎖
實(shí)現(xiàn)讀寫(xiě)鎖

Redisson 還可以創(chuàng)建讀寫(xiě)鎖,如下代碼所示:

RReadWriteLock lock = redissonClient.getReadWriteLock(lockKey); // 獲取讀寫(xiě)鎖
lock.readLock();  // 讀鎖
lock.writeLock(); // 寫(xiě)鎖

讀寫(xiě)鎖的特點(diǎn)就是并發(fā)性能高,它是允許多個(gè)線程同時(shí)獲取讀鎖進(jìn)行讀操作的,也就是說(shuō)在沒(méi)有寫(xiě)鎖的情況下,讀取操作可以并發(fā)執(zhí)行,提高了系統(tǒng)的并行度。但寫(xiě)鎖則是獨(dú)占式的,同一時(shí)間只有一個(gè)線程可以獲得寫(xiě)鎖,無(wú)論是讀還是寫(xiě)都無(wú)法與寫(xiě)鎖并存,這樣就確保了數(shù)據(jù)修改時(shí)的數(shù)據(jù)一致性。

實(shí)現(xiàn)聯(lián)鎖

Redisson 也支持聯(lián)鎖,也叫分布式多鎖 MultiLock,它允許客戶端一次性獲取多個(gè)獨(dú)立資源(RLock)上的鎖,這些資源可能是不同的鍵或同一鍵的不同鎖。當(dāng)所有指定的鎖都被成功獲取后,才會(huì)認(rèn)為整個(gè)操作成功鎖定。這樣能夠確保在分布式環(huán)境下進(jìn)行跨資源的并發(fā)控制。聯(lián)鎖的實(shí)現(xiàn)示例如下:

// 獲取需要加鎖的資源
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
// 聯(lián)鎖
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
try {
    // 一次性嘗試獲取所有鎖
    if (multiLock.tryLock()) {
        // 獲取鎖成功...
    }
} finally {
    // 釋放所有鎖
    multiLock.unlock();
}

總結(jié)

分布式鎖是保證多節(jié)點(diǎn)環(huán)境下數(shù)據(jù)一致性的重要工具之一。Redisson提供了簡(jiǎn)單易用的API,可以幫助開(kāi)發(fā)人員實(shí)現(xiàn)分布式鎖。本文介紹了Redisson分布式鎖的原理和使用方法,并提供了在多節(jié)點(diǎn)環(huán)境下實(shí)現(xiàn)數(shù)據(jù)一致性的方法。通過(guò)合理地使用Redisson的分布式鎖,開(kāi)發(fā)人員可以確保在分布式系統(tǒng)中對(duì)共享資源的訪問(wèn)是安全可靠的,從而提高系統(tǒng)的可靠性和性能。總之,Redisson是一個(gè)強(qiáng)大的工具,可以幫助開(kāi)發(fā)人員實(shí)現(xiàn)分布式鎖和數(shù)據(jù)一致性。通過(guò)合理地使用Redisson的分布式鎖功能,開(kāi)發(fā)人員可以構(gòu)建高可靠性、高性能的分布式系統(tǒng)。

0 人點(diǎn)贊