【server】springboot 整合 redis

1、redis 使用模式

1.1 单机模式

1.1.1 编译安装方式

1.1.1.1 下载

Redis的安装非常简单,到Redis的官网(Downloads - Redis),下载对应的版本,简单几个命令安装即可。

1.1.1.2 编译安装
tar xzf redis-stable.tar.gz
cd redis-stable/
make & make install

安装完成后

cd /usr/local/bin/

1.1.1.3 安装常见问题

如果执行make命令报错:cc 未找到命令,原因是虚拟机系统中缺少gcc,执行下面命令安装gcc:

yum -y install gcc automake autoconf libtool make

 如果执行make命令报错:致命错误:jemalloc/jemalloc.h: 没有那个文件或目录,则需要在make指定分配器为libc。执行下面命令即可正常编译:       

make MALLOC=libc
1.1.1.4 redis单机启动

Redis编译完成后,会生成几个可执行文件,这些文件各有各的作用,我们现在先简单了解下,后面的课程会陆续说到和使用这些可执行文件。

image.png

1.1.1.4.1 默认启动

使用Redis的默认配置来启动,在bin目录下直接输入 ./redis-server         

image.png

可以看到直接使用redis-server启动Redis后,会打印出一些日志,通过日志可以看到一些信息:

当前的Redis版本的是64位的6.2.7,默认端口是6379。Redis建议要使用配置文件来启动。

因为直接启动无法自定义配置,所以这种方式是不会在生产环境中使用的。

1.1.1.4.2 带参启动

redis-server加上要修改配置名和值(可以是多对),没有设置的配置将使用默认配置,例如:如果要用6380作为端口启动Redis,那么可以执行:

./redis-server --port 6380

image.png

这种方式一般我们也用得比较少。

1.1.1.4.3 配置文件启动

配置文件是我们启动的最多的模式,配置文件安装目录中有

一般会采用将redis.conf cp 到一个新文件夹的方式,并使用./redis-server <path>/redis.conf

的形式来开启一台新的redis 服务器

     

1.1.2 docker 安装方式

1.1.2.1 下载
docker pull redis
 1.1.2.2 配置
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
#bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问
#bind 127.0.0.1
#protected-mode no #默认yes,开启保护模式,限制为本地访问
protected-mode no
#daemonize no#默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
daemonize no
#appendonly yes #redis持久化(可选)
appendonly yes

#主从复制,从读
replica-read-only yes

requirepass admin123

# min-replicas-to-write 3
# min-replicas-max-lag 10
1.1.2.3 启动
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/:/etc/redis/ \
--restart=always \
-d redis --appendonly yes

1.2 主从模式

主从模式与哨兵模式的区别为,哨兵模式需要另外启动3个哨兵

1.2.1 配置

daemonize yes
#bind 127.0.0.1
protected-mode no
port 6380
appendonly yes
dir /mydata/redis/6380/dumpfiles
pidfile /var/run/redis_6380.pid
logfile "/mydata/redis-cluster/6380/redis.log"
requirepass 111111
#从机需要配置,主机不用
masterauth "111111"
replicaof 192.168.10.131 6380
#移除高危操作键
rename-command keys ""
rename-command flushdb ""
rename-command flushall ""

1.2.2 启动服务器

#主机先启动, 再启动从机
redis-server /mydata/redis-cluster/6380/redis.conf
redis-server /mydata/redis-cluster/6381/redis.conf
redis-server /mydata/redis-cluster/6382/redis.conf

1.2.3 检查结果

# 进入客户端
redis-cli -h 127.0.0.1 -p 6380 -a 111111
redis-cli -h 127.0.0.1 -p 6381 -a 111111
redis-cli -h 127.0.0.1 -p 6382 -a 111111

1.3 哨兵模式

1.3.1 sentinel 配置

bind 0.0.0.0
#是否以后台daemon方式运行
daemonize yes
#安全保护模式
protected-mode no
# 端口
port 26379
#日志文件
logfile "/mydata/redis-cluster/26379/sentinel.log"
#pid文件路径
pidfile /var/run/redis-sentinel26379.pid
#工作目录
dir /mydata/redis-cluster/26379
# sentinel monitor <master-name> <ip> <redis-port> <quorum> 
#设置要监控的master服务器,quorum 表示最少要有几个哨兵认可下线,同意故障迁移的票数
sentinel monitor mymaster 192.168.10.131 6380 2
#连接master服务的密码
sentinel auth-pass mymaster 111111

1.3.2 启动哨兵

redis-sentinel /mydata/redis-cluster/26379/sentinel.conf  --sentinel
redis-sentinel /mydata/redis-cluster/26380/sentinel.conf  --sentinel
redis-sentinel /mydata/redis-cluster/26381/sentinel.conf  --sentinel

1.3.3 检查状态

#查看进程情况
ps -ef | grep redis
#查看单机情况
#登录客户端
redis-cli -p 6380 -a 111111
#查看详情
info replication

1.4 集群模式

1.4.1 集群模式配置

#87行
#bind 127.0.0.1
#309行
daemonize yes
#111行
protected-mode no
#138行
port 6381
#341行
pidfile /mydata/redis-cluster/6381/redis.pid
#355行
logfile "/mydata/redis-cluster/6381/cluster.log"
#510行
dir /mydata/redis-cluster/6381/dumpfiles
#1387行
appendonly yes
#539 540行
requirepass 111111
masterauth 111111
# 1584 1592 1598 行  
cluster-enabled yes
cluster-config-file /mydata/redis-cluster/6379/nodes.conf
cluster-node-timeout 5000
#移除高危操作键
rename-command keys ""
rename-command flushdb ""
rename-command flushall ""

1.4.2 启动服务器

# 各自启动主机
redis-server /mydata/redis-cluster/6580/redis.conf
...
#构建集群关系
redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.10.131:6580 192.168.10.131:6581 192.168.10.131:6582 192.168.10.131:6583 192.168.10.131:6584 192.168.10.131:6585

 

1.4.3 集群使用

#连接客户端 后面添加 -c 用来自动确认对应slot
#不加 -c 异常
# (error) MOVED 12706 192.168.10.131:6582
redis-cli -h 192.168.10.131 -p 6580 -a 111111 -c 
# 查看某个Key 所在的slot
cluster keyslot k1
#master节点下线后,slave 会切换为master ,原master 会以 slave的方式回归
#手动切换从属关系
cluster failover
# 检查集群状态
redis-cli -a 111111 --cluster check 192.168.10.131:6580

2、整合

2.1 主从模式

与哨兵模式一致

2.2 哨兵模式

2.2.1 POM.XML

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.2.2 application.yml

spring:
  data:
    redis:
      lettuce:
        pool:
          enabled: true
          max-active: 8
          max-idle: 8
          min-idle: 0
          max-wait: -1ms
      sentinel:
        master: mymaster
        nodes:
          - 192.168.10.131:26379
          - 192.168.10.131:26380
          - 192.168.10.131:26381
      database: 0
      password: 111111

 2.2.3 添加RedisConfig类

@Configuration
public class RedisConfig {
    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    /**
     * 增加部分
     * 读写分离
     * @return
     */

    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
        return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA);
    }

}

业务类查阅集群模式2.3.4 

2.3 集群模式

2.3.1 POM.XML

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.3.2 application.yml

server:
  port: 7777
spring:
  application:
    name: redis-demo
  data:
    redis:
      cluster:
        nodes:
          - 192.168.10.131:6580
          - 192.168.10.131:6581
          - 192.168.10.131:6582
          - 192.168.10.131:6583
          - 192.168.10.131:6584
          - 192.168.10.131:6585
        max-redirects: 3
      password: 111111
      database: 0
      lettuce:
        pool:
          max-active: 8
          max-wait: -1ms
          max-idle: 8
          min-idle: 0
        cluster:
          refresh:
            #支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
            adaptive: true
            #定时刷新
            period: 2000ms

2.3.3 添加Redis.config 类

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

2.3.4 业务类

2.3.4.1 service
#service
public interface OrderService {
    /**
     *  创建订单 key
     * @param key
     * @return
     */
    void createOrder(String key);

    public String getOrder(String key);
}

#serviceImpl
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    public static final String ORDER_KEY = "order:";
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void createOrder(String key) {
        String orderNo = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(ORDER_KEY + key, orderNo);
        log.info("=====>编号" + key + "的订单流水生成:{}", orderNo);
    }

    @Override
    public String getOrder(String key) {
        return Objects.requireNonNull(redisTemplate.opsForValue().get(ORDER_KEY + key)).toString();
    }
}
2.3.4.2 controller
@RestController
@RequestMapping("/lettuce")
@Slf4j
public class Demo {

    @Resource
    private OrderService orderService;

    @GetMapping("/create")
    public String createOrder() {
        String key = UUID.randomUUID().toString();
        orderService.createOrder(key);
        return key;
    }

    @GetMapping("/get/{key}")
    public String getOrder(@PathVariable("key") String key) {
        return orderService.getOrder(key);
    }

}

2.3.5故障

Redis Cluster集群部署采用了3主3从拓扑结构,数据读写访问master节点, slave节点负责备份。

当master宕机主从切换成功,redis手动OK,but 2个经典故障

 

 

问题的解决方案为:

添加定时刷新参数

spring:
  data:
    redis:
      lettuce:
        cluster:
          refresh:
            #支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
            adaptive: true
            #定时刷新
            period: 2000ms

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/782609.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 开发工具

IDEA 开发工具 IDEA软件激活新建项目新建project 运行调试 IDEA软件激活 访问激活码网进入带*的域名下载并解压左上角的zip包先执行sh uninstall.sh&#xff0c;再执行sh install.sh在带*的网页中复制并使用激活码code 新建项目 新建project file》New〉Project》New Proje…

【测试】系统压力测试报告模板(Word原件)

系统压力测试&#xff0c;简而言之&#xff0c;是在模拟高负载、高并发的环境下&#xff0c;对系统进行全面测试的过程。它旨在评估系统在面对极端使用条件时的性能表现&#xff0c;包括处理能力、响应时间、资源消耗及稳定性等关键指标。通过压力测试&#xff0c;开发团队能够…

MySQL之备份与恢复和MySQL用户工具(一)

备份与恢复 备份脚本化 为备份写一些脚本是标准做法。展示一个示例程序&#xff0c;其中必定有很多辅助内容&#xff0c;这只会增加篇幅&#xff0c;在这里我们更愿意列举一些典型的备份脚本功能&#xff0c;展示一些Perl脚本的代码片段。你可以把这些当作可重用的代码块&…

Python酷库之旅-第三方库Pandas(009)

目录 一、用法精讲 19、pandas.read_xml函数 19-1、语法 19-2、参数 19-3、功能 19-4、返回值 19-5、说明 19-6、用法 19-6-1、数据准备 19-6-2、代码示例 19-6-3、结果输出 20、pandas.DataFrame.to_xml函数 20-1、语法 20-2、参数 20-3、功能 20-4、返回值 …

【国产开源可视化引擎Meta2d.js】网格

画布背景网格 在线体验&#xff1a; 乐吾乐2D可视化 示例&#xff1a; // 设置默认缺省网格属性 meta2d.store.options.grid true; // 开启 meta2d.store.options.gridColor eeeeee; // 网格线条颜色 meta2d.store.options.gridSize 10; // 格子大小// 设置单个图纸的网格…

Golang | Leetcode Golang题解之第222题完全二叉树的节点个数

题目&#xff1a; 题解&#xff1a; func countNodes(root *TreeNode) int {if root nil {return 0}level : 0for node : root; node.Left ! nil; node node.Left {level}return sort.Search(1<<(level1), func(k int) bool {if k < 1<<level {return false}…

【ETABS】【RHINO】案例:Swallow to ETABS

文章目录 01. Swallow Overview总览1 LOAD&#xff1a;Defination of LoadCase、Response Combo2 SectionArea Section and Area Load&#xff08;面截面定义与指定&#xff0c;面荷载指定&#xff09;Frame Section with rebarattr and linear load&#xff08;带钢筋属性框架…

flutter:监听路由的变化

问题 当从路由B页面返回路由A页面后&#xff0c;A页面需要进行数据刷新。因此需要监听路由变化 解决 使用RouteObserver进行录音监听 创建全局变量&#xff0c;不在任何类中 final RouteObserver<PageRoute> routeObserver RouteObserver<PageRoute>();在mai…

Hi3861 OpenHarmony嵌入式应用入门--UDP Server

本篇使用的是lwip编写udp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点&#xff0c;并且密码为PARAM_HOTSPOT_PSK。 修改网络参数 在Hi3861开发板上运行上述四个测试程序之前&#xff0c;需要根据你的无线路由、Linux系统IP修改 net_params.h文件的相关代码&…

基于轨迹信息的图像近距离可行驶区域方案验证

一 图像可行驶区域方案 1.1 标定场景 1.2 标定步骤 设计一定间距标定场&#xff0c;在标定场固定位置设置摄像头标定标识点。主车开到标定场固定位置录制主车在该位置各个摄像头数据&#xff0c;通过摄像头捕获图像获取图像上关键点坐标pts-2d基于标定场设计&#xff0c;计算…

Python | Leetcode Python题解之第222题完全二叉树的节点个数

题目&#xff1a; 题解&#xff1a; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def countNodes(self,…

基于字典学习的地震数据降噪(MATLAB R2021B)

稀疏表示基于研究者们提出了许多变换基函数的方法逐渐成型&#xff0c;比如小波域&#xff0c;曲波域&#xff0c;dreamlet 域等&#xff0c;其原理是利用地震信号在变换域内的稀疏性和可分离性以去除噪声。继 Donoho发表非线性去噪方法-小波阈值萎缩方法&#xff0c;在后续的研…

汉中茗茶小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;茶叶管理&#xff0c;论坛管理&#xff0c;公告管理&#xff0c;茗茶历史管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;茗茶信息&#xf…

阶段三:项目开发---搭建项目前后端系统基础架构:任务9:导入空管基础数据

任务描述 本阶段任务是导入项目的基础数据&#xff0c;包括空管基础数据和离线的实时飞行数据&#xff08;已经脱敏&#xff09;。 任务指导 本阶段任务需要导入两种数据&#xff1a; 1、在MySQL中导入空管基础数据 kongguan.sql空管基础数据表说明&#xff1a; 1告警信息…

JVM原理(二二):JVM虚拟机线程调度与状态转换

1. Java线程调度 Java的线程是被映射到系统的原生线程上实现的 线程调度是指系统为线程分配处理器使用权的过程&#xff0c;调度主要方式有两种&#xff0c;分别是协同式线程调度和抢占式线程调度。 协同式线程调度&#xff1a;如果使用协同式调度的多线程系统&#xff0c;线…

Cortex-A510——内核及汇编

Cortex-A510——内核及汇编 小狼http://blog.csdn.net/xiaolangyangyang 1、异常等级 2、异常等级切换 同步异常&#xff1a; 1、SVC/HVC/SMC&#xff1b; 2、MMU引发的异常&#xff08;内核态EL1发生&#xff0c;发生后不会进行异常等级切换…

Java基础-内部类与异常处理

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Java 内部类 什么是内部类&#xff1f; 使用内部类的优点 访问局部变量的限制 内部类和继承 内部…

java 闭锁(CountDownLatch)

闭锁&#xff08;CountDownLatch&#xff09;是Java中的一个同步辅助类&#xff0c;用于协调多个线程之间的协作。它允许一个或多个线程等待&#xff0c;直到在其他线程中执行的一组操作完成。闭锁非常适用于需要等待一组事件发生之后再执行某些操作的场景。 import java.uti…

maxwell启动报错:Could not find first log file name in binary log index file

出现该问题是因为&#xff1a;maxwell 读取的是 mysql 的 binlog 日志&#xff0c;而配置文件中的两个值与 binlog 的最新值没有保持一致导致 1. 切换到maxwell的库 show master status;记住图片中的 FIle 和 Position 2. 修改maxwell的配置 SELECT * from positions p ;将…

生物墨水:3D组织生物打印的基石

生物墨水是3D组织生物打印技术的核心组成部分。生物墨水通常由生物材料&#xff08;如水凝胶聚合物&#xff09;与所需的细胞和/或其他生物大分子&#xff08;例如生长因子&#xff09;混合而成。为了成功地进行组织生物打印&#xff0c;生物墨水必须满足以下要求&#xff1a; …