目录
一、哨兵和复制
1.1 哨兵(sentinal)
1.Redis哨兵主要功能
2.Redis哨兵的高可用
1.2 Redis复制(Replication)
1.数据复制原理(执行步骤)
1.3 Redis 主从复制、哨兵和集群这三个有什么区别
二、Java访问哨兵实现
一、哨兵和复制
谈到Redis服务器的高可用,如何保证备份的机器是原始服务器的完整备份呢?
这时候就需要哨兵和复制。
哨兵(Sentinel): 可以管理多个Redis 服务器,它提供了监控,提醒以
及自动的故障转移的功能。
复制(Replication) :则是负责让一个Redis 服务器可以配备多个备份的
服务器。
Redis正是利用这两个功能来保证Redis的高可用。
1.1 哨兵(sentinal)
哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复
制出现故障时需要人为干预的问题。
1.Redis哨兵主要功能
(1)集群监控 :负责监控Redis master和 slave 进程是否正常工作
(2)消息通知:如果某个Redis 实例有故障,那么哨兵负责发送消息作为报警
通知给管理员
(3)故障转移:如果master node挂掉了,会自动转移到slave node上
(4)配置中心 :如果故障转移发生了,通知client 客户端新的master 地址
2.Redis哨兵的高可用
原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。
哨兵机制建立了多个哨兵节点(进程),共同监控数据节点的运行状况。同时哨兵节点之间也互相通信,交换对主从节点的监控状况。每隔1秒每个哨兵会向整个集群: Master 主服务器+Slave从服务器+其他Sentinel (哨兵)进程,发送一次 ping 命令做一次心跳检测。
哨兵用来判断节点是否正常的重要依据,涉及两个新的概念:主观下线和客观下线。
- 主观下线: 一个哨兵节点判定主节点down 掉是主观下线。
- 客观下线:只有半数哨兵节点都主观判定主节点down 掉,此时多个哨兵节点交换主观判定结果,才会判定主节点客观下线。
原理:基本上哪个哨兵节点最先判断出这个主节点客观下线,就会在各个哨兵 节点中发起投票机制Raft算法(选举算法),最终被投为领导者的哨兵节点完成主从自动化切换的过程。
1.2 Redis复制(Replication)
Redis为了解决单点数据库问题,会把数据复制多个副本部署到其他节点上,通 过复制,实现Redis 的高可用性,实现对数据的冗余备份,保证数据和服务的高度可靠性。
1.数据复制原理(执行步骤)
①从数据库向主数据库发送sync (数据同步)命令。
②主数据库接收同步命令后,会保存快照,创建一个RDB 文件。
③当主数据库执行完保持快照后,会向从数据库发送RDB 文件,而从数据库会
接收并载入该文件。
④主数据库将缓冲区的所有写命令发给从服务器执行。
⑤以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发
送给从数据库。
注意:主从断开重连后会根据断开之前最新的命令偏移量进行增量复制。
reidis-slave节点运行日志:
24268:S 24 Apr 2023 15:19:49.735 * Ready to accept connections
24268:S 24 Apr 2023 15:19:49.735 * Connecting to MASTER 192.168.2.212:6379
24268:S 24 Apr 2023 15:19:49.735 * MASTER <-> REPLICA sync started
24268:S 24 Apr 2023 15:19:49.736 * Non blocking connect for SYNC fired the event.
24268:S 24 Apr 2023 15:19:49.736 * Master replied to PING, replication can continue...
24268:S 24 Apr 2023 15:19:49.737 * Partial resynchronization not possible (no cached master)
24268:S 24 Apr 2023 15:19:49.738 * Full resync from master: 95bd682b26515c903d9dca88bf171e97f30da682:0
24268:S 24 Apr 2023 15:19:49.760 * MASTER <-> REPLICA sync: receiving 175 bytes from master to disk
24268:S 24 Apr 2023 15:19:49.760 * MASTER <-> REPLICA sync: Flushing old data
24268:S 24 Apr 2023 15:19:49.761 * MASTER <-> REPLICA sync: Loading DB in memory
24268:S 24 Apr 2023 15:19:49.762 * Loading RDB produced by version 6.2.6
24268:S 24 Apr 2023 15:19:49.762 * RDB age 0 seconds
24268:S 24 Apr 2023 15:19:49.762 * RDB memory usage when created 1.91 Mb
24268:S 24 Apr 2023 15:19:49.762 # Done loading RDB, keys loaded: 0, keys expired: 0.
24268:S 24 Apr 2023 15:19:49.762 * MASTER <-> REPLICA sync: Finished with success
24268:S 24 Apr 2023 15:19:49.763 * Background append only file rewriting started by pid 24272
24268:S 24 Apr 2023 15:19:49.787 * AOF rewrite child asks to stop sending diffs.
24272:C 24 Apr 2023 15:19:49.788 * Parent agreed to stop sending diffs. Finalizing AOF...
24272:C 24 Apr 2023 15:19:49.788 * Concatenating 0.00 MB of AOF diff received from parent.
24272:C 24 Apr 2023 15:19:49.788 * SYNC append only file rewrite performed
24272:C 24 Apr 2023 15:19:49.789 * AOF rewrite: 0 MB of memory used by copy-on-write
24268:S 24 Apr 2023 15:19:49.836 * Background AOF rewrite terminated with success
24268:S 24 Apr 2023 15:19:49.836 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
24268:S 24 Apr 2023 15:19:49.837 * Background AOF rewrite finished successfully
1.3 Redis 主从复制、哨兵和集群这三个有什么区别
- 主从模式 :读写分离,备份, 一个Master 可以有多个Slaves。
- 哨兵sentinel: 监控,自动转移,哨兵发现主服务器挂了后,就会从slave 中
重新选举一个主服务器。
- 集群 :为了解决单机Redis 容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS 不受限于单机,可受益于分布式集群高扩展性。哨兵作用于高可用,集群提高并发量
二、Java访问哨兵实现
哨兵搭建: sRedis 6.x哨兵模式部署(五)_开着拖拉机回家的博客-CSDN博客
pom.xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
代码示例
package com.kangna.redi;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/*********************************************************************
*
*@Author kangll
*@Date 2023/4/25 15:11
*@Desc Java 连接 Redis
*
********************************************************************/
public class RedisConn {
public static void main(String[] args) {
//连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
jedisPoolConfig.setMinIdle(5);
//哨兵信息
Set<String> sentinels = new HashSet<String>(Arrays.asList(
"192.168.2.211:26379",
"192.168.2.212:26379",
"192.168.2.213:26379"
));
//创建连接池
//mymaster是我们配置给哨兵的服务名称
//sentinels是哨兵信息
//jedisPoolConfig是连接池配置
//abcdefg是连接Redis服务器的密码
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig, "123456");
//获取客户端
Jedis jedis = pool.getResource();
//执行两个命令
jedis.set("kafka", "kangll");
String myvalue = jedis.get("kafka");
//打印信息
System.out.println(myvalue);
}
}
redis 命令行查询结果: