当前位置: 首页 > news >正文

Redis搭建哨兵模式一主两从三哨兵

Redis搭建哨兵模式一主两从三哨兵

目录

Redis搭建哨兵模式一主两从三哨兵

一、Redis哨兵模式

1. 哨兵模式原理:

2. 哨兵的作用:

3.哨兵的结构

4.故障转移机制

故障转移过程如下:

主节点的选举条件:

二、节点规划

三、实施部署

1.关闭防火墙安全内核机制,所有节点全部执行

2.分别修改主机名

3.修改所有节点hosts文件

4.主从部署

5.修改Master节点配置文件

6.修改slave1和slave2两个从节点

8.哨兵部署

9.启动哨兵模式所有节点都要启动

10.在master查看哨兵信息

总结


一、Redis哨兵模式

哨兵的核心功能:在主从复制的基础上,哨兵引入了主节点的自动故障转移

1. 哨兵模式原理:

哨兵:是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的Master。所以整个运行哨兵的集群的数量不得少于3个节点。

2. 哨兵的作用:

监控:哨兵会不断地检查主节点和从节点是否运作正常。

自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,他会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

通知提醒:哨兵可以将故障转移的结果发送给客户端

3.哨兵的结构

哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点就是特殊的redis节点,不存储数据

数据节点:主节点和从节点都是数据节点

注意:

哨兵的启动依赖主从模式,所以须把主从模式安装好的情况下再去做哨兵模式,所有节点上都需要部署哨兵模式,哨兵模式会监控所有的Redis工作节点是否正常

4.故障转移机制

  由哨兵节点定期监控主节点是否出现了故障,每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。 如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的),当超过半数哨兵节点认为该主节点下线了,这样就客观下线了。 此时哨兵节点会通过Raft算法〈选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。

故障转移过程如下:

1.将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;

2.若原主节点恢复也变成从节点,并指向新的主节点

3.通知客户端主节点已经更换

主节点的选举条件:

1.过滤掉不健康的(已下线的),没有回复哨兵ping响应的丛节点

2.选择配置文件中从节点优先级最高的(replication-priority,默认值为100)

3.选择复制偏移量最大的,也就是复制最完整的从节点。

二、节点规划

节点服务器IPCPU内存磁盘版本

master

Almalinux

10.0.20.176

816150

redis-7.4.2.tar.gz

slave1

Almalinux

10.0.20.177

816150

redis-7.4.2.tar.gz

slave2

Almalinux

10.0.20.178

816150

redis-7.4.2.tar.gz

三、实施部署

1.关闭防火墙安全内核机制,所有节点全部执行

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

2.分别修改主机名

[root@localhost ~]# hostnamectl set-hostname master && bash    #10.0.20.176
[root@localhost ~]# hostnamectl set-hostname slave1 && bash     #10.0.20.177
[root@localhost ~]# hostnamectl set-hostname slave2 && bash     #10.0.20.178

3.修改所有节点hosts文件

[root@master ~]#  cat >>/etc/hosts<< EOF
10.0.20.176 master
10.0.20.177 slave1
10.0.20.178 slave2
EOF

4.主从部署

所有节点源码编译安装redis(也可以使用下方一键安装脚本)

将源码包上传至/usr/local/src路径下

#!/bin/bash# ====== 配置变量 ======
REDIS_VERSION="7.4.2"
REDIS_PORT="63790"
REDIS_USER="redis"
REDIS_GROUP="redis"
REDIS_HOME="/usr/local/redis"
REDIS_DATA_DIR="/var/lib/redis"
REDIS_LOG_DIR="/var/log/redis"
REDIS_RUN_DIR="/var/run/redis"# ====== 颜色输出函数 ======
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Colorlog_info() {echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}log_warning() {echo -e "${YELLOW}[WARNING]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}log_error() {echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}# ====== 检查并安装依赖 ======
install_dependencies() {log_info "开始安装依赖包..."# 检查并安装tarif ! command -v tar &> /dev/null; thenyum -y install tarlog_info "已安装tar"elselog_info "tar已安装"fi# 检查并安装gccif ! command -v gcc &> /dev/null; thenyum -y install gcclog_info "已安装gcc"elselog_info "gcc已安装"fi# 检查gcc是否安装成功if ! command -v gcc &> /dev/null; thenlog_error "GCC安装失败,请检查YUM源配置"exit 1fi
}# ====== 配置系统参数 ======
configure_system() {log_info "配置系统参数..."# 配置内存过度分配if ! grep -q "vm.overcommit_memory = 1" /etc/sysctl.conf; thenecho "vm.overcommit_memory = 1" >> /etc/sysctl.confsysctl -plog_info "已配置内存过度分配策略"fi# 配置透明大页 (需要重启生效)if [ ! -f /etc/rc.d/rc.local ]; thenecho '#!/bin/bash' > /etc/rc.d/rc.localfichmod +x /etc/rc.d/rc.localif ! grep -q "transparent_hugepage" /etc/rc.d/rc.local; thenecho 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.locallog_info "已配置透明大页禁用(重启后生效)"fi
}# ====== 创建Redis用户和组 ======
create_redis_user() {log_info "创建Redis用户和组..."if ! getent group ${REDIS_GROUP} > /dev/null; thengroupadd -r ${REDIS_GROUP}log_info "已创建Redis组: ${REDIS_GROUP}"fiif ! id -u ${REDIS_USER} > /dev/null 2>&1; thenuseradd -r -g ${REDIS_GROUP} -s /sbin/nologin ${REDIS_USER}log_info "已创建Redis用户: ${REDIS_USER}"fi
}# ====== 安装Redis ======
install_redis() {log_info "开始安装Redis ${REDIS_VERSION}..."# 检查Redis源码包是否存在if [ ! -f "/usr/local/src/redis-${REDIS_VERSION}.tar.gz" ]; thenlog_error "Redis源码包不存在: /usr/local/src/redis-${REDIS_VERSION}.tar.gz"exit 1fi# 解压Redis源码tar -zxf "/usr/local/src/redis-${REDIS_VERSION}.tar.gz" -C /usr/localif [ $? -ne 0 ]; thenlog_error "解压Redis源码包失败"exit 1fi# 重命名目录mv "/usr/local/redis-${REDIS_VERSION}" "${REDIS_HOME}"# 编译安装Rediscd "${REDIS_HOME}"make MALLOC=libcif [ $? -ne 0 ]; thenlog_error "Redis编译失败"exit 1ficd "${REDIS_HOME}/src"make install PREFIX="${REDIS_HOME}"if [ $? -ne 0 ]; thenlog_error "Redis安装失败"exit 1filog_info "Redis ${REDIS_VERSION} 安装成功"
}# ====== 配置Redis ======
configure_redis() {log_info "配置Redis..."# 创建数据和日志目录mkdir -p ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}chown -R ${REDIS_USER}:${REDIS_GROUP} ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}chmod -R 755 ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}# 修改Redis配置文件if [ -f "${REDIS_HOME}/redis.conf" ]; then# 备份原始配置文件cp "${REDIS_HOME}/redis.conf" "${REDIS_HOME}/redis.conf.bak"# 应用配置修改sed -i 's/^bind 127.0.0.1/bind 0.0.0.0/g' "${REDIS_HOME}/redis.conf"   # 开放对外链接sed -i 's/daemonize no/daemonize yes/' "${REDIS_HOME}/redis.conf"      # 守护进程方式启动sed -i 's/protected-mode yes/protected-mode no/' "${REDIS_HOME}/redis.conf"   # 开放外部访问sed -i "s/port 6379/port ${REDIS_PORT}/" "${REDIS_HOME}/redis.conf"    # 修改端口号# 添加额外配置echo "dir ${REDIS_DATA_DIR}" >> "${REDIS_HOME}/redis.conf"echo "logfile ${REDIS_LOG_DIR}/redis.log" >> "${REDIS_HOME}/redis.conf"echo "pidfile ${REDIS_RUN_DIR}/redis.pid" >> "${REDIS_HOME}/redis.conf"# 设置配置文件权限chown ${REDIS_USER}:${REDIS_GROUP} "${REDIS_HOME}/redis.conf"chmod 644 "${REDIS_HOME}/redis.conf"log_info "Redis配置已完成"elselog_error "Redis配置文件不存在: ${REDIS_HOME}/redis.conf"exit 1fi
}# ====== 创建Systemd服务 ======
create_systemd_service() {log_info "创建Systemd服务..."cat > /etc/systemd/system/redis.service << EOF
[Unit]
Description=Redis In-Memory Data Store
Documentation=https://redis.io/documentation
After=network.target[Service]
Type=forking
User=${REDIS_USER}
Group=${REDIS_GROUP}
PIDFile=${REDIS_RUN_DIR}/redis.pid
ExecStart=${REDIS_HOME}/bin/redis-server ${REDIS_HOME}/redis.conf
ExecStop=${REDIS_HOME}/bin/redis-cli -h 127.0.0.1 -p ${REDIS_PORT} shutdown
Restart=always
RestartSec=3
LimitNOFILE=65535
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
PrivateTmp=true[Install]
WantedBy=multi-user.target
EOF# 重新加载Systemd配置systemctl daemon-reloadlog_info "Systemd服务已创建"
}# ====== 创建符号链接 ======
create_symlinks() {log_info "创建符号链接..."ln -sf "${REDIS_HOME}/bin/redis-cli" /usr/local/sbin/redis-cliln -sf "${REDIS_HOME}/bin/redis-server" /usr/local/sbin/redis-server# 添加到PATH环境变量if ! grep -q "${REDIS_HOME}/bin" /etc/profile; thenecho "export PATH=\${PATH}:${REDIS_HOME}/bin" >> /etc/profilesource /etc/profilefilog_info "符号链接已创建"
}# ====== 配置防火墙 ======
configure_firewall() {log_info "配置防火墙..."if systemctl is-active --quiet firewalld; thenfirewall-cmd --permanent --add-port=${REDIS_PORT}/tcpfirewall-cmd --reloadlog_info "已放行TCP ${REDIS_PORT}端口"elselog_warning "firewalld未运行,跳过端口放行"fi
}# ====== 启动Redis服务 ======
start_redis_service() {log_info "启动Redis服务..."# 设置目录权限chown -R ${REDIS_USER}:${REDIS_GROUP} ${REDIS_HOME}# 启动并启用服务systemctl start redissystemctl enable redis# 检查服务状态sleep 2  # 等待服务启动if systemctl is-active --quiet redis; thenlog_info "Redis服务启动成功"systemctl status redis --no-pagerelselog_error "Redis服务启动失败"journalctl -u redis --since "1 minute ago" --no-pagerexit 1fi
}# ====== 安装后提示 ======
post_install_info() {echo ""log_info "========== Redis 安装完成 =========="log_info "版本: Redis ${REDIS_VERSION}"log_info "端口: ${REDIS_PORT}"log_info "配置文件: ${REDIS_HOME}/redis.conf"log_info "数据目录: ${REDIS_DATA_DIR}"log_info "日志文件: ${REDIS_LOG_DIR}/redis.log"log_info "管理命令:"log_info "  启动: systemctl start redis"log_info "  停止: systemctl stop redis"log_info "  状态: systemctl status redis"log_info "  连接: redis-cli -p ${REDIS_PORT}"echo ""log_warning "注意: 当前配置未设置密码,生产环境请设置requirepass"log_warning "      修改配置文件: ${REDIS_HOME}/redis.conf"log_warning "      取消注释: # requirepass foobared 并设置强密码"echo ""
}# ====== 主执行流程 ======
main() {log_info "开始Redis安装流程"# 检查root权限if [ "$(id -u)" != "0" ]; thenlog_error "此脚本必须使用root权限运行"exit 1fi# 执行安装步骤install_dependenciesconfigure_systemcreate_redis_userinstall_redisconfigure_rediscreate_systemd_servicecreate_symlinksconfigure_firewallstart_redis_servicepost_install_infolog_info "Redis安装完成"
}# 执行主函数
main "$@"

执行流程:

[root@master ~]# touch install_redis.sh       #创建脚本文件&&脚本插入进去
[root@master ~]# chmod +x install_redis.sh    #给予执行权限
[root@master ~]# ./install_redis.sh           #执行

预计输出

5.修改Master节点配置文件

[root@master ~]# cp /usr/local/redis/redis.conf redis.conf.bak     #备份(好习惯)
[root@master ~]# vi /usr/local/redis/redis.conf
bind 0.0.0.0                 #88行,注释掉bind项,或修改0.0.0.0默认监听所有端口
daemonize yes               #310行,开启守护进程
logfile /var/log/redis/redis.log   #356行,指定日志文件目录
dir /var/lib/redis              #516行,指定工作目录
# requirepass 密码           #1050行,指定redis登录密码,可不设置
#重启redis
[root@master redis]# systemctl restart redis

6.修改slave1和slave2两个从节点

[root@slave1 ~]# cp /usr/local/redis/redis.conf redis.conf.bak
[root@slave1 ~]# vi /usr/local/redis/redis.conf
bind 0.0.0.0                 #88行,注释掉bind项,或修改0.0.0.0默认监听所有端口
daemonize yes               #310行,开启守护进程
logfile /var/log/redis/redis.log   #356行,指定日志文件目录
dir /var/lib/redis              #516行,指定工作目录
replicaof 10.0.20.176 63790     #539行,指定主节点的ip和端口#重启slave1节点和slave2节点redis服务
[root@slave1 ~]# systemctl restart redis
[root@slave2 ~]# systemctl restart redis

7.验证主从效果

[root@master redis]# tail -f /var/log/redis/redis.log
[root@master redis]# redis-cli -p 63790    #登录redis
127.0.0.1:63790> info replication         #查看
127.0.0.1:63790> set k1 1               #在主库创建文件在从库查看
OK
127.0.0.1:63790> get k1                 #存在
"1"
127.0.0.1:63790> 

在master上动态查看日志:

在master上验证从节点

8.哨兵部署

[root@master ~]# cd /usr/local/redis
[root@master redis]# ll

修改哨兵模式的配置文件(所有节点操作)

[root@master ~]# cp /usr/local/redis/sentinel.conf sentinel.conf.bak  #备份protected-mode no             #6行,关闭保护模式
port 26379                    #10行,哨兵默认端口号
daemonize yes                 #15行,开启后台运行
logfile /var/log/redis/sentinel.log   #34行,指定日志目录
dir /var/lib/redis                 #73行,数据文件#92行,改变master节点地址,指定哨兵节点监控10.0.20.176:63790这个主节点
sentinel monitor mymaster 10.0.20.176 63790 2#133行,可以修改时间,判定服务器down掉的时间周期,默认30000毫秒(30秒)
sentinel down-after-milliseconds mymaster 30000#233行,故障切换时间,故障节点的最大超时时间为180000(180秒)
sentinel failover-timeout mymaster 180000

9.启动哨兵模式所有节点都要启动

#注意:先启动主节点,在启从节点

[root@master redis]# /usr/local/redis/src/redis-sentinel sentinel.conf &
[1]13569
[root@slave1 redis]# /usr/local/redis/src/redis-sentinel sentinel.conf &
[1] 13496
[root@slave2 redis]# /usr/local/redis/src/redis-sentinel sentinel.conf &
[1] 13754

10.在master查看哨兵信息

所有节点都可以查看哨兵info sentinel

[root@master redis]# redis-cli -p 26379 info Sentinel

11.验证哨兵,模拟故障

[root@master redis]# ps -ef |grep redis
[root@master redis]# systemctl stop redis
[root@master redis]# tail -f /var/log/redis/sentinel.log

在Slave1上查看是否转换成功

[root@slave1 redis]#  redis-cli -p 26379 INFO Sentinel

在slave2上查看是否转换成功

[root@slave2 redis]#  redis-cli -p 26379 INFO Sentinel

当原来的master修复后会做为slave从新加入

[root@master redis]# redis-cli -p 26379
127.0.0.1:26379> info

将权重值调成默认方便下次选举

总结

哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。

哨兵节点本质上是Redis节点.

每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点.

在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(Config Rewrite)。

故障转移分三步

1.从下线的主服务的所有从服务里面挑选一个从服务, 将其转成主服务

2.已下线主服务的所有从服务改为复制新的主服务 挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master。

3.将已下线的主服务设置成新的主服务的从服务, 当其回复正常时,复制新的主服务,变成新的主服务的从服务 当已下线的服务重新上线时,sentinel会向其发送slaveof命令, 让其成为新主的从。

查看[root@master redis-5.0.9]下的master节点信息
sentinel master imooc-master查看[root@master redis-5.0.9]下的slaves节点信息
sentinel slaves imooc-master

欢迎一起交流

http://www.dtcms.com/a/356574.html

相关文章:

  • GO入门(一)——安装和了解
  • MySQL底层数据结构与算法浅析
  • “设计深圳”亚洲权威消费科技与室内设计盛会
  • CVPR 强化学习模块深度分析:连多项式不等式+自驾规划
  • 在Linux的环境下安装GitLab(保姆级别)
  • 打造高效外贸网站:美国服务器的战略价值
  • 阻塞,非阻塞,同步,异步的理解
  • Windows 下 MSYS2 + MinGW-w64 配置 Fyne GUI 编译环境全流程
  • 【计算机408计算机网络】第三章:自底向上五层模型之数据链路层
  • WINTRUST!_GetMessage函数分析之CRYPT32!CryptSIPGetSignedDataMsg函数的作用是得到nt5inf.cat的信息
  • 【算法】链表专题
  • 钉钉补卡事件处理方案
  • uni-app 跨平台项目的 iOS 上架流程:多工具组合的高效协作方案
  • 常见视频封装格式对比
  • 从零开始学习单片机16
  • 数据结构——线性表(链表,力扣中等篇,增删查改)
  • AI接管浏览器:Anthropic发布Claude for Chrome,是效率革命还是安全噩梦?
  • MySQL-内置函数
  • Python 【深度解析】线程与进程:操作系统中多任务的核心机制
  • WebRTC音频QoS方法五(音频变速算法之Expand算法实现)
  • Nodejs介绍
  • FreeRTOS基础知识记录
  • MTK Linux DRM分析(二十)- KMS drm_mm.c drm_vma_manager.c
  • Docker部署单节点使用KRaft存储数据的Kafka与可视化界面Kafka-Map
  • el-table合并列实例
  • 云市场周报 (2025.08.29):解读阿里云g8y、腾讯云Serverless容器与FinOps趋势
  • 神经语言学与脑科学启发的NLP深层分析:从统计拟合到机制理解的范式转变
  • LeetCode 317 离建筑物最近的距离
  • Spring Boot 整合 MongoDB:CRUD 与聚合查询实战
  • vscode优化合集 - Visual Studio Code