Redisson 主從一致性問題詳解
更新時間:2022年08月26日 11:34:36 作者:ruochen
這篇文章主要為大家介紹了Redisson 主從一致性問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
Redisson 主從一致性
- 我們先來說一下 Redis 的主從模式,
Redis Master(主節(jié)點)中處理所有發(fā)向 Redis 的寫操作(增刪改),Redis Slave(從節(jié)點)只負責處理讀操作,主節(jié)點會不斷將自己的數(shù)據(jù)同步給從節(jié)點,確保主從之間的數(shù)據(jù)一致性,但是數(shù)據(jù)同步會存在一定的延時,主從一致性問題就是因為延時而導致的 - 比如我們通過
set lock thread1 nx ex 10來獲取鎖,主節(jié)點就會保存這個鎖的標識 thread1,然后主節(jié)點會向從節(jié)點進行同步,但在同步尚未完成時時主節(jié)點發(fā)生故障,Redis 哨兵發(fā)現(xiàn)主節(jié)點宕機后,客戶端連接會斷開,然后從從節(jié)點中選出一個作為新的主節(jié)點,但是由于之前主從同步未完成,即 thread1 這個鎖已經(jīng)丟失,所以此時 Java 應用再來訪問新的主節(jié)點時就會發(fā)現(xiàn)鎖失效了,此時其他線程來獲取鎖時也能獲取成功,這時就可能出現(xiàn)并發(fā)安全問題,以上就是主從一致性導致的鎖失效問題 - 那么 Redisson 是如何解決上述問題的呢?既然導致主從一致性問題發(fā)生的主要原因是主從同步延時問題,Redisson 干脆直接舍棄了主從節(jié)點,所有 Redis 節(jié)點都是獨立的節(jié)點,相互之間無任何關系,都可以做讀寫操作。此時,我們想獲取鎖就必須依次向多個 Redis 都去獲取鎖(之前直接向 Master 節(jié)點獲取就可以),多個 Redis 節(jié)點都保存鎖的標識,才算獲取成功
- 這樣一來,由于所有節(jié)點都是獨立的,所以避免了主從一致性問題;又由于所有的節(jié)點都保存了鎖標識,即使由一個節(jié)點宕機,其他的節(jié)點也保存有鎖的標識,保證了高可用,并且可用性會隨著節(jié)點的增多而增高
- 此外,我們還以為給這些獨立的節(jié)點再加上從節(jié)點 Slave,即使一個獨立節(jié)點宕機了導致其對應的從節(jié)點變成新的主節(jié)點,且節(jié)點上鎖標識丟失了也沒有關系,因為我們只有在每一個節(jié)點都拿到鎖才算成功, 盡管可以在這個空虛的節(jié)點上獲取到鎖,但在其他節(jié)點上是獲取不到的,最終仍然是失敗,因此只要有任意一個節(jié)點存貨,其他線程就不可能拿到鎖,就不會出現(xiàn)鎖失效問題。這樣,既保留了主從同步機制,又確保了 Redis 集群的高可用特性,同時還避免了主從一致所引發(fā)的鎖失效問題,這個方案就叫做
mutilLock
Java 實現(xiàn) mutilLock
RedissonConfig.java
package com.hmdp.config;
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();
// 地址 & 密碼
config.useSingleServer().setAddress("redis://ip:端口").setPassword("pwd");
// 創(chuàng)建 RedissonClient 對象
return Redisson.create(config);
}
@Bean
public RedissonClient redissonClient2() {
// 配置
Config config = new Config();
// 地址 & 密碼
config.useSingleServer().setAddress("redis://ip:端口").setPassword("pwd");
// 創(chuàng)建 RedissonClient 對象
return Redisson.create(config);
}
@Bean
public RedissonClient redissonClient3() {
// 配置
Config config = new Config();
// 地址 & 密碼
config.useSingleServer().setAddress("redis://ip:端口").setPassword("pwd");
// 創(chuàng)建 RedissonClient 對象
return Redisson.create(config);
}
}
TestRedisson.java
package com.hmdp;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Slf4j
@SpringBootTest
public class TestRedisson {
@Resource
private RedissonClient redissonClient;
@Resource
private RedissonClient redissonClient2;
@Resource
private RedissonClient redissonClient3;
private RLock lock;
@BeforeEach
void setUp() {
RLock lock1 = redissonClient.getLock("order");
RLock lock2 = redissonClient2.getLock("order");
RLock lock3 = redissonClient3.getLock("order");
// 創(chuàng)建連鎖 multiLock
lock = redissonClient.getMultiLock(lock1, lock2, lock3);
}
@Test
void method1() throws InterruptedException {
// 嘗試獲取鎖
boolean isLock = lock.tryLock(1L, TimeUnit.SECONDS);
if (!isLock) {
log.error("獲取鎖失敗 .... 1");
return;
}
try {
log.info("獲取鎖成功 .... 1");
method2();
log.info("開始執(zhí)行業(yè)務 .... 1");
} finally {
log.warn("準備釋放鎖 .... 1");
lock.unlock();
}
}
void method2() {
// 嘗試獲取鎖
boolean isLock = lock.tryLock();
if (!isLock) {
log.error("獲取鎖失敗 .... 2");
return;
}
try {
log.info("獲取鎖成功 .... 2");
log.info("開始執(zhí)行業(yè)務 .... 2");
} finally {
log.warn("準備釋放鎖 .... 2");
lock.unlock();
}
}
}
跟蹤源碼,我們發(fā)現(xiàn)只有所有的鎖都獲取成功了才會返回 true

以上就是Redisson 主從一致性問題詳解的詳細內(nèi)容,更多關于Redisson 主從一致的資料請關注腳本之家其它相關文章!
相關文章
Redis鏈表底層實現(xiàn)及生產(chǎn)實戰(zhàn)
Redis 的 List 是一個雙向鏈表,鏈表中的每個節(jié)點都包含了一個字符串。是redis中最常用的數(shù)據(jù)結(jié)構(gòu)之一,本文主要介紹了Redis鏈表底層實現(xiàn)及生產(chǎn)實戰(zhàn),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2023-03-03
RabbitMQ+redis+Redisson分布式鎖+seata實現(xiàn)訂單服務的流程分析
訂單服務涉及許多方面,分布式事務,分布式鎖,例如訂單超時未支付要取消訂單,訂單如何防止重復提交,如何防止超賣、這里都會使用到,這篇文章主要介紹了RabbitMQ+redis+Redisson分布式鎖+seata實現(xiàn)訂單服務的流程分析,需要的朋友可以參考下2024-07-07
Redis之常用數(shù)據(jù)結(jié)構(gòu)哈希表
這篇文章主要介紹了Redis常用的數(shù)據(jù)結(jié)構(gòu)哈希表,哈希表是一種保存鍵值對的數(shù)據(jù)結(jié)構(gòu),具有一定的參考價值,需要的朋友可以參考閱讀2023-04-04

