SpringBoot Redis入门(四)——Redis单机、哨兵、集群模式

本文介绍了如何在SpringBoot项目中配置哨兵模式和集群模式的Redis缓存,比较了一主多从和分布式存储的差异,以及在主节点故障后的自动切换机制。
  • 单机模式:单台缓存服务器,开发、测试环境下使用;
  • 哨兵模式:主-从模式,提高缓存服务器的高可用安全性。所有缓存的数据在每个节点上都一致。每个节点添加监听器,不断监听节点可用状态,一旦主节点不能再提供服务。各监听器会立即在“从节点“中投票选择一台将之作为”主节点“器。从而使业务系统服务不会被中断。当然主节点具体出了什么问题,还得运维人员排查并及时修复并上线;
  • 集群模式:分布式+主从模式,具有高可用安全性高数据量大并发量大等优势。一般需要6台服务器,3台主+3台从。一般在缓存数据量大或者并发访问量非常高以至于单台服务器已经无法承受这样的数据量或访问量时才考虑集群模式。集群模式中几台主服务器中的数据是不一致的,只有主和从中的数据是相同的。

在SpringBoot中使用哨兵模式和集群模式,也是不费吹灰之力。对于我们使用来说和前面单机模式没有任何区别。唯一需要做的就是告诉SbringBoot框架:这个项目我要使用哨兵模式,这个项目我要使用集群模式。如何告诉框架呢,当然是通过application.yml文件中的配置来说明:
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>lab-03-redis</artifactId>
        <groupId>com.luo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lab-03-redis-06-redis-cluster</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- 实现对 Spring MVC 的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 实现对 Spring Data Redis 的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- pool 对象池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- 阿里JSON解析器 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.34</version>
        </dependency>

        <!-- 引入 Swagger 依赖 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!-- 引入 Swagger UI 依赖,以实现 API 接口的 UI 界面 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!-- 方便等会写单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

关于使用哨兵模式的Redis缓存配置:

spring:
  profiles:
    active: cluster
---
spring:
  profiles: standalone
  # 默认使用的是lettuce框架封装的redis操作
  # 默认连接redis的s顺序: 先 Sentinel哨兵模式 -> Cluster集群 -> 单机Redis
  redis:
    host: 127.0.0.1 # 连接redis的ip
    port: 6379
    database: 0 # 连接的是redis的几号数据库
    password: 123456  # 连接redis的密码
    lettuce:
      #      连接池
      pool:
        max-wait: 100ms  # 连接的最大等待时间
        max-active: 8  # 最大连接数
        max-idle: 4 # 最大空闲连接数
        min-idle: 0 # 最小空闲连接数

---
spring:
  profiles: sentinel
  redis:
    host: 127.0.0.1 # 连接redis的ip
    port: 6379
    database: 0 # 连接的是redis的几号数据库
    password: 123456  # 连接redis的密码
    lettuce:
      #      连接池
      pool:
        max-wait: 100ms  # 连接的最大等待时间
        max-active: 8  # 最大连接数
        max-idle: 4 # 最大空闲连接数
        min-idle: 0 # 最小空闲连接数
    sentinel:
      master: mymaster  # 配置哨兵时候master的名字
      nodes:
        - 127.0.0.1:26379
        - 127.0.0.1:26380
        - 127.0.0.1:26381

---
spring:
  profiles: cluster
  redis:
    host: 127.0.0.1 # 连接redis的ip
    port: 6379
    database: 0 # 连接的是redis的几号数据库
    password: 123456  # 连接redis的密码
    lettuce:
      #      连接池
      pool:
        max-wait: 100ms  # 连接的最大等待时间
        max-active: 8  # 最大连接数
        max-idle: 4 # 最大空闲连接数
        min-idle: 0 # 最小空闲连接数
    # 配置集群
    cluster:
      nodes:
        - 127.0.0.1:6379
        - 127.0.0.1:6380
        - 127.0.0.1:6381
        - 127.0.0.1:7379
        - 127.0.0.1:7380
        - 127.0.0.1:7381

哨兵模式的配置中,特别注意:*ndes配置的是哨兵的IP和端口,并非缓存服务器的;
集群模式的配置,都是缓存服务器的IP和端口。

接下来我们验证一下哨兵模式和集群模式在使用结果上的差异;

哨兵模式

如下图所示:三台缓存服务器,每台服务都有对应哨兵;
在这里插入图片描述

将6个服务启动后,如下图所示:
主:6380;从:6379、6381;
在这里插入图片描述

1、一主多从,读写分离
	//测试方法
    public Object getUserInfo(String username) {
        if (redisTemplate.opsForValue().get(username) == null) {
            System.out.println("未获取到缓存,新建用户信息.............");
            Map<String, Object> user = new HashMap<>();
            user.put("username", username);
            user.put("usercode", "zhangsan");
            user.put("sex", "男");
            user.put("createtime", new Date());
            redisTemplate.opsForValue().set(username, user);
        }
        return redisTemplate.opsForValue().get(username);
    }

	@Test
    public void testRedis() throws InterruptedException {
        System.out.println(userService.getUserInfo("1"));
        System.out.println(userService.getUserInfo("2"));
        System.out.println(userService.getUserInfo("3"));
    }

三台缓存服务器存储结果都是一致的,由此可见,哨兵模式是一主多从和读写分离模式。
在这里插入图片描述

2、主服务宕机,从服务升级主

哨兵模式另一目的就是当Master宏机后,从服务可快速自动升级为Master,不致于业务被中断。

当我们将主服务器6380停机之后,将会出现以下的内容。
三台哨兵控制台中都打印了,切换master的日志,可以看出主服务器已经变为6381这台服务器了。
在这里插入图片描述
对于我们的系统而言,由于缓存配置也是配置的哨兵的地址,主服务挂了之后,对于我们系统并无影响。

集群模式

集群模式一般需要6台服务器,3主3从,如下图共有6台缓存服务器。
在这里插入图片描述
分别启动6台服务器后,再cmd命令模式下执行一个命令,完成集群配置:

redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:7379 127.0.0.1:7380 127.0.0.1:7381 --cluster-replicas 1 -a 123456

集群启动后:
在这里插入图片描述
集群情况:在这里插入图片描述
主:6379、6381、6380;从:7379、7380、7381;

1、分布式存储
    @Test
    public void testRedis() throws InterruptedException {
        System.out.println(userService.getUserInfo("1"));
        System.out.println(userService.getUserInfo("2"));
        System.out.println(userService.getUserInfo("20000001"));
        System.out.println(userService.getUserInfo("20200002"));
    }

在这里插入图片描述
从结果看:
我们存储了4个值,1、2、2000001、20200002。
1,2------------> 主6380,从7381;
2000001----->主6381,从7379;
20200002—>主6379,从7380

2、高可用

我们关闭主节点6380,然后查看。

在这里插入图片描述
查看集群中各节点情况,6380显示fail。而7380已经变成了master节点了。

现在从缓存中读取前面缓存的4个值,虽然是异常提示:127.0.0.1:6380连接失败,但还是能获取到缓存内的值。(这里的异常是因为执行Test方法时,集群配置中有这台机器,初始化时连接不上的异常。若是一般在运行中的web项目不会出现这样的异常)
在这里插入图片描述
再次将6380启动起来后,6380变成了slave从节点。
6380启动日志:

[20520] 16 Jan 14:46:39.163 # Server initialized
[20520] 16 Jan 14:46:39.163 * DB loaded from append only file: 0.000 seconds
[20520] 16 Jan 14:46:39.163 * Ready to accept connections
[20520] 16 Jan 14:46:39.164 # Configuration change detected. Reconfiguring myself as a replica of c96d92167f25658f92b8e68fbe2cd641db0c9962
[20520] 16 Jan 14:46:39.164 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
[20520] 16 Jan 14:46:39.165 # Cluster state changed: ok
[20520] 16 Jan 14:46:40.253 * Connecting to MASTER 127.0.0.1:7380
[20520] 16 Jan 14:46:40.253 * MASTER <-> REPLICA sync started
[20520] 16 Jan 14:46:40.256 * Non blocking connect for SYNC fired the event.
[20520] 16 Jan 14:46:40.256 * Master replied to PING, replication can continue...
[20520] 16 Jan 14:46:40.258 * Trying a partial resynchronization (request 3ce7caf46b989d9524c450b595a19e5d0c82b868:1).
[20520] 16 Jan 14:46:40.280 * Full resync from master: 609626e133d8d053640826b2da85b3789ed7ec02:5125
[20520] 16 Jan 14:46:40.280 * Discarding previously cached master state.
[20520] 16 Jan 14:46:40.419 * MASTER <-> REPLICA sync: receiving 419 bytes from master
[20520] 16 Jan 14:46:40.421 * MASTER <-> REPLICA sync: Flushing old data
[20520] 16 Jan 14:46:40.426 * MASTER <-> REPLICA sync: Loading DB in memory
[20520] 16 Jan 14:46:40.427 * MASTER <-> REPLICA sync: Finished with success
[20520] 16 Jan 14:46:40.442 * Background append only file rewriting started by pid 18008
[20520] 16 Jan 14:46:40.578 * AOF rewrite child asks to stop sending diffs.
[20520] 16 Jan 14:46:40.687 # fork operation complete
[20520] 16 Jan 14:46:40.697 * Background AOF rewrite terminated with success
[20520] 16 Jan 14:46:40.698 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
[20520] 16 Jan 14:46:40.700 * Background AOF rewrite finished successfully

在这里插入图片描述

天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认收货,评价等一系列操作。 作为模拟天猫商城系统的核心组成部分之一,采用SSM框架的天猫数据管理后台包含商品管理,订单管理,类别管理,用户管理和交易额统计等模块,实现了对整个商城的一站式管理和维护。本课程是一门专业的Java微服架构开发实战课程,主要讲解了当下流行的SpringBoot框架、SpringCloud架构以及与第三方技术整合开发实战内容。通过本课程的学习,能够理解并掌握SpringBoot的基础知识,同时能够掌握SpringBoot与常用的第三方技术整合实现实际开发中的业务需求,包括实现Web开发、数据访问、缓存管理、安全管理、消息服务、任务管理等;了解并掌握SpringCloud微服务架构的基础知识及相关组件的应用,掌握微服务架构在企业级开发的实践,建立起微服架构思想。项目技术栈:采用SpringBoot简化商城系统的初始搭建以及开发过程采用SpringMVC+Spring+IBatis完成项目的整合采用Mysql作为数据库存储,Druid配置数据库连接池采用SpringCloud+Netflix 微服务技术栈的实战开发使用Redis完成缓存的数据存储,搭建Redis搭建主从、哨兵、集群应用,保证Redis的高可用使用ElasticSearch全文检索系统进行商品数据搜索,使用ElasticSearch搭建搜索服务的高可用使用Ngnix实现页面动静分离与负载均衡的配置采用FastDFS文件储存系统文件存储,完成广告图片、商品图片的上传和存储系统使用采用CAS+shiro单点登录系统实现用户认证使用ECharts根据后台查询数据生成图表使用POI实现了商城盈利状况的Excel表格导出。商品的详情页使用Thymeleaf完成页面静态化,减少页面数据展示延迟项目中使用SpringBoot下的Aop + 自定义注解完成用户行为记录,日志采集后台管理系统使用Shiro实现登录验证和权限管理(超级管理员、管理员、产品编辑员)项目整合微信完成订单的支付使用Redission完成分布式锁,生成订单的编号使用SpringCloud Alibaba Seat完成下订单模块的分布式事务(新增订单表,库存减少,库存超卖设计)使用RabbitMQ 做消息队列,完成订单未支付自动取消和模块直接的解耦合使用Quartz任务调度,完成缓存的定时刷新,保证缓存的一致性使用本地消息表机制完成消息然队列RabbitMQ消息可靠性传输订单支付模块使用微信扫码支付,并设置订单超时自动取消通过Jquery实现前端校验,通过基于Hibernate的Valida注解实现后端的校验功能使用Base64编码对Json数据传输进行编码和解码项目使用RESTful设计风格实现资源的访问,实现前后端分离项目使用聚合数据第三方短信平台完成用户的登陆功能项目使用SpringBoot整合JavaMail完成邮件的发送项目使用SpringBoot整合Swagger2生成接口文档使用PostMan完成接口的测试项目的测试:SpringTest、dbunit、EasyMock使用Docker 进行应用的自动化打包和发布、自动化测试和持续集成、部署和调整其他应用使用 PowerDesigner,完成数据库的建模项目使用禅道进行BUG管理环境采用Maven实施多模块项目构建,采用Git进行项目版本管理 架构解读:  项目部分截图:              讲义部分截图:          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wolf犭良

谢谢您的阅读与鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值