良许Linux教程网 干货合集 详解Redisson 主从一致性

详解Redisson 主从一致性

本篇文章重点为大家讲解一下Redisson 主从一致性,有需要的小伙伴可以参考一下。

image-20220908213058122

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

简单探讨Redisson 主从一致性问题简单探讨Redisson 主从一致性问题

以上就是Redisson 主从一致性问题详解的详细内容

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部