Redis Sentinel哨兵模式部署 主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel模式应运而生。sentinel中文含义为哨兵,顾名思义,它的作用就是监控redis集群的运行状况,此模式具有如下一些特点:
sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义;
当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master;
当master重新启动后,它将不再是master,而是做为slave接收新的master的同步数据;
sentinel因为也是一个进程,所以有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群;
多sentinel配置的时候,sentinel之间也会自动监控;
当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中;
一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis;
sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也可能会挂掉。
其工作的流程如下所示:
每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令;
如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线;
如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态;
当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线;
在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令; - 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次;
若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除。
环境
IP
角色
192.168.1.21
master, sentinel
192.168.1.22
slave1, sentinel
192.168.1.23
slave2, sentinel
安装编译环境 1 2 3 4 # ubuntu apt install make gcc # centos yum install make gcc
安装 Redis 1 2 3 4 5 6 7 8 9 10 11 12 # 查看 Redis 版本 http://download.redis.io/releases/ # 下载 Redis wget http://download.redis.io/releases/redis-7.2.5.tar.gz # 解压 tar xvf redis-7.2.5.tar.gz cd redis-7.2.5/ # 进行编译 make && make install
配置服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # Redis 服务 cat << EOF > /usr/lib/systemd/system/redis.service [Unit] Description=Redis persistent key-value database After=network.target After=network-online.target Wants=network-online.target [Service] ExecStart=/usr/local/bin/redis-server /usr/local/redis/redis.conf --supervised systemd ExecStop=/usr/local/redis/redis-shutdown Type=forking User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 LimitNOFILE=65536 PrivateTmp=true [Install] WantedBy=multi-user.target EOF
配置停止脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 mkdir /usr/local/redis vim /usr/local/redis/redis-shutdown # !/bin/bash # test x"$REDIS_DEBUG" != x && set -x REDIS_CLI=/usr/local/bin/redis-cli # Retrieve service name SERVICE_NAME="$1" if [ -z "$SERVICE_NAME" ]; then SERVICE_NAME=redis fi # Get the proper config file based on service name CONFIG_FILE="/usr/local/redis/$SERVICE_NAME.conf" # Use awk to retrieve host, port from config file HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1` PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1` PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1` SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1` # Just in case , use default host, port HOST=${HOST:-127.0.0.1} if [ "$SERVICE_NAME" = redis ]; then PORT=${PORT:-6379} else PORT=${PORT:-26739} fi # Setup additional parameters # e.g password-protected redis instances [ -z "$PASS" ] || ADDITIONAL_PARAMS="-a $PASS" # shutdown the service properly if [ -e "$SOCK" ] ; then $REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown else $REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown fi
授权启动服务 1 2 3 4 5 6 chmod +x /usr/local/redis/redis-shutdown useradd -s /sbin/nologin redis cp /root/redis-7.2.5/redis.conf /usr/local/redis/ && chown -R redis:redis /usr/local/redis mkdir -p /usr/local/redis/data && chown -R redis:redis /usr/local/redis/data mkdir -p /usr/local/redis/sentinel && chown -R redis:redis /usr/local/redis/sentinel
修改配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 vim /usr/local/redis/redis.conf # master节点配置 bind 0.0.0.0 -::1 # 监听ip,多个ip用空格分隔 daemonize yes # 允许后台启动 logfile "/usr/local/redis/redis.log" # 日志路径 dir /usr/local/redis/data # 数据库备份文件存放目录 masterauth 123123 # slave连接master密码,master可省略 requirepass 123123 # 设置master连接密码,slave可省略 appendonly yes # 在/usr/local/redis/data目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中 vim /usr/local/redis/redis.conf # slave1节点配置 bind 0.0.0.0 -::1 # 监听ip,多个ip用空格分隔 daemonize yes # 允许后台启动 logfile "/usr/local/redis/redis.log" # 日志路径 dir /usr/local/redis/data # 数据库备份文件存放目录 replicaof 192.168.1.21 6379 # replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点。就是设置master节点 masterauth 123123 # slave连接master密码,master可省略 requirepass 123123 # 设置master连接密码,slave可省略 appendonly yes # 在/usr/local/redis/data目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中 vim /usr/local/redis/redis.conf # slave2节点配置 bind 0.0.0.0 -::1 # 监听ip,多个ip用空格分隔 daemonize yes # 允许后台启动 logfile "/usr/local/redis/redis.log" # 日志路径 dir /usr/local/redis/data # 数据库备份文件存放目录 replicaof 192.168.1.21 6379 # replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点。就是设置master节点 masterauth 123123 # slave连接master密码,master可省略 requirepass 123123 # 设置master连接密码,slave可省略 appendonly yes # 在/usr/local/redis/data目录生成appendonly.aof文件,将每 # 三个节点都执行 cat >/usr/local/redis/sentinel.conf<<EOF port 26379 daemonize yes logfile "/usr/local/redis/sentinel.log" # sentinel工作目录 dir "/usr/local/redis/sentinel" # 判断master失效至少需要2个sentinel同意,建议设置为n/2+1,n为sentinel个数 # sentinel monitor <master-name> <ip> <port> <count> sentinel monitor mymaster 192.168.1.21 6379 2 sentinel auth-pass mymaster 123123 # 判断master主观下线时间,默认30s sentinel down-after-milliseconds mymaster 30000 EOF
修改linux内核参数 1 2 3 4 5 6 7 8 # 临时生效 sysctl -w vm.overcommit_memory=1 # 永久生效 echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf && sysctl -p # # 0,:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 # 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。 # 2: 表示内核允许分配超过所有物理内存和交换空间总和的内存。
启动 Redis 1 2 3 4 5 6 7 8 9 10 11 12 systemctl daemon-reload systemctl enable redis systemctl stop redis systemctl start redis systemctl status redis # 启动sentinel /usr/local/bin/redis-sentinel /usr/local/redis/sentinel.conf root@cby:~# netstat -anpt|grep 26379 tcp 0 0 0.0.0.0:26379 0.0.0.0:* LISTEN 9156/redis-sentinel tcp6 0 0 :::26379 :::* LISTEN 9156/redis-sentinel root@cby:~#
查看集群 1 2 3 4 5 6 7 8 9 10 redis-cli -h 192.168.1.21 -p 26379 -a 123123 192.168.1.21:26379> info sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_tilt_since_seconds:-1 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=192.168.1.21:6379,slaves=2,sentinels=3 192.168.1.21:26379>
故障模拟 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 # 停掉master systemctl stop redis # 查看信息 redis-cli -h 192.168.1.22 -a 123123 info replication role:slave master_host:192.168.1.21 master_port:6379 master_link_status:down # 这里 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_read_repl_offset:4567834 slave_repl_offset:4567834 master_link_down_since_seconds:0 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:449440daec10a3eb742b13e690de4adb26b20a07 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4567834 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:3515695 repl_backlog_histlen:1052140 # 再次查看信息 已经恢复 redis-cli -h 192.168.1.22 -a 123123 info replication role:master connected_slaves:1 # 这里 slave0:ip=192.168.1.23,port=6379,state=online,offset=4574293,lag=1 master_failover_state:no-failover master_replid:70e80f38d396bd5e649b30bd2669b3ae024f7e25 master_replid2:449440daec10a3eb742b13e690de4adb26b20a07 master_repl_offset:4574571 second_repl_offset:4567835 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:3515695 repl_backlog_histlen:1058877 # 测试一下读写 redis-cli -h 192.168.1.22 -a 123123 192.168.1.22:6379> set k2 v2 OK 192.168.1.22:6379> 192.168.1.22:6379> get k2 "v2" 192.168.1.22:6379> # 恢复故障 systemctl start redis redis-cli -h 192.168.1.22 -a 123123 info replication role:master connected_slaves:2 # 这里 slave0:ip=192.168.1.23,port=6379,state=online,offset=4620778,lag=1 slave1:ip=192.168.1.21,port=6379,state=online,offset=4620940,lag=0 master_failover_state:no-failover master_replid:70e80f38d396bd5e649b30bd2669b3ae024f7e25 master_replid2:449440daec10a3eb742b13e690de4adb26b20a07 master_repl_offset:4620940 second_repl_offset:4567835 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:3556575 repl_backlog_histlen:1064366 # 测试一下读写 redis-cli -h 192.168.1.22 -a 123123 192.168.1.22:6379> set k3 v3 OK 192.168.1.22:6379> get k3 "v3" 192.168.1.22:6379>
关于
https://www.oiox.cn/
https://www.oiox.cn/index.php/start-page.html
CSDN、GitHub、51CTO、知乎、开源中国、思否、博客园、掘金、简书、华为云、阿里云、腾讯云、哔哩哔哩、今日头条、新浪微博、个人博客
全网可搜《小陈运维》
文章主要发布于微信公众号