網站首頁 編程語言 正文
Redisson 主從一致性
- 我們先來說一下 Redis 的主從模式,
Redis Master
(主節點)中處理所有發向 Redis 的寫操作(增刪改),Redis Slave
(從節點)只負責處理讀操作,主節點會不斷將自己的數據同步給從節點,確保主從之間的數據一致性,但是數據同步會存在一定的延時,主從一致性問題就是因為延時而導致的 - 比如我們通過
set lock thread1 nx ex 10
來獲取鎖,主節點就會保存這個鎖的標識 thread1,然后主節點會向從節點進行同步,但在同步尚未完成時時主節點發生故障,Redis 哨兵發現主節點宕機后,客戶端連接會斷開,然后從從節點中選出一個作為新的主節點,但是由于之前主從同步未完成,即 thread1 這個鎖已經丟失,所以此時 Java 應用再來訪問新的主節點時就會發現鎖失效了,此時其他線程來獲取鎖時也能獲取成功,這時就可能出現并發安全問題,以上就是主從一致性導致的鎖失效問題 - 那么 Redisson 是如何解決上述問題的呢?既然導致主從一致性問題發生的主要原因是主從同步延時問題,Redisson 干脆直接舍棄了主從節點,所有 Redis 節點都是獨立的節點,相互之間無任何關系,都可以做讀寫操作。此時,我們想獲取鎖就必須依次向多個 Redis 都去獲取鎖(之前直接向 Master 節點獲取就可以),多個 Redis 節點都保存鎖的標識,才算獲取成功
- 這樣一來,由于所有節點都是獨立的,所以避免了主從一致性問題;又由于所有的節點都保存了鎖標識,即使由一個節點宕機,其他的節點也保存有鎖的標識,保證了高可用,并且可用性會隨著節點的增多而增高
- 此外,我們還以為給這些獨立的節點再加上從節點 Slave,即使一個獨立節點宕機了導致其對應的從節點變成新的主節點,且節點上鎖標識丟失了也沒有關系,因為我們只有在每一個節點都拿到鎖才算成功, 盡管可以在這個空虛的節點上獲取到鎖,但在其他節點上是獲取不到的,最終仍然是失敗,因此只要有任意一個節點存貨,其他線程就不可能拿到鎖,就不會出現鎖失效問題。這樣,既保留了主從同步機制,又確保了 Redis 集群的高可用特性,同時還避免了主從一致所引發的鎖失效問題,這個方案就叫做
mutilLock
Java 實現 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"); // 創建 RedissonClient 對象 return Redisson.create(config); } @Bean public RedissonClient redissonClient2() { // 配置 Config config = new Config(); // 地址 & 密碼 config.useSingleServer().setAddress("redis://ip:端口").setPassword("pwd"); // 創建 RedissonClient 對象 return Redisson.create(config); } @Bean public RedissonClient redissonClient3() { // 配置 Config config = new Config(); // 地址 & 密碼 config.useSingleServer().setAddress("redis://ip:端口").setPassword("pwd"); // 創建 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"); // 創建連鎖 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("開始執行業務 .... 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("開始執行業務 .... 2"); } finally { log.warn("準備釋放鎖 .... 2"); lock.unlock(); } } }
跟蹤源碼,我們發現只有所有的鎖都獲取成功了才會返回 true
原文鏈接:https://juejin.cn/post/7135613701951848461
相關推薦
- 2023-05-31 如何在ubuntu中切換使用不同版本的python_python
- 2022-04-27 jquery+css實現移動端元素拖動排序_jquery
- 2022-10-29 qt輸出自定義的pdf文件源碼詳解
- 2022-12-09 C++?Boost?Variant示例超詳細講解_C 語言
- 2023-11-14 樹莓派以及linux ubuntu 上,各種依賴不滿足,修復不了:E: Release file f
- 2022-07-03 級聯分類器算法原理解析_相關技巧
- 2022-09-29 React函數組件useContext?useReducer自定義hooks_React
- 2023-04-12 Python批量刪除txt文本指定行的思路與代碼_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支