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.选择复制偏移量最大的,也就是复制最完整的从节点。
二、节点规划
节点 | 服务器 | IP | CPU | 内存 | 磁盘 | 版本 |
master | Almalinux | 10.0.20.176 | 8 | 16 | 150 | redis-7.4.2.tar.gz |
slave1 | Almalinux | 10.0.20.177 | 8 | 16 | 150 | redis-7.4.2.tar.gz |
slave2 | Almalinux | 10.0.20.178 | 8 | 16 | 150 | 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
欢迎一起交流