手机网站比例尺寸,北京建网站,外贸网站响应式,西安专业承接网站搭建模板大家好#xff0c;我是袁庭新。
在Redis主从复制模式中#xff0c;因为系统不具备自动恢复的功能#xff0c;所以当主服务器#xff08;master#xff09;宕机后#xff0c;需要手动把一台从服务器#xff08;slave#xff09;切换为主服务器。在这个过程中#xff0…大家好我是袁庭新。
在Redis主从复制模式中因为系统不具备自动恢复的功能所以当主服务器master宕机后需要手动把一台从服务器slave切换为主服务器。在这个过程中不仅需要人为干预而且还会造成一段时间内服务器处于不可用状态同时数据安全性也得不到保障因此主从模式的可用性较低不适用于线上生产环境。
为了解决这一问题Redis引入了哨兵模式。就是为了让它更靠谱、不容易出问题。你想啊如果Redis的主服务器突然挂了那整个服务不就断了嘛但有了哨兵模式就相当于有了个小管家它会时刻盯着Redis服务器们看谁不对劲儿。下面就来给大家系统的介绍Redis的哨兵模式。
1 哨兵模式介绍
Sentinel是Redis的高可用性的解决方案。由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及所有从服务器并在被监视的主服务器进入下线状态时Sentinel会自动将下线主服务器属下的某个从服务器升级为新的主服务器然后由新的主服务器代替已下线的主服务器继续处理命令请求。
Redis哨兵模式是一种特殊的模式Redis为其提供了专属的哨兵命令它是一个独立的进程能够独立运行。哨兵模式的结构如下图所示。 Redis哨兵模式的作用如下
监控哨兵节点会以每30秒一次的频率对每个Redis节点发送PING命令并通过Redis节点的回复来判断其运行状态。自动故障恢复当哨兵监测到主服务器发生故障时会自动在从节点中选择一台机器并将其提升为主服务器当故障实例恢复后也以新的master为主。通知Sentinel充当Redis客户端的服务发现来源当集群发生故障转移Failover时会将最新信息通过PubSub发布订阅模式推送给Redis的客户端以及其他的从节点。
2 哨兵模式原理
2.1 集群监控原理
Sentinel基于心跳机制监测服务状态每隔30秒向集群的每个实例发送PING命令。 2.1.1 主观下线
主观下线适用于主服务器和从服务器。如果在规定的时间内配置参数down-after-millisecondsSentinel节点没有收到目标服务器的有效回复Sentinel基于心跳机制监测服务状态则判定该服务器为“主观下线”。例如Sentinel-1向主服务发送PING命令在规定时间内没收到主服务器PONG回复则Sentinel-1判定主服务器为“主观下线”。
2.1.2 客观下线
客观下线只适用于主服务器。Sentinel-1发现主服务器出现了故障它会通过相应的命令询问其它Sentinel节点对主服务器的状态判断。如果超过指定数量配置参数quorum的Sentinel节点认为主服务器down掉主观下线则Sentinel-1节点判定主服务为“客观下线”。quorum值最好超过Sentinel实例数量的一半。
2.2 集群故障恢复原理
投票选举底层使用的是Raft算法所有Sentinel节点会通过投票机制按照谁发现谁去处理的原则例如是由Sentinel-1发现的则选举Sentinel-1为领头节点去做Failover故障转移操作Sentinel-1节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器然后通过发布订功能通知其余的从节点slave更改配置文件跟随新上任的主服务器master。至此就完成了主从切换的操作。
一旦发现master故障Sentinel需要在salve中选择一个作为新的master。选择依据见下
首先会判断slave节点与master节点断开时间长短如果超过指定值down-after-milliseconds * 10则会排除该slave节点。然后判断slave节点的slave-priority值越小优先级越高如果是0则永不参与选举。如果slave-prority一样则判断slave节点的offset值越大说明数据越新优先级越高。最后是判断slave节点的运行id大小越小优先级越高。
当选出一个新的master后假设选举的是salve1节点该如何实现切换呢流程如下
Sentinel给备选的slave1节点发送REPLICAOF NO ONE命令让该节点成为master。Sentinel给所有其它slave节点发送REPLICAOF 192.168.230.132 6379命令让这些slave成为新master的从节点开始从新的master上同步数据。最后Sentinel将故障节点标记为slave当故障节点恢复后会自动成为新的master的slave节点。 对上述过程可简要概述为Sentinel负责监控主从节点的“健康”状态。当主节点挂掉时自动选择一个最优的从节点切换为主节点。客户端来连接Redis集群时会首先连接Sentinel通过Sentinel来查询主节点的地址然后再去连接主节点进行数据交互。当主节点发生故障时客户端会重新向Sentinel要地址Sentinel会将最新的主节点地址告诉客户端。因此应用程序无需重启即可自动完成主从节点切换。
3 搭建哨兵模式集群
这里我们搭建一个三节点形成的Sentinel哨兵模式集群来监控之前的Redis主从复制模式集群。
Redis哨兵模式集群搭建设计信息如下表所示。 主机名 IP地址 Redis服务/Sentinel服务 角色 node1 192.168.230.131 192.168.230.131:6379 master node2 192.168.230.132 192.168.230.132:6379 slave node3 192.168.230.133 192.168.230.133:6379 slave node1 192.168.230.131 192.168.230.131:26379 sentinel node2 192.168.230.132 192.168.230.132:26379 sentinel node3 192.168.230.133 192.168.230.133:26379 sentinel
在Redis的安装目录下/usr/local/src/redis-7.2.5有一个sentinel.conf配置文件该文件专门用于配置哨兵模式的相关参数信息。文件中用于配置Redis哨兵模式最核心的一个参数是monitor其语法格式见下。
# 默认值sentinel monitor mymaster 127.0.0.1 6379 2
sentinel monitor master-name ip redis-port quorum
上述语句的含义是让Sentinel去监控一个地址为ip:redis-port的主服务器。对该命令中涉及到的几个参数做如下的说明。 参数 作用 master-name 被监控主机名被监控主机名的命名由开发者进行自定义。主名称不应包含特殊字符或空格。 ip 主节点Redis服务IP地址。 redis-port 主节点Redis服务端口。 quorum 票数只有在至少quorum个Sentinel同意的情况下才将其视为O_DOWNObjectively DOWN状态。即表示当有多少个Sentinel认为主服务器宕机时它才算真正的宕机掉通常数量为半数或半数以上才会认为主机已经宕机quorum需要根据Sentinel的数量设置。
3.1 搭建主从复制模式
接下来我们在三台虚拟机中使用主从复制模式搭建一个拥有三台服务器的Redis集群具体操作步骤见下。
1.将三台Redis服务器的redis.conf配置文件/usr/local/src/redis-7.2.5/redis.conf做以下参数的配置。
# 允许访问的地址默认是“bind 127.0.0.1 -::1”会导致只能在本地访问。修改为“bind 0.0.0.0 -::1”则可以在任意IP访问生产环境不要设置为“bind 0.0.0.0 -::1”
bind 0.0.0.0 -::1
# 守护进程修改为yes后即可后台运行默认值为no
daemonize yes
# 保护模式no表示关闭保护模式默认值为yes
protected-mode no
# 密码设置后redis-cli访问必须输入密码默认没有配置密码
requirepass 123456
2.在mater主机和两个slave从机的redis.conf配置文件添加复制同步的密码参数配置即master主机的requirepass参数的取值。该配置项必须添加否则主机将拒绝从机请求。
# 配置复制同步密码(即master主机的requirepass参数的取值)
masterauth 123456
3.按照顺序逐一启动三台Redis服务器并通过客户端连接到Redis服务。
# 检测6379端口是否在监听
$ netstat -lntp | grep 6379
# 进入Redis安装目录
$ cd /usr/local/src/redis-7.2.5
# 指定配置文件启动redis服务
$ redis-server redis.conf
$ redis-cli -h 127.0.0.1 -p 6379 -a 123456
4.依次查看三台Redis服务器的信息发现三台Redis服务器的角色都是master。
127.0.0.1:6379 info replication
5.然后将第二台和第三台Redis服务器设置成192.168.230.131的从服务器。
127.0.0.1:6379 REPLICAOF 192.168.230.131 6379
OK
6.查看master主机的信息发现此时有两台slave从机连接在master主机上日志信息如下所示。
127.0.0.1:6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip192.168.230.132,port6379,stateonline,offset14,lag1
slave1:ip192.168.230.133,port6379,stateonline,offset14,lag1
master_failover_state:no-failover
master_replid:8d667e34232c22c8a145bfa36eea058e876b5f6a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
3.2 配置Sentinel哨兵模式
1.实际开发当中不要直接修改sentinel.conf文件在三台主机上我们先将这个配置文件备份一份。
$ cp sentinel.conf sentinel.conf.backup
2.分别在三台Redis服务器的sentinel.conf文件中添加下面的配置内容。
# 守护进程修改为yes后即可后台运行默认值为no
daemonize yes
# 让Sentinel去监控一个地址为ip:port的主服务器
sentinel monitor mymaster 192.168.230.131 6379 2
# 若主服务器设置了密码则哨兵必须也配置密码否则哨兵无法对主从服务器进行监控该密码与主服务器密码相同
sentinel auth-pass mymaster 123456
auth-pass命令用于设置用于与master主服务器和slave从服务器进行身份验证的密码。需要注意的是master密码也用于slave因此如果你想使用Sentinel监视这些实例则无法在master实例和slave实例中设置不同的密码。
默认情况下Redis Sentinel不作为守护进程运行。如果需要请使用“yes”。请注意Redis在守护进程化时会在/var/run/Redis-sentinel.pid中写入一个pid文件。
3.3 启动Sentinel哨兵模式
1.在三台服务器上按照顺序逐一启动Sentinel哨兵命令见下。
$ redis-sentinel sentinel.conf
2.在第一台Redis机器192.168.230.131上执行添加字符串操作并查看键的值。
127.0.0.1:6379 SET city xian
OK
127.0.0.1:6379 GET city
xian
3.然后在第二台和第三台Redis机器上查看对应city键的值便可获取到如下所示。
127.0.0.1:6379 GET city
xian
至此Redis Sentinel哨兵模式的集群搭建完毕同时启动了Sentinel哨兵集群。此时就算主服务器挂了该集群仍然可以正常运转。
3.4 停止主服务器服务
下面模拟主服务意外宕机的情况首先直接将主服务器的Redis服务终止然后查看从服务器是否被提升为了主服务器。具体操纵演示步骤见下。
1.关闭Redis主服务器master192.168.230.131执行以下命令。
127.0.0.1:6379 SHUTDOWN
(0.75s)
not connected EXIT
2.在192.168.230.132机器上查看Redis主从复制的集群信息。通过查询结果发现该从服务器将192.168.230.133服务器做为master连接。
127.0.0.1:6379 info replication
Error: Server closed the connectionnot connected info replication
# Replication
role:slave
master_host:192.168.230.133
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:109506
slave_repl_offset:109506
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:5719a81cea24fba3fad543bbbe4467a5ba7abcd4
master_replid2:f3b539f424774450b26de565fb92502737f108b4
master_repl_offset:109506
second_repl_offset:105831
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:109492
3.在192.168.230.133机器上查看Redis主从复制的集群信息。通过查询结果发现才服务器的角色从原来的slave变成了master且192.168.230.132变成了它的的从服务器。
127.0.0.1:6379 info replication
Error: Server closed the connectionnot connected info replication
# Replication
role:master
connected_slaves:1
slave0:ip192.168.230.132,port6379,stateonline,offset113435,lag1
master_failover_state:no-failover
master_replid:5719a81cea24fba3fad543bbbe4467a5ba7abcd4
master_replid2:f3b539f424774450b26de565fb92502737f108b4
master_repl_offset:113435
second_repl_offset:105831
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:113421
在Redis集群中开启哨兵模式后如果主服务器master宕机此时所有的从服务器slave在后台会自动发起激烈的投票重新选出新的主服务器master。这就是开启哨兵模式后所发挥的作用。
思考问题假设此时192.168.230.131机器原来的主服务器恢复正常运行状态那么集群环境的状态将会怎样
4.重新启动192.168.230.131机器的Redis服务。
[rootnode1 redis-7.2.5]# redis-server redis.conf
[rootnode1 redis-7.2.5]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with -a or -u option on the command line interface may not be safe.
127.0.0.1:6379 KEYS *
Error: Server closed the connection
not connected KEYS *
1) city
5.查看192.168.230.131机器的Redis信息并观察日志的输入内容。
重新归来的Redis服务启动成功后立刻查看此台机器的Redis服务信息发现角色为master。几秒后再次查看当前机器的Redis服务信息此时发现角色变成slave。原因是在Redis集群中开启了哨兵模式哨兵检测到有新的Redis服务器被启动立刻将该Redis服务拉入到现有的集群中以从服务器的身份加入。
127.0.0.1:6379 info replication
# Replication
role:slave
master_host:192.168.230.133
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:182056
slave_repl_offset:182056
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:5719a81cea24fba3fad543bbbe4467a5ba7abcd4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182056
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:168030
repl_backlog_histlen:14027
哨兵模式也是有缺点的由于所有的写操作都是在master上完成的然后再同步到slave上因此两台机器之间通信会有延迟。当系统很繁忙的时候延迟问题会加重slave机器数量增加问题也会加重。
4 RedisTemplate连接Sentinel
在Sentinel集群监管下的Redis主从集群其节点会因为自动故障转移而发生变化Redis的客户端必须感知这种变化及时更新连接信息。Spring的RedisTemplate底层利用Lettuce实现了节点的感知和自动切换。
下面我们通过一个测试示例来实现RedisTemplate集成Sentinel哨兵机制具体实现步骤见下。
4.1 基础环境搭建
1.创建Spring Boot项目。使用Spring Initializr方式创建一个名为springboot-cache-demo的Spring Boot项目效果如下图所示。 2.引入相关依赖。在项目的pom.xml文件中添加Web模块中的Spring Data Redis依赖启动器、Spring Web依赖、Lombok依赖以及Spring Boot单元测试依赖示例代码如下。
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.8/versionrelativePath//parentgroupIdcom.ytx/groupIdartifactIdredis-advanced-demo/artifactIdversion0.0.1-SNAPSHOT/versionnameredis-advanced-demo/namedescriptionredis-advanced-demo/descriptionurl/licenseslicense//licensesdevelopersdeveloper//developersscmconnection/developerConnection/tag/url//scmpropertiesjava.version21/java.version/propertiesdependencies!-- Spring Data Redis依赖启动器 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configuration/plugin/plugins/build
/project
3.在项目的resources目录下新建全局配置文件application.yml并编写对应的日志级别的配置。
logging:level:io.lettuce.core: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
4.编写Web访问层类。在项目中创建名为com.ytx.controller的包并在该包下创建一个名为HelloRedisController的控制器类。
package com.ytx.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;RestController
public class HelloRedisController {Autowiredprivate StringRedisTemplate redisTemplate;GetMapping(/set/{key}/{value})public String hi(PathVariable String key, PathVariable String value) {redisTemplate.opsForValue().set(key, value);return success;}GetMapping(/get/{key})public String hi(PathVariable String key) {return redisTemplate.opsForValue().get(key);}
}
4.2 配置Sentinel
1.配置Redis Sentinel的连接信息。在项目的全局配置文件application.yml中添加Redis数据库服务器的连接配置示例代码如下。
spring:data:redis:sentinel:master: mymasternodes: # 指定Redis的Sentinel哨兵集群相关信息- 192.168.230.131:26379- 192.168.230.132:26379- 192.168.230.133:26379password: 123456 # Redis密码
2.接下来我们在项目中创建名为com.ytx.config的包在该包下创建一个Redis自定义配置类RedisConfig示例代码如下。
package com.ytx.config;
import io.lettuce.core.ReadFrom;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/** 定义一个Redis配置类 */
Configuration
public class RedisConfig {/** 配置读写分离 */Beanpublic LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {return clientConfigurationBuilder - clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);}
}
在上述代码中使用了io.lettuce.core.ReadFrom类该类中提供了对Redis的读写策略具体介绍见下表。 属性 作用 MASTER 从主节点读取。 MASTER_PREFERRED 优先从master节点读取master不可用才读取replica。 REPLICA 从slavereplica节点读取。 REPLICA _PREFERRED 优先从slavereplica节点读取所有的slave都不可用才读取master。
3.启动项目项目启动成功后通过浏览器访问http://localhost:8080/set/country/China向Redis数据库中插入一条数据结果如下图所示。 4.然后在通过浏览器访问http://localhost:8080/get/country查询key为country的数据结果如下图所示。 5 总结
Redis哨兵模式是一种提高其高可用性的解决方案。在Redis主从复制模式中主服务器宕机需要手动切换从服务器导致服务不可用和数据安全风险。哨兵模式通过引入哨兵节点来自动监控和管理Redis集群。
哨兵节点会定期向Redis节点发送PING命令判断其运行状态。当主服务器出现故障时哨兵节点会自动选择一个从服务器升级为新的主服务器并通知其他节点更新配置实现自动故障转移。这个过程包括投票选举最优从服务器、发送命令让其成为新主服务器并调整其他从服务器的配置。
哨兵模式还具备通知功能当发生故障转移时会将最新信息推送给Redis客户端和其他从节点。这种模式简化了系统管理降低了人为干预的风险提升了Redis集群的可靠性和稳定性。总的来说Redis哨兵模式让Redis服务更加可靠和稳定保障了业务的连续性。