redis哨兵模式的配置及在springboot中使用

在这里插入图片描述

一、从0搭建redis哨兵模式
1、下载redis
http://download.redis.io/releases/

这里使用的6.0.4版本
下载后上传到服务器中
这里准备三台服务器:192.168.200.135(主) 192.168.200.136(从) 192.168.200.137(从)
并准备好服务器看看装没装gcc:rpm -q gcc
没装的话就装(依次执行):

yum install gcc-c++
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash
2、解压redis压缩包
tar -zxvf redis-6.0.4.tar.gz

在解压目录下编译安装:(我的目录是 /home/soft/redis/redis-6.0.4)
编译: make
安装:(make install PREFIX=安装路径)
例如:make install PREFIX=/home/soft/redis/redis-6.0.4
那么他就会在redis-6.0.4文件夹生成一个bin文件夹,这就是安装的redis目录,当然可以指定其他目录方便辨识:例如 make install PREFIX=/home/soft/redis/redis1

3、配置 conf文件

把安装目录(就是/home/soft/redis/redis-6.0.4)下的文件redis.conf、sentinel.conf
拷贝到刚刚生成的bin目录下。
修改redis.conf:

3.1、持久化

AOF
appendonly no 改为 appendonly always/everysec/no 就是使用AOF持久化模式,always是总是执行、everysec是每秒钟执行(默认) no是不执行
RDB
将save 900 1、save 300 10、save 60 10000注释掉就是关闭放开就是开启

4、搭建主从模式(哨兵模式是在主从模式基础上搭建的)

4.1、手动创建一个data目录 /home/soft/redis/redis-6.0.4/data 待会用来存数据
主节点(192.168.200.135)的redis.conf文件配置:

# redis进程是否以守护进程的方式运行,yes为是,no为否(不以守护进程的方式运行会占用一个终端)。
daemonize yes
# 指定redis进程的PID文件存放位置
pidfile "/var/run/redis.pid"
# redis进程的端口号
port 6379
#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭设置为no。
protected-mode no
# 绑定的主机地址
bind 0.0.0.0
# 客户端闲置多长时间后关闭连接,默认此参数为0即关闭此功能
timeout 300
# redis日志级别,可用的级别有debug.verbose.notice.warning
loglevel verbose
# log文件输出位置,如果进程以守护进程的方式运行,此处又将输出文件设置为stdout的话,就会将日志信息输出到/dev/null里面去了
logfile "stdout"
# 设置数据库的数量,默认为0可以使用select <dbid>命令在连接上指定数据库id
databases 16
# 指定在多少时间内刷新次数达到多少的时候会将数据同步到数据文件
save 900 1
save 300 10
save 60 10000
# 指定存储至本地数据库时是否压缩文件,默认为yes即启用存储
rdbcompression yes
# 指定本地数据库文件名
dbfilename "dump.db"
# redis数据文件存放的目录
dir "/home/soft/redis/redis-6.0.4/data"
# 指定当本机为slave服务时,设置master服务的IP地址及端口,在redis启动的时候他会自动跟master进行数据同步
#replicaof 192.168.200.135 6379
# 当master设置了密码保护时,slave服务连接master的密码
#masterauth 420188
# 设置redis连接密码,如果配置了连接密码,客户端在连接redis是需要通过AUTH<password>命令提供密码,默认关闭
requirepass 420188
# 设置同一时间最大客户连接数,默认无限制。redis可以同时连接的客户端数为redis程序可以打开的最大文件描述符,如果设置 maxclients #0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回 max number of clients reached 错误信息
maxclients 128
# #指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key。当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可#以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
#maxmemory<bytes>
# #指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面save条件来同步的,#所以有的数据会在一段时间内只存在于内存中。默认为no。
appendonly yes
# 指定跟新日志文件名默认为appendonly.aof
appendfilename "appendonly.aof"
# 指定更新日志的条件,有三个可选参数 - no:表示等操作系统进行数据缓存同步到磁盘(快),always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全), #everysec:表示每秒同步一次(折衷,默认值);
appendfsync everysec
# 开启集群
# cluster-enabled yes

从节点配置(192.168.200.136/192.168.200.137):
跟上面一样,只是放开两行:

replicaof 192.168.200.135 6379
masterauth "420188"
5、启动redis
./redis-server ./redis.conf

因为daemonize yes所以它一定会挂在后台运行

这样的话就组成了一主二从的主从模式。
测试,在135机器上连接客户端 :(另开一个窗口)

./redis-cli 

执行
登录:auth 420188
查看redis节点信息:info replication
显示:
role:master #当前节点是主节点
connected_slaves:2 #它还有两个从节点
还有很多其他信息…………
设置一个信息试试:set name llcc
在136/137的客户端连接上,执行get name 就可以看到主节点刚才保存的数据了

6、搭建哨兵模式

主从模式只是解决了数据的备份但是主节点挂了,没法自动选举从节点,所以要使用哨兵模式。
在上面主从模式基础上开始搭建:
6.1、手动创建目录sentinel:/home/soft/redis/redis-6.0.4/data/sentinel
6.2、修改bin下的sentinel.conf文件(几台服务器的sentinel.conf都配置一样,哨兵本身也形成了集群)

port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/home/soft/redis/redis-6.0.4/data/sentinel"
dir /home/soft/redis/redis-6.0.4/data/sentinel
# 设定监控地址,为对应的主redis库的内网地址, 行尾最后的一个1代表当master挂掉时,集群中1个sentine(哨兵)都认为master挂了才能认为master 不可用,sentinel集群中各个sentinel通过gossip协议进行通讯(这里的哨兵都监控master,而不是分别监听自己的redis)
sentinel monitor mymaster 192.168.200.135 6379 1
# 设定sentinel myid 每个都不一样,使用yum安装的时候,直接就生成了
sentinel myid 8136d69cca59e0918a73a7af97eb59c77742d352
# 主数据库密码,需要将配置放在sentinel monitor master 127.0.0.1 6379 1下面
sentinel auth-pass mymaster 420188
sentinel down-after-milliseconds mymaster 3000
sentinel deny-scripts-reconfig yes
# 表示如果master重新选出来后,其它slave节点能同时并行从新master同步缓存的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保定的设置为1,只同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。
sentinel parallel-syncs mymaster 1
# 设定10秒内master没有活起来,就重新选举主
sentinel failover-timeout mymaster 10000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# 保护模式修改为否,允许远程连接
protected-mode no

这里重点是:
sentinel monitor mymaster 192.168.200.135 6379 1
sentinel auth-pass mymaster 420188
这里的哨兵都监控master,而不是分别监听自己的redis,所以三台服务器这里配置都是一样:
sentinel monitor mymaster 192.168.200.135 6379 1

注意:一主二从的配置 sentinel monitor mymaster 192.168.200.135 6379 1
7、启动哨兵

在bin目录下执行:

./redis-sentinel ./sentinel.conf

这是135是master ,136、137是slave
现在手动关闭135的redis,再去136、137查看info replication会发现136已经成了master
这就实现了自动切换主从,故障转移(注:如果重启主节点发现它没有加入新的哨兵主从,那要检查一下它密码有没有被注释,就是这个 masterauth,我之前就遇到这个这个问题了)

二、springboot集成redis哨兵

这里用的是springboot2.2.5.RELEASE

1、导包
 <!--集成redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <!-- 排除lettuce包,使用jedis代替-->
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
2、配置yml文件
spring:
  redis:
    cluster:
      nodes: 192.168.200.135:6379,192.168.200.136:6379,192.168.200.137:6379
    password: 420188
    timeout: 6000
    database: 0
    jedis:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0
    sentinel:
      master: mymaster
      nodes: 192.168.200.135:26379,192.168.200.136:26379,192.168.200.137:26379
3、写一个配置类(自定义redis序列化)
@Configuration
public class RedisConfig{

    @Bean
    public RedisTemplate<String,Object> redisTemplate(JedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //自定义序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
4、代码中使用
@Autowired
    private RedisTemplate redisTemplate;
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐