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

淺析Redis中紅鎖RedLock的實現(xiàn)原理

 更新時間:2024年02月28日 09:35:06   作者:Java中文社群  
RedLock?是一種分布式鎖的實現(xiàn)算法,由?Redis?的作者?Salvatore?Sanfilippo(也稱為?Antirez)提出,本文主要為大家詳細介紹了紅鎖RedLock的實現(xiàn)原理,感興趣的可以了解下

RedLock 是一種分布式鎖的實現(xiàn)算法,由 Redis 的作者 Salvatore Sanfilippo(也稱為 Antirez)提出,主要用于解決在分布式系統(tǒng)中實現(xiàn)可靠鎖的問題。在 Redis 單獨節(jié)點的基礎(chǔ)上,RedLock 使用了多個獨立的 Redis 實例(通常建議是奇數(shù)個,比如 5 個),共同協(xié)作來提供更強健的分布式鎖服務(wù)。

RedLock 算法旨在解決單個 Redis 實例作為分布式鎖時可能出現(xiàn)的單點故障問題,通過在多個獨立運行的 Redis 實例上同時獲取鎖的方式來提高鎖服務(wù)的可用性和安全性。

RedLock 具備以下主要特性:

  • 互斥性:在任何時間,只有一個客戶端可以獲得鎖,確保了資源的互斥訪問。
  • 避免死鎖:通過為鎖設(shè)置一個較短的過期時間,即使客戶端在獲得鎖后由于網(wǎng)絡(luò)故障等原因未能按時釋放鎖,鎖也會因為過期而自動釋放,避免了死鎖的發(fā)生。
  • 容錯性:即使一部分 Redis 節(jié)點宕機,只要大多數(shù)節(jié)點(即過半數(shù)以上的節(jié)點)仍在線,RedLock 算法就能繼續(xù)提供服務(wù),并確保鎖的正確性。

1.RedLock 實現(xiàn)思路

RedLock 是對集群的每個節(jié)點進行加鎖,如果大多數(shù)節(jié)點(N/2+1)加鎖成功,則才會認(rèn)為加鎖成功。

這樣即使集群中有某個節(jié)點掛掉了,因為大部分集群節(jié)點都加鎖成功了,所以分布式鎖還是可以繼續(xù)使用的。

2.工作流程

RedLock 算法的工作流程大致如下:

  • 客戶端向多個獨立的 Redis 實例嘗試獲取鎖,設(shè)置鎖的過期時間非常短。
  • 如果客戶端能在大部分節(jié)點上成功獲取鎖,并且所花費的時間小于鎖的過期時間的一半,那么認(rèn)為客戶端成功獲取到了分布式鎖。
  • 當(dāng)客戶端完成對受保護資源的操作后,它需要向所有曾獲取鎖的 Redis 實例釋放鎖。
  • 若在釋放鎖的過程中,客戶端因故無法完成,由于設(shè)置了鎖的過期時間,鎖最終會自動過期釋放,避免了死鎖。

3.基本使用

在 Java 開發(fā)中,可以使用 Redisson 框架很方便的實現(xiàn) RedLock,具體操作代碼如下:

import org.redisson.Redisson;
import org.redisson.api.RedisClient;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.redisson.RedissonRedLock;

public class RedLockDemo {

    public static void main(String[] args) {
        // 創(chuàng)建 Redisson 客戶端配置
        Config config = new Config();
        config.useClusterServers()
        .addNodeAddress("redis://127.0.0.1:6379",
                        "redis://127.0.0.1:6380",
                        "redis://127.0.0.1:6381"); // 假設(shè)有三個 Redis 節(jié)點
        // 創(chuàng)建 Redisson 客戶端實例
        RedissonClient redissonClient = Redisson.create(config);
        // 創(chuàng)建 RedLock 對象
        RedissonRedLock redLock = redissonClient.getRedLock("resource");
        try {
            // 嘗試獲取分布式鎖,最多嘗試 5 秒獲取鎖,并且鎖的有效期為 5000 毫秒
            boolean lockAcquired = redLock.tryLock(5, 5000, TimeUnit.MILLISECONDS); 
            if (lockAcquired) {
                // 加鎖成功,執(zhí)行業(yè)務(wù)代碼...
            } else {
                System.out.println("Failed to acquire the lock!");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Interrupted while acquiring the lock");
        } finally {
            // 無論是否成功獲取到鎖,在業(yè)務(wù)邏輯結(jié)束后都要釋放鎖
            if (redLock.isLocked()) {
                redLock.unlock();
            }
            // 關(guān)閉 Redisson 客戶端連接
            redissonClient.shutdown();
        }
    }
}

4.實現(xiàn)原理

Redisson 中的 RedLock 是基于 RedissonMultiLock(聯(lián)鎖)實現(xiàn)的。

RedissonMultiLock 是 Redisson 提供的一種分布式鎖類型,它可以同時操作多個鎖,以達到對多個鎖進行統(tǒng)一管理的目的。聯(lián)鎖的操作是原子性的,即要么全部鎖住,要么全部解鎖。這樣可以保證多個鎖的一致性。

RedissonMultiLock 使用示例如下:

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.multi.MultiLock;

public class RedissonMultiLockDemo {

    public static void main(String[] args) throws InterruptedException {
        // 創(chuàng)建 Redisson 客戶端
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);

        // 創(chuàng)建多個分布式鎖實例
        RLock lock1 = redisson.getLock("lock1");
        RLock lock2 = redisson.getLock("lock2");
        RLock lock3 = redisson.getLock("lock3");

        // 創(chuàng)建 RedissonMultiLock 對象
        MultiLock multiLock = new MultiLock(lock1, lock2, lock3);

        // 加鎖
        multiLock.lock();
        try {
            // 執(zhí)行任務(wù)
            System.out.println("Lock acquired. Task started.");
            Thread.sleep(3000);
            System.out.println("Task finished. Releasing the lock.");
        } finally {
            // 釋放鎖
            multiLock.unlock();
        }
        // 關(guān)閉客戶端連接
        redisson.shutdown();
    }
}

在示例中,我們首先創(chuàng)建了一個 Redisson 客戶端并連接到 Redis 服務(wù)器。然后,我們使用 redisson.getLock 方法創(chuàng)建了多個分布式鎖實例。接下來,我們通過傳入這些鎖實例來創(chuàng)建了 RedissonMultiLock 對象。

說回正題,RedissonRedLock 是基于 RedissonMultiLock 實現(xiàn)的這點,可以從繼承關(guān)系看出。

RedissonRedLock 繼承自 RedissonMultiLock,核心實現(xiàn)源碼如下:

public class RedissonRedLock extends RedissonMultiLock {
    public RedissonRedLock(RLock... locks) {
        super(locks);
    }

    /**
     * 鎖可以失敗的次數(shù),鎖的數(shù)量-鎖成功客戶端最小的數(shù)量
     */
    @Override
    protected int failedLocksLimit() {
        return locks.size() - minLocksAmount(locks);
    }

    /**
     * 鎖的數(shù)量 / 2 + 1,例如有3個客戶端加鎖,那么最少需要2個客戶端加鎖成功
     */
    protected int minLocksAmount(final List<RLock> locks) {
        return locks.size()/2 + 1;
    }

    /** 
     * 計算多個客戶端一起加鎖的超時時間,每個客戶端的等待時間
     */
    @Override
    protected long calcLockWaitTime(long remainTime) {
        return Math.max(remainTime / locks.size(), 1);
    }

    @Override
    public void unlock() {
        unlockInner(locks);
    }
}

從上述源碼可以看出,Redisson 中的 RedLock 是基于 RedissonMultiLock(聯(lián)鎖)實現(xiàn)的,當(dāng) RedLock 是對集群的每個節(jié)點進行加鎖,如果大多數(shù)節(jié)點,也就是 N/2+1 個節(jié)點加鎖成功,則認(rèn)為 RedLock 加鎖成功。

5.存在問題

RedLock 主要存在以下兩個問題:

性能問題:RedLock 要等待大多數(shù)節(jié)點返回之后,才能加鎖成功,而這個過程中可能會因為網(wǎng)絡(luò)問題,或節(jié)點超時的問題,影響加鎖的性能。

并發(fā)安全性問題:當(dāng)客戶端加鎖時,如果遇到 GC 可能會導(dǎo)致加鎖失效,但 GC 后誤認(rèn)為加鎖成功的安全事故,例如以下流程:

客戶端 A 請求 3 個節(jié)點進行加鎖。

在節(jié)點回復(fù)處理之前,客戶端 A 進入 GC 階段(存在 STW,全局停頓)。

之后因為加鎖時間的原因,鎖已經(jīng)失效了。

客戶端 B 請求加鎖(和客戶端 A 是同一把鎖),加鎖成功。

客戶端 A GC 完成,繼續(xù)處理前面節(jié)點的消息,誤以為加鎖成功。

此時客戶端 B 和客戶端 A 同時加鎖成功,出現(xiàn)并發(fā)安全性問題。

6.已廢棄的 RedLock

因為 RedLock 存在的問題爭議較大,且沒有完美的解決方案,所以 Redisson 中已經(jīng)廢棄了 RedLock,這一點在 Redisson 官方文檔中能找到,如下圖所示:

課后思考

既然 RedLock 已經(jīng)被廢棄,那么想要實現(xiàn)分布式鎖,同時又想避免 Redis 單點故障問題,應(yīng)該使用哪種解決方案呢?

到此這篇關(guān)于淺析Redis中紅鎖RedLock的實現(xiàn)原理的文章就介紹到這了,更多相關(guān)Redis紅鎖RedLock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何利用Redis?List實現(xiàn)Java數(shù)據(jù)庫分頁快速查詢

    如何利用Redis?List實現(xiàn)Java數(shù)據(jù)庫分頁快速查詢

    這篇文章主要給大家介紹了關(guān)于如何利用Redis?List實現(xiàn)Java數(shù)據(jù)庫分頁快速查詢的相關(guān)資料,Redis是一個高效的內(nèi)存數(shù)據(jù)庫,它支持包括String、List、Set、SortedSet和Hash等數(shù)據(jù)類型的存儲,需要的朋友可以參考下
    2024-02-02
  • Redis slowlog使用和實現(xiàn)

    Redis slowlog使用和實現(xiàn)

    slowlog是redis server記錄查詢命令執(zhí)行時間的日志模塊, 本文就來介紹一下slowlog使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • Redis教程(二):String數(shù)據(jù)類型

    Redis教程(二):String數(shù)據(jù)類型

    這篇文章主要介紹了Redis教程(二):String數(shù)據(jù)類型,本文講解了String數(shù)據(jù)類型概述、相關(guān)命令列表、命令使用示例三部分內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Docker + Redis 部署集群的實現(xiàn)步驟

    Docker + Redis 部署集群的實現(xiàn)步驟

    本文詳細介紹了在三臺服務(wù)器上部署高可用Redis集群的完整流程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • 深入淺析Redis 集群伸縮原理

    深入淺析Redis 集群伸縮原理

    Redis 集群提供了靈活的節(jié)點擴容和收縮方案。在不影響集群對外服務(wù)的情況下,可以為集群添加節(jié)點進行擴容,也可以下線部分節(jié)點進行縮容,接下來通過本文給大家分享Redis 集群伸縮原理,感興趣的朋友一起看看吧
    2021-05-05
  • redis實現(xiàn)多級緩存同步方案詳解

    redis實現(xiàn)多級緩存同步方案詳解

    這篇文章主要介紹了redis實現(xiàn)多級緩存同步方案詳解,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • redis中redis-cli使用小結(jié)

    redis中redis-cli使用小結(jié)

    redis-cli 是Redis命令行界面,一個簡單的程序,允許直接從終端向Redis發(fā)送命令,并讀取服務(wù)器發(fā)送的回復(fù),本文主要介紹了redis中redis-cli使用小結(jié),感興趣的可以了解一下
    2023-10-10
  • Win10下 Redis啟動 錯誤1067導(dǎo)致進程意外終止的解決方法

    Win10下 Redis啟動 錯誤1067導(dǎo)致進程意外終止的解決方法

    這篇文章主要介紹了Win10下 Redis啟動 錯誤1067導(dǎo)致進程意外終止的完美解決方案,需要的朋友可以參考下
    2018-01-01
  • Redis2.8配置文件中文詳解

    Redis2.8配置文件中文詳解

    這篇文章主要介紹了Redis2.8配置文件中文詳解,本文提供的是是Redis2.8.9的配置文件各項的中文解釋,需要的朋友可以參考下
    2015-06-06
  • Redis在項目中常見的12種使用場景示例和說明

    Redis在項目中常見的12種使用場景示例和說明

    Redis是一個開源的高性能鍵值對數(shù)據(jù)庫,它以其內(nèi)存中數(shù)據(jù)存儲、鍵過期策略、持久化、事務(wù)、豐富的數(shù)據(jù)類型支持以及原子操作等特性,在許多項目中扮演著關(guān)鍵角色,以下是整理的12個Redis在項目中常見的使用場景舉例說明和解釋
    2024-06-06

最新評論

焉耆| 白水县| 临潭县| 山丹县| 疏勒县| 永年县| 麻栗坡县| 民勤县| 永靖县| 上思县| 尉氏县| 丰县| 张家口市| 美姑县| 通许县| 潼关县| 古蔺县| 司法| 浏阳市| 图木舒克市| 公安县| 泸水县| 边坝县| 芦山县| 莎车县| 银川市| 莫力| 扬中市| 仙游县| 固始县| 铅山县| 佛山市| 高邮市| 海城市| 南投市| 望谟县| 平舆县| 连云港市| 岢岚县| 萨嘎县| 新巴尔虎右旗|