【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生内存数据库 Tair,内存型 2GB
简介: Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。

简介

Redis 的哨兵模式(Sentinel)是用于实现 Redis 高可用性的一种机制。它通过监控主节点和从节点,自动进行主节点故障切换,确保 Redis 集群在主节点出现故障时仍然能够继续提供服务。下面是对 Redis 哨兵模式的详细介绍:

1. Redis 哨兵模式的基本组成

哨兵模式主要由以下几个组件组成:

  • 主节点(Master):提供读写服务的 Redis 实例,所有数据的写操作都由主节点处理。
  • 从节点(Slave):从主节点复制数据的 Redis 实例,通常用于分担读取请求。当主节点宕机时,从节点可以提升为新的主节点。
  • 哨兵(Sentinel):负责监控 Redis 主从节点的实例。哨兵会定期检查主节点和从节点的状态,并在主节点出现故障时,自动进行故障转移(failover),选举一个新的主节点。

2. 哨兵模式的功能

  • 监控(Monitoring):哨兵会定期对主节点和从节点进行健康检查,判断它们是否处于正常工作状态。
  • 通知(Notification):当主节点出现问题时,哨兵可以向管理员或其他系统发出通知。
  • 自动故障转移(Automatic Failover):如果主节点发生故障,哨兵会在多个从节点中选举一个作为新的主节点,并将其他从节点重新配置为从新的主节点进行复制。
  • 配置提供者(Configuration Provider):应用程序可以通过哨兵获取当前主节点的地址,这样即使发生故障转移,应用程序仍然可以通过哨兵来找到新的主节点。

3. 工作机制

3.1 健康检查

每个哨兵会定期向主节点、从节点和其他哨兵实例发送 PING 命令,以判断这些实例是否可达。如果在规定时间内没有收到响应,哨兵会将该节点标记为主观下线(Subjectively Down,SDOWN)。

3.2 主观下线与客观下线

  • 主观下线(SDOWN):单个哨兵实例认为一个节点不可达。
  • 客观下线(Objectively Down,ODOWN):当多数哨兵实例都认为主节点不可达时,会达成共识并认为该节点确实下线。

3.3 故障转移(Failover)

当主节点被判定为 ODOWN 后,哨兵会进行故障转移操作:

  1. 选举领导者:如果有多个哨兵实例,首先需要通过 Raft 协议选举一个领导者来执行故障转移操作。
  2. 选举新的主节点:从可用的从节点中选择一个新的主节点。通常会选择数据最完整且与旧主节点同步延迟最小的从节点。
  3. 重新配置集群:将其他从节点指向新的主节点,并通知客户端更新主节点地址。
  4. 通知客户端:更新客户端连接的主节点地址。

4. 哨兵的优势与局限性

优势:

  • 高可用性:在主节点发生故障时,能够自动切换到新的主节点,保证服务的连续性。
  • 自动化运维:减少人工介入,自动完成故障转移。
  • 动态配置:客户端可以通过哨兵获取最新的主节点信息,无需手动调整。

局限性:

  • 复杂性增加:引入哨兵增加了系统的复杂性,需要额外配置和监控哨兵本身。
  • 网络分区问题:在网络分区的情况下,可能会发生脑裂(Split-brain)现象,导致系统不一致。
  • 依赖多哨兵:为了实现可靠的故障检测和转移,通常需要部署多个哨兵实例,增加了运维成本。

5. 最佳实践

  • 哨兵数量:部署奇数个哨兵实例(至少 3 个),以确保在发生故障时能够达成共识。
  • 独立部署:哨兵实例应尽量部署在独立的服务器上,以避免与 Redis 实例之间的相互影响。
  • 监控与报警:定期检查哨兵的状态,并设置相应的监控和报警机制,及时发现潜在问题。

redis 单实例标准安装

系统优化

# >/etc/sysctl.conf

# socket监听数
echo 'net.core.somaxconn= 2048' >> /etc/sysctl.conf

# 尽可能不使用swap
echo  'vm.swappiness = 0' >> /etc/sysctl.conf   

# 设置kill内存指标
echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf

# 关闭大叶内存
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# 生效
sysctl -p

安装redis

# 安装依赖及命令
yum -y install gcc automake autoconf libtool make jemalloc wget

# 下载安装包
wget  http://download.redis.io/releases/redis-5.0.9.tar.gz

# 解压软件包
tar -xf redis-5.0.9.tar.gz

# 移到工作目录
mv redis-5.0.9 /usr/local/redis50

# 进入工作目录
cd /usr/local/redis50

# 初始化安装
make
make install

配置redis

配置文件中有些端口、文件路径、密码之类的需根据现场情况自行定义。

# 配置环境变量
cat >/etc/profile.d/redis50.sh<<'EOF'
export PATH=/usr/local/redis50/src:$PATH
EOF

# 授权
chmod 700  /etc/profile.d/redis50.sh

# 生效
source /etc/profile.d/redis50.sh

# 创建数据目录
mkdir -p /data/redis/6379/

# 编写配置文件
cat >> /data/redis/6379/redis.conf <<EOF
port 6379
bind 0.0.0.0
daemonize yes
databases 16
protected-mode yes
tcp-backlog 511
timeout 3600
tcp-keepalive 60
pidfile /data/redis/6379/redis.pid
loglevel notice
logfile "/data/redis/6379/redis.log"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
maxmemory 4gb
maxclients 20000
maxmemory-policy allkeys-lru
dir /data/redis/6379/
requirepass Passw0rd
############################## APPEND ONLY MODE ###############################
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-rewrite-incremental-fsync yes
################################# REPLICATION #################################
#slaveof <master_ip> <master_port>
masterauth Passw0rd
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
repl-ping-slave-period 10
repl-timeout 600
repl-backlog-size 100mb
repl-backlog-ttl 3600
################################## SLOW LOG ###################################
# 10000微妙10毫秒
slowlog-log-slower-than 10000
slowlog-max-len 512
############################### ADVANCED CONFIG ###############################
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
################################## SECURITY ###################################
rename-command SHUTDOWN "SHUTDOWN_W9C6Q5xTchUqNL"
rename-command SAVE "SAVE_ohFejQ8aYuEU2x"
rename-command FLUSHALL "FLUSHALL_GaFBQfATtJM7Py"
rename-command FLUSHDB "FLUSHDB_j6ruW0iQ97TenF"
rename-command KEYS "KEYS_ZX778890"
EOF

手工启停redis

# 指定配置文件启动redis
#redis-server /data/redis/6379/redis.conf

# 指定实例及密码关闭redis
#redis-cli -p 6379 -a "Passw0rd"  SHUTDOWN_W9C6Q5xTchUqNL

使用systemd 管理redis

# 编辑配置文件
cat >/usr/lib/systemd/system/redis6379.service<<'EOF'
[Unit]
Description=Redis 6379  server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
# 启动redis
ExecStart=/usr/local/redis50/src/redis-server /data/redis/6379/redis.conf
# 关闭redis
ExecStop=/usr/local/redis50/src/redis-cli -p 6379 -h 127.0.0.1 -a "Passw0rd"  SHUTDOWN_W9C6Q5xTchUqNL
Restart=always
PrivateTmp=true
EOF

# 重载systemd配置
systemctl daemon-reload

启停redis

# 启动redis
systemctl start  redis6379

# 开机自启
systemctl enable  redis6379

# 查看状态
systemctl status redis6379

连接redis

redis-cli  -h 127.0.0.1 -p 6379  -a Passw0rd

测试redis

127.0.0.1:6379> set a 111
OK
127.0.0.1:6379> set b 2222
OK
127.0.0.1:6379> set c 3333
OK
127.0.0.1:6379> set d 4444
OK
127.0.0.1:6379> DBSIZE
(integer) 4

远程连接

redis-cli  -h 10.10.8.203 -p 6379 -a Passw0rd
10.10.8.203:6379> DBSIZE
(integer) 4
10.10.8.203:6379> exit # 退出命令行

# 查看内存
info memory

redis性能监控

# Server
# Clients
# Memory
# Persistence
# Stats
# Replication
# CPU
# Cluster
# Keyspace

主从复制

redis的主从配置非常简单,只需要在配置文件或命令行中指定主从的密码,然后在登录从库命令行指定主库的地址即可。

# 登录从库指定主库地址
127.0.0.1:6379> slaveof 10.10.8.203 6379
OK

# 查看状态
127.0.0.1:6379> info replication

或者

# 免登录指定
redis-cli -a "Passw0rd" -p 6379 -h 10.10.8.204   SLAVEOF 10.10.8.203 6379
redis-cli -a "Passw0rd" -p 6379 -h 10.10.8.206   SLAVEOF 10.10.8.203 6379


# 免登录查看状态
redis-cli -p 6379 -h 10.10.8.203 -a "Passw0rd" info replication
redis-cli -p 6379 -h 10.10.8.204 -a "Passw0rd" info replication
redis-cli -p 6379 -h 10.10.8.206 -a "Passw0rd" info replication

配置sentinel

三台机器都要配置sentinel,以监视每个redis实例的状态。

配置

# 创建目录
mkdir -p /usr/local/redis50/sentinel/26379
cd    /usr/local/redis50/sentinel/26379

# 配置
cat >/usr/local/redis50/sentinel/26379/sentinel.conf<<EOF
port 26379
bind 0.0.0.0
logfile "/usr/local/redis50/sentinel/26379/sentinel.log"
pidfile "/usr/local/redis50/sentinel/26379/redis-sentinel.pid"
dir "/usr/local/redis50/sentinel/26379"
sentinel monitor mymaster 10.10.8.203 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
sentinel parallel-syncs mymaster 3
sentinel auth-pass mymaster Passw0rd
sentinel client-reconfig-script mymaster /usr/local/redis50/scripts/6379/failover.sh
EOF

# 配置切换脚本
mkdir -p  /usr/local/redis50/scripts/6379/
cat >/usr/local/redis50/scripts/6379/failover.sh<<'EOF'
#!/bin/bash
MASTER_IP=$6  #第六个参数是新主redis的ip地址
LOCAL_IP='10.10.8.203'  #当前主机的IP
VIP='10.10.8.210'       # 虚拟IP
NETMASK='23'
INTERFACE='ens192'
if [ ${MASTER_IP} = ${LOCAL_IP} ];then   
    /sbin/ip  addr  add ${VIP}/${NETMASK}  dev ${INTERFACE}  #将VIP绑定到该服务器上
    /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
    exit 0
else 
   /sbin/ip  addr del  ${VIP}/${NETMASK}  dev ${INTERFACE}   #将VIP从该服务器上删除
   exit 0
fi
exit 1  #如果返回1,sentinel会一直执行这个脚本
EOF

# 授权
chmod +x /usr/local/redis50/scripts/6379/failover.sh

注意修改切换脚本的本地IP,每台机器都不同

启停

当存在多个实例时请根据,现场环境进行多实例配置管理

# 手动启动
#redis-sentinel /usr/local/redis50/sentinel/26379/sentinel.conf  &

# systemd管理
cat  >/usr/lib/systemd/system/sentinel_26379.service<<'EOF'
[Unit]
Description=Redis_sentinel_26379_server 
Before=httpd.service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/redis50/src/redis-sentinel  /usr/local/redis50/sentinel/26379/sentinel.conf
[Install]
WantedBy=multi-user.target
EOF

# 重载systemd配置
systemctl daemon-reload

systemctl start sentinel_26379
systemctl enable sentinel_26379
systemctl status sentinel_26379
systemctl restart sentinel_26379

绑定VIP

第一次开启需要在主库上,手动绑定VIP,请根据自己的网卡信息进行配置。

# 主库手动绑定VIP
/sbin/ip  addr add 10.10.8.210/23 dev ens192
/sbin/arping -q   -c 3 -A 10.10.8.210 -I ens192

# 删除VIP 
#ip addr del 10.10.8.210 dev ens192

测试切换

当安装配置完成后,可以关闭主节点,实时观察一台主机的sentinel日志信息,获取是否切换成功。

切换时,新主库的sentinel如运行异常或关闭,VIP将会切换失败,如果旧主库的sentinel运行异常或关闭VIP也有可能切换失败或发生脑裂。

切换成功的前提是必须保证有两个sentinel节点运行正常。

# 打开日志
tail -f  /usr/local/redis50/sentinel/26379/sentinel.log

# 关闭主节点
#systemctl stop  redis6379.service

# 查看VIP是否切换成功
ip  addr
  • 打开日志观察主库位置
  • 关闭主节点
  • 查看日志是否切换
  • 查看VIP是否切换

故障恢复

sentinel的恢复十分简单,当你开启旧主库后,会自动开启主从复制,sentinel也会将该节点加入到集群中。

如果无法恢复主从,可以直接重做从库开启主从后会自动将该从库加入节点。

systemctl start   redis6379.service

# 删除VIP // 用在发生脑裂时删除一台主机上的IP地址
#ip addr del 10.10.8.210 dev ens192
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
18天前
|
NoSQL Redis
Redis 执行 Lua保证原子性原理
Redis 执行 Lua 保证原子性原理
81 1
|
22天前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
45 0
|
1天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
16天前
|
缓存 NoSQL Java
惊!Spring Boot遇上Redis,竟开启了一场缓存实战的革命!
【8月更文挑战第29天】在互联网时代,数据的高速读写至关重要。Spring Boot凭借简洁高效的特点广受开发者喜爱,而Redis作为高性能内存数据库,在缓存和消息队列领域表现出色。本文通过电商平台商品推荐系统的实战案例,详细介绍如何在Spring Boot项目中整合Redis,提升系统响应速度和用户体验。
41 0
|
16天前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
44 1
|
3月前
|
监控 Java Sentinel
使用Sentinel进行服务调用的熔断和限流管理(SpringCloud2023实战)
Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
99 3
|
1天前
|
监控 Java Nacos
SpringCloud基础5——微服务保护、Sentinel
sentinel、雪崩问题、流量控制、隔离和降级、授权规则、规则持久化
SpringCloud基础5——微服务保护、Sentinel
|
2月前
|
监控 Java 应用服务中间件
SpringCloud面试之流量控制组件Sentinel详解
SpringCloud面试之流量控制组件Sentinel详解
140 0
|
2月前
|
监控 Dubbo 应用服务中间件
通用快照方案问题之Sentinel与SpringCloud和Dubbo的整合如何解决
通用快照方案问题之Sentinel与SpringCloud和Dubbo的整合如何解决
37 0
|
3月前
|
Java 开发者 Sentinel
Spring Cloud系列——使用Sentinel进行微服务保护
Spring Cloud系列——使用Sentinel进行微服务保护
52 5

相关产品

  • 云数据库 Tair(兼容 Redis)