【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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值