Redis高可用方案:sentinel(哨兵模式)以及springboot整合sentinel模式

一、前言

单点的redis如果崩溃或者宕机了,是很容易造成程序问题的。所以需要高可用的redis方案。sentinel是常用的redis高可用方案之一,本篇文章将记录整个搭建过程。

二、图解

我采用的是一主二从三哨兵,如图:

在这里插入图片描述

 三、关于 Redis Sentinel 的概念

Redis Sentinel(译为“哨兵”)是 Redis 官方推荐的高可用性(HA)解决方案,当用 Redis 做 Master-slave 的高可用方案时,假如 master 宕机了,Redis 本身(包括它的很多客户端)都没有实现自动进行主备切换,而 Redis-sentinel 本身也是一个独立运行的进程,它能监控多个 master-slave 集群,发现 master 宕机后能进行自动切换。

Redis Sentinel 系统用于管理多个 Redis 服务器(instance),该系统执行以下三个任务:

  • 监控(Monitoring):Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification):当被监控的某个 Redis 服务器出现问题时,Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover):当一个主服务器不能正常工作时,Sentinel 会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。

Redis Sentinel 是一个分布式系统,你可以在一个架构中运行多个 Sentinel 进程(progress),这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。

一个 Sentinel 进程可以与其他多个 Sentinel 进程进行连接,每个 Sentinel 进程之间可以互相检查对方的可用性,并进行信息交换。

四、 搭建 Redis Server(master)

我们就按照上面的架构图进行搭建,大概三台服务器(防火墙关闭):

因为我没有三台服务器,我都装在一台上,模拟在三台上:

47.xxx.xx.102: master redis-server-6379,redis-sentinel -26379

47.xxx.xx.102: slave redis-server-6380 ,redis-sentinel-26380

47.xxx.xx.102: slave redis-server-6381, redis-sentinel-26381

下载redis包,解压到相应的目录,修改配置。

redis配置解释

master-6379机器redis配置:

#bind 127.0.0.1,这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接
#bind 127.0.0.1
#保护模式,默认开启,分两种:1、关闭protected-mode模式  2、配置bind或者设置密码
protected-mode yes 
#端口
port 6379
#请求密码
requirepass "123456"
tcp-backlog 511
#当客户端闲置多长秒后关闭连接,如果指定为 0 ,表示关闭该功能
timeout 0
tcp-keepalive 300
# 使用守护进程模式
daemonize yes
supervised no
#当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定
pidfile "/var/run/redis_6379.pid"
#指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warningnotice生产常用等级,默认为 notice
loglevel notice
#日志文件路径
logfile "/usr/local/redis/redis-4.0.1_6379/log/redis_6379.log"
databases 16
always-show-logo yes
#RDB配置
save 900 1
save 300 10
save 60 10000

stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
#指定本地数据库文件名,默认值为 dump.rdb
dbfilename "dump.rdb"
#指定本地数据库存放目录
dir "/usr/local/redis/redis-4.0.1_6379/data"

slave-6380机器redis配置:

protected-mode no
port 6380
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile "/var/run/redis_6379.pid"

loglevel notice
logfile "/usr/local/redis/redis-4.0.1_6380/redis_6380.log"

databases 16
always-show-logo yes

save 900 1
save 300 10
save 60 10000

dir "/usr/local/redis/redis-4.0.1_6380/data"
#设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步
slaveof 47.xx.xx.102 6379

requirepass "123456"
# 设置访问 master 的密码
masterauth 123456

slave-6381机器redis配置:

protected-mode no
port 6381
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile "/var/run/redis_6381.pid"

loglevel notice
logfile "/usr/local/redis/redis-4.0.1_6381/redis_6381.log"

databases 16
always-show-logo yes

save 900 1
save 300 10
save 60 10000

dir "/usr/local/redis/redis-4.0.1_6381/data"

slaveof 47.110.12.102 6379

requirepass "123456"
# 设置访问 master 的密码
masterauth 123456

依次启动不同服务器上的三台redis服务器:

./redis-server etc/redis_6379.config

./redis-server etc/redis_6380.config

./redis-server etc/redis_6381.config

查看主从信息:INFO replication(因为写文章时,sentinel已经搭建好了,且进行过故障转移,所以当前master是端口为6381的机器)

slave角色redis信息:

[root@iZbp1i9fu1a7yjd42innezZ etc]# ../bin/redis-cli -h 127.0.0.1 -p 6379 -a 123456
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:47.110.12.102
master_port:6381
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:104705046
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:48c11566ab36630e66aeabfa67192368a12fd66c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:104705046
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:103656471
repl_backlog_histlen:1048576

master角色redis信息:

[root@iZbp1i9fu1a7yjd42innezZ etc]# ../bin/redis-cli -h 127.0.0.1 -p 6381 -a 123456
127.0.0.1:6381> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=47.110.12.102,port=6379,state=online,offset=104777860,lag=1
slave1:ip=47.110.12.102,port=6380,state=online,offset=104777860,lag=1
master_replid:48c11566ab36630e66aeabfa67192368a12fd66c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:104777860
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:103729285
repl_backlog_histlen:1048576

五、 搭建 Redis Server(slave)

接着,我们分别在三台服务器上,配置 Redis Sentinel,创建redis-4.0.1/sentinel-26379.conf(sentinel-26380.conf、sentinel-26381.conf)配置文件,示例配置(记得更改不同的bind ip):

sentinel-26379.conf:

port 26379
daemonize yes
protected-mode no
logfile "/usr/local/redis/redis-4.0.1_6379/log/sentinel_26379.log"
dir "/usr/local/redis/redis-4.0.1_6379/temp"

sentinel monitor mymaster 47.110.xx.xxx 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 15000
sentinel auth-pass mymaster 123456
sentinel parallel-syncs mymaster 1

这四行配置为一组,因为我们只有一个 master 节点,所以只配置了一个 master,可以配置多个 master,不用配置 slave 的信息,因为 slave 能够被自动检测到(master 节点会有关于 slave 的消息)

第一行配置指示 Sentinel 去监视一个名为manager1的主服务器,这个主服务器的 IP 地址为10.9.10.154,端口号为 6379,而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意(只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)。

选项说明:

  • auth-pass:选项指定了 master 的连接密码。
  • down-after-milliseconds:选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。
  • failover-timeout:如果在该时间(ms)内未能完成 failover 操作,则认为该 failover 失败。
  • parallel-syncs:选项指定了在执行故障转移时,最多可以有多少个从服务器同时对新的主服务器进行同步,这个数字越小,完成故障转移所需的时间就越长。

 

sentinel-26380.conf:

port 26380
daemonize yes
protected-mode no
logfile "/usr/local/redis/redis-4.0.1_6380/sentinel_26380.log"
dir "/usr/local/redis/redis-4.0.1_6380/temp"

sentinel monitor mymaster 47.110.xx.xxx 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 15000
sentinel auth-pass mymaster 123456
sentinel parallel-syncs mymaster 1

sentinel-26379.conf:

port 26381
daemonize yes
protected-mode no
logfile "/usr/local/redis/redis-4.0.1_6381/sentinel_26381.log"
dir "/usr/local/redis/redis-4.0.1_6381/temp"

sentinel monitor mymaster 47.110.xx.xxx 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 15000
sentinel auth-pass mymaster 123456
sentinel parallel-syncs mymaster 1

依次启动不同服务器上的sentinel:

../bin/redis-server sentinel-26379.conf --sentinel

../bin/redis-server sentinel-26380.conf --sentinel

../bin/redis-server sentinel-26381.conf --sentinel

 当有其他服务器启动 Redis Sentinel 的时候,会有这样的日志(Redis Sentinel 是会相互通信的):

24113:X 20 Oct 02:36:47.607 * +sentinel sentinel 39e2a84573443574f8cf5839aa92509ca1878a16 127.0.0.1 26380 @ mymaster 47.110.12.102 6379

 六、Redis Sentinel 故障转移测试

测试当前master角色为:redis-6381

首先kill掉当前master角色redis-6381进程,或者执行redis-cli shutdown命令:

sentinel_26379日志(sentinel_26380、sentinel_26381日志一致):

24113:X 20 Oct 16:32:36.709 +sdown master mymaster 47.110.12.102 6381
24113:X 20 Oct 16:32:36.709 # +new-epoch 418143
24113:X 20 Oct 16:32:36.711 # +vote-for-leader 95f44f2cb9f4b2a0dfdb51db0d0e405974352052 418143
24113:X 20 Oct 16:32:36.941 # +odown master mymaster 47.110.12.102 6381 #quorum 2/2
24113:X 20 Oct 16:32:36.941 # Next failover delay: I will not start a failover before Tue Oct 20 16:33:07 2020
24113:X 20 Oct 16:32:37.470 * +sentinel-address-switch master mymaster 47.110.12.102 6381 ip 172.16.134.91 port 26380 for 39e2a84573443574f8cf5839aa92509ca1878a16
24113:X 20 Oct 16:32:37.503 # -odown master mymaster 47.110.12.102 6381
24113:X 20 Oct 16:32:37.576 # +config-update-from sentinel 95f44f2cb9f4b2a0dfdb51db0d0e405974352052 172.16.134.91 26381 @ mymaster 47.110.12.102 6381
24113:X 20 Oct 16:32:37.576 # +switch-master mymaster 47.110.12.102 6381 47.110.12.102 6380

翻译一下就是:

  1. 每个 Sentinel 发现了主节点挂掉了并有一个 +sdown 事件
  2. 这个事件稍候升级到 +odown,意味着大多数 Sentinel 已经同意了主节点是不可达的。
  3. Sentinels 开始投票一个 Sentinel 开始并尝试故障转移
  4. 故障转移开始 

另外,需要注意的是,Redis Sentinel 并不是提供对外服务的地址,它只是管理 Redis 主备切换的监测工具,所以,对外 Client 提供的地址,仍是 Redis Server 的地址(包含 salve),当然,也可以像提供负载均衡(SLB)或者虚拟IP(Virtual IP,VIP),进行统一地址的访问。 

七、springboot项目中如何连接Redis哨兵模式

1.引入springboot-redis依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.application.properties配置redis哨兵模式相关参数

# database name
spring.redis.database=0
# server password 密码,如果没有设置可不配
spring.redis.password=123456
# pool settings ...池配置
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
# name of Redis server  哨兵监听的Redis server的名称
spring.redis.sentinel.master=mymaster
# comma-separated list of host:port pairs  哨兵的配置列表
spring.redis.sentinel.nodes=47.110.12.102:26379,47.110.12.102:26380,47.110.12.102:26381

3.代码中测试

    @Autowired
    RedisTemplate redisTemplate;

    @Test
    public void setKey(){
        redisTemplate.opsForValue().set("test100","100");
        System.out.println("############"+redisTemplate.opsForValue().get("test100"));
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值