1、总结tomcat优化方法
1. Linux内核参数调优
1.1 打开的文件数量的限制
查看系统允许当前用户进程打开的文件数量的限制:ulimit -n 默认值为1024 。即是Linux操作系统对一个进程打开的文件句柄数量的限制
ulimit参数含义
参数 含义
-H 设置硬资源限制,一旦设置不能增加.
-S 设置软资源限制,设置后可以增加,但不能超过硬资源设置
-a 显示当前所有limit信息
-c 最大的core文件大小,以blocks为单位
-d 进程最大的数据段大小,以blocks为单位
-f 进程可以创造文件的最大值,以kbytes为单位
-l 最大可加锁内存大小,以kbytes为单位
-m 最大内存大小,以kbytes为单位
-n Linux操作系统对一个进程可以打开最大文件描述符的数量.
-p 管道缓冲区大小,以kbytes为单位
-s 线程栈大小,以kbytes为单位
-t 最大CPU占用时间,以秒为单位
-u 用户最大可用的进程数
-v 进程最大可用的虚拟机内存,以kbytes为单位.
对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。
配置文件:/etc/security/limits.conf
echo '* soft nofile 655350' >>/etc/security/limits.conf
echo '* hard nofile 655350' >>/etc/security/limits.conf
echo '* soft nproc 655350' >>/etc/security/limits.conf
echo '* hard nproc 650000' >>/etc/security/limits.conf
hard和soft两个值都代表什么意思呢?
soft是一个警告值,而hard则是一个真正意义的阀值,超过就会报错
配置完成后重新登录参数生效
临时生效方法(重启失效):
ulimit -Hn 65535
ulimit -Sn 65535
如果只是配置tomcat用户打开文件数:
echo 'tomcat soft nofile 655350' >>/etc/security/limits.conf
echo 'tomcat hard nofile 655350' >>/etc/security/limits.conf
echo 'tomcat soft nproc 655350' >>/etc/security/limits.conf
echo 'tomcat hard nproc 650000' >>/etc/security/limits.conf
1.2 Linux网络内核对TCP连接的有关限制
配置文件:/etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_recycle = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf
echo "net.ipv4.ip_local_port_range = 10000 65000" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog = 8192" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_tw_buckets = 10000" >> /etc/sysctl.conf
echo "net.core.somaxconn=8192" >> /etc/sysctl.conf
sysctl -p
即时生效,不用重启或注销登录
2. JVM优化
2.1 内存空间优化
配置文件:/usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g \
-XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts \
-XX:+UseBiasedLocking -XX:+DisableExplicitGC \
-XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:PermSize=128m \
-XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 \
-XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC \
-XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled \
-XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m \
-XX:+UseFastAccessorMethods"
参数 含义
-server 服务器模式
-Xms 堆内存初始化大小
-Xmx 堆内存空间上限
-XX:NewSize= 新生代空间初始化大小
-XX:MaxNewSize= 新生代空间最大值
3. Tomcat 调优
配置文件:/usr/local/tomcat/conf/server.xml
3.1 maxThreads 修改
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
修改为:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="1500" minSpareThreads="50" maxIdleTime="60000"
prestartminSpareThreads = "true" maxQueueSize = "100"/>
3.2 maxConnections acceptCount修改
<Connector
port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
/>
修改为:
<Connector executor ="tomcatThreadPool" port="8009"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="20000" maxConnections="10000" redirectPort="8443"
acceptCount="1500"/>
参数 含义
connectionTimeout 连接超时时长,单位ms
maxThreads 最大线程数,默认200
minSpareThreads 最小空闲线程数
maxSpareThreads 最大空闲线程数
acceptCount 当启动线程满了之后,等待队列的最大长度,默认100
URIEncoding URI 地址编码格式,建议使用 UTF-8
enableLookups 是否启用客户端主机名的DNS反向解析,缺省禁用,建议禁用,就使用客户端IP就行
compression 是否启用传输压缩机制,建议 “on”,CPU和流量的平衡
compressionMinSize 启用压缩传输的数据流最小值,单位是字节
compressableMimeType 定义启用压缩功能的MIME类型text/html, text/xml, text/css,text/javascript
2、java程序出现oom如何解决?什么场景下会出现oom?
oom
Out of memory(OOM)是一种操作系统或者程序已经无法再申请到内存的状态。经常是因为所有可用的内存,包括磁盘交换空间都已经被分配了。当JVM因为没有足够的内存来为对象分配空间、并且垃圾回收器也已经没有空间可回收时,就会抛出 java.lang.Out Of Memory Error 错误
1 Java heap space
当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出 java.lang.Out Of Memory Error:Java heap space 错误(根据实际生产经验,可以对程序日志中的 Out Of Memory Error 配置关键字告警,一经发现,立即处理)。
原因分析
Javaheap space 错误产生的常见原因可以分为以下几类:
(1)请求创建一个超大对象,通常是一个大数组。
(2)超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
(3)过度使用终结器(Finalizer),该对象没有立即被 GC。
(4)内存泄漏(Memory Leak),大量对象引用没有释放,JVM 无法对其自动回收,常见于使用了 File 等资源没有回收。
解决方案
针对大部分情况,通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决,可以参考以下情况做进一步处理:
(1)如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。
(2)如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。
(3)如果是内存泄漏,需要找到持有的对象,修改代码设计,比如关闭没有释放的连接。
2 GC overhead limit exceeded
当 Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次,就会抛出 java.lang.Out Of Memory Error:GC overhead limit exceeded 错误。简单地说,就是应用程序已经基本耗尽了所有可用内存, GC 也无法回收。
此类问题的原因与解决方案跟 Java heap space 非常类似,可以参考上文。
3 Permgen space
该错误表示永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大。
原因分析
永久代存储对象主要包括以下几类:
(1)加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码;
(2)常量池;
(3)对象数组/类型数组所关联的 class;
(4)JIT 编译器优化后的 class 信息。
PermGen 的使用量与加载到内存的 class 的数量/大小正相关。
解决方案
根据 Permgen space 报错的时机,可以采用不同的解决方案,如下所示:
(1)程序启动报错,修改 -XX:MaxPermSize 启动参数,调大永久代空间。
(2)应用重新部署时报错,很可能是没有应用没有重启,导致加载了多份 class 信息,只需重启 JVM 即可解决。
(3)运行时报错,应用程序可能会动态创建大量 class,而这些 class 的生命周期很短暂,但是 JVM 默认不会卸载 class,可以设置 -XX:+CMSClassUnloadingEnabled 和 -XX:+UseConcMarkSweepGC这两个参数允许 JVM 卸载 class。
如果上述方法无法解决,可以通过 jmap 命令 dump 内存对象 jmap-dump:format=b,file=dump.hprof ,然后利用 Eclipse MAT (https://www.eclipse.org/mat) 功能逐一分析开销最大的 classloader 和重复 class。
4 Metaspace
JDK 1.8 使用 Metaspace 替换了永久代(Permanent Generation),该错误表示 Metaspace 已被用满,通常是因为加载的 class 数目太多或体积太大。
此类问题的原因与解决方法跟 Permgen space 非常类似,可以参考上文。需要特别注意的是调整 Metaspace 空间大小的启动参数为 -XX:MaxMetaspaceSize。
5 Unable to create new native thread
每个 Java 线程都需要占用一定的内存空间,当 JVM 向底层操作系统请求创建一个新的 native 线程时,如果没有足够的资源分配就会报此类错误。
原因分析
JVM 向 OS 请求创建 native 线程失败,就会抛出 Unable to create new native thread,常见的原因包括以下几类:
(1)线程数超过操作系统最大线程数 ulimit 限制;
(2)线程数超过 kernel.pid_max(只能重启);
(3)native 内存不足;
该问题发生的常见过程主要包括以下几步:
1、JVM 内部的应用程序请求创建一个新的 Java 线程;
2、JVM native 方法代理了该次请求,并向操作系统请求创建一个 native 线程;
3、操作系统尝试创建一个新的 native 线程,并为其分配内存;
4、如果操作系统的虚拟内存已耗尽,或是受到 32 位进程的地址空间限制,操作系统就会拒绝本次 native 内存分配;
5、JVM 将抛出 java.lang.Out Of Memory Error:Unable to create new native thread 错误。
解决方案
(1)升级配置,为机器提供更多的内存;
(2)降低 Java Heap Space 大小;
(3)修复应用程序的线程泄漏问题;
(4)限制线程池大小;
(5)使用 -Xss 参数减少线程栈的大小;
(6)调高 OS 层面的线程最大数:执行 ulimia-a 查看最大线程数限制,使用 ulimit-u xxx 调整最大线程数限制。
ulimit -a … 省略部分内容 … max user processes (-u) 16384
6 Out of swap space
该错误表示所有可用的虚拟内存已被耗尽。虚拟内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)两部分组成。当运行时程序请求的虚拟内存溢出时就会报 Outof swap space? 错误。
原因分析
该错误出现的常见原因包括以下几类:
(1)地址空间不足;
(2)物理内存已耗光;
(3)应用程序的本地内存泄漏(native leak),例如不断申请本地内存,却不释放。
(4)执行 jmap-histo:live 命令,强制执行 Full GC;如果几次执行后内存明显下降,则基本确认为 Direct Byte Buffer 问题。
解决方案
根据错误原因可以采取如下解决方案:
(1)升级地址空间为 64 bit;
(2)使用 Arthas 检查是否为 Inflater/Deflater 解压缩问题,如果是,则显式调用 end 方法。
(3)Direct Byte Buffer 问题可以通过启动参数 -XX:MaxDirectMemorySize 调低阈值。
(4)升级服务器配置/隔离部署,避免争用。
7 Kill process or sacrifice child
有一种内核作业(Kernel Job)名为 Out of Memory Killer,它会在可用内存极低的情况下“杀死”(kill)某些进程。OOM Killer 会对所有进程进行打分,然后将评分较低的进程“杀死”,具体的评分规则可以参考 Surviving the Linux OOM Killer。
不同于其他的 OOM 错误, Kill process or sacrifice child 错误不是由 JVM 层面触发的,而是由操作系统层面触发的。
原因分析
默认情况下,Linux 内核允许进程申请的内存总量大于系统可用内存,通过这种“错峰复用”的方式可以更有效的利用系统资源。
然而,这种方式也会无可避免地带来一定的“超卖”风险。例如某些进程持续占用系统内存,然后导致其他进程没有可用内存。此时,系统将自动激活 OOM Killer,寻找评分低的进程,并将其“杀死”,释放内存资源。
解决方案
(1)升级服务器配置/隔离部署,避免争用。
(2)OOM Killer 调优。
8 Requested array size exceeds VM limit
JVM 限制了数组的最大长度,该错误表示程序请求创建的数组超过最大长度限制。
JVM 在为数组分配内存前,会检查要分配的数据结构在系统中是否可寻址,通常为 Integer.MAX_VALUE-2。
此类问题比较罕见,通常需要检查代码,确认业务是否需要创建如此大的数组,是否可以拆分为多个块,分批执行。
9 Direct buffer memory
Java 允许应用程序通过 Direct Byte Buffer 直接访问堆外内存,许多高性能程序通过 Direct Byte Buffer 结合内存映射文件(Memory Mapped File)实现高速 IO。
原因分析
Direct Byte Buffer 的默认大小为 64 MB,一旦使用超出限制,就会抛出 Direct buffer memory 错误。
解决方案
(1)Java 只能通过 Byte Buffer.allocateDirect 方法使用 Direct Byte Buffer,因此,可以通过 Arthas 等在线诊断工具拦截该方法进行排查。
(2)检查是否直接或间接使用了 NIO,如 netty,jetty 等。
(3)通过启动参数 -XX:MaxDirectMemorySize 调整 Direct Byte Buffer 的上限值。
(4)检查 JVM 参数是否有 -XX:+DisableExplicitGC 选项,如果有就去掉,因为该参数会使 System.gc() 失效。
(5)检查堆外内存使用代码,确认是否存在内存泄漏;或者通过反射调用 sun.misc.Cleaner 的 clean() 方法来主动释放被 Direct ByteBuffer 持有的内存空间。
(6)内存容量确实不足,升级配置。
3、简述redis特点及其应用场景
1 Redis 简介
Redis (Remote Dictionary Server) ,远程字典服务,Redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库。redis 提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcached,但相比memcached,redis还提供了易扩展、高性能、具备数据持久性等功能。 Redis 在高并发、低延迟环境要求比较高的环境使用量非常广泛。
2 Redis 特性
速度快:10W QPS,基于内存,C语言实现
单线程
持久化
支持多种数据结构
支持多种编程语言
功能丰富:支持Lua脚本,发布订阅,事务,pipeline等功能
简单:代码短小精悍(单机核心代码只有23000行左右),单线程开发容易,不依赖外部库,使用简单
主从复制
支持高可用和分布式
2.1 单线程
Redis 6.0版本前一直是单线程方式处理用户的请求
单线程为何如此快?
纯内存
非阻塞
避免线程切换和竞态消耗
注意事项:
一次只运行一条命令
拒绝长(慢)命令:keys,flushall,flushdb,slow lua script,mutil/exec,operate big value(collection)
其实不是单线程:早期版本是单进程单线程,3版本后实际还有其它的线程,实现特定功能,如:fysnc file descriptor,close file descriptor
3 redis 对比 memcached
支持数据的持久化:可以将内存中的数据保持在磁盘中,重启redis服务或者服务器之后可以从备份文件中恢复数据到内存继续使用
支持更多的数据类型:支持string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zset(有序集
合)
支持数据的备份:可以实现类似于数据的master-slave模式的数据备份,另外也支持使用快照+AOF
支持更大的value数据:memcache单个key value最大只支持1MB,而redis最大支持512MB(生产不建议超过2M,性能受影响)
在Redis6版本前,Redis 是单线程,而memcached是多线程,所以单机情况下没有memcached 并发高,性能更好,但redis 支持分布式集群以实现更高的并发,单Redis实例可以实现数万并发
支持集群横向扩展:基于redis cluster的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性
都是基于 C 语言开发
4 redis 典型应用场景
Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
缓存:数据查询、电商网站商品信息、新闻内容
计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
微博/微信社交场合:共同好友,粉丝数,关注,点赞,评论等
消息队列:ELK的日志缓存、部分业务的订阅发布系统
地理位置:基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能
4、对比redis的RDB、AOF模式的优缺点
Redis 提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,简而言之,就是在不同的时间点,将Redis 存储的数据生成快照并存储到磁盘等介质上。
AOF,则是换了一个角度来实现持久化,那就是将Redis 执行过的所有写指令记录下来,在下次Redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
RDB 和AOF 两种方式也可以同时使用,在这种情况下,如果Redis 重启的话,则会优先采用AOF 方式来进行数据恢复,这是因为AOF 方式的数据恢复完整度更高。
RDB
RDB持久化方式,是将Redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。
RDB持久化方式:Redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。
对于RDB 方式,Redis 会单独创建一个子进程来进行持久化,而主进程是不会进行任何IO 操作的,这样就确保了Redis 极高的性能。
RDB优点:如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB 方式要比AOF 方式更加的高效。
RDB缺点:如果你对数据的完整性非常敏感,那么RDB 方式就不太适合你,因为即使你每5 分钟都持久化一次,当Redis 故障时,仍然会有近5 分钟的数据丢失。所以,Redis 还提供了另一种持久化方式,那就是AOF。
AOF
AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍。
实现方式:我们通过配置Redis.conf 中的appendonly yes 就可以打开AOF功能。如果有写操作(如SET 等),Redis 就会被追加到AOF 文件的末尾。
AOF 持久化的方式:默认的AOF 持久化策略是每秒钟fsync 一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,Redis 仍然可以保持很好的处理性能,即使Redis 故障,也只会丢失最近1 秒钟的数据。
如果在追加日志时,恰好遇到磁盘空间满或断电等情况导致日志写入不完整,也没有关系,Redis 提供了Redis-check-aof 工具,可以用来进行日志修复。
因为采用了追加方式,如果不做任何处理的话,AOF 文件会变得越来越大,为此,Redis 提供了AOF 文件重写(rewrite)机制,即当AOF 文件的大小超过所设定的阈值时,Redis 就会启动AOF 文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100 次INCR 指令,在AOF 文件中就要存储100 条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET 指令,这就是重写机制的原理。
AOF 优点:我们通过一个场景再现来说明。某同学在操作Redis 时,不小心执行了FLUSHALL,导致Redis 内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要Redis 配置了AOF 持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停Redis 并编辑AOF文件,将最后一行的FLUSHALL 命令删除,然后重启Redis,就可以恢复Redis的所有数据到FLUSHALL 之前的状态了。是不是很神奇,这就是AOF 持久化方式的好处之一。但是如果AOF 文件已经被重写了,那就无法通过这种方法来恢复数据了。
AOF缺点:比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF 方式的恢复速度也要慢于RDB 方式。
如果你直接执行BGREWRITEAOF 命令,那么Redis 会生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最少的命令集。
如果运气比较差,AOF 文件出现了被写坏的情况,也不必过分担忧,Redis并不会贸然加载这个有问题的AOF 文件,而是报错退出。这时可以通过以下步骤来修复出错的文件:
1.备份被写坏的AOF 文件。
2.运行Redis-check-aof –fix 进行修复。
3.用diff -u 来看下两个文件的差异,确认问题点。
4.重启Redis,加载修复后的AOF 文件。
5、实现redis哨兵,模拟master故障场景
1 redis 哨兵(Sentinel)
1.1 redis 集群介绍
主从架构无法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题导致master无法使用,而redis主从复制无法实现自动的故障转移(将slave 自动提升为新master),需要手动修改环境配置,才能切换到slave redis服务器,另外当单台Redis服务器性能无法满足业务写入需求的时候,也无法横向扩展Redis服务的并行写入性能
需要解决以上的两个核心问题:
master和slave角色的无缝切换,让业务无感知从而不影响业务使用
可横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。
Redis 集群实现方式:
客户端分片:由应用决定将不同的KEY发送到不同的Redis服务器
代理分片:由代理决定将不同的KEY发送到不同的Redis服务器,代理程序如:codis,twemproxy等
Redis Cluster:着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
1.2 哨兵 (Sentinel) 工作原理
Redis Sentinal:着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Sentinel 故障转移 :
(1)多个sentinel发现并确认master有问题
(2)选举出一个sentinel作为领导
(3)选出一个slave作为master
(4)通知其余slave成为新master的slave
(5)通知客户端主从变化
(6)等待老的master复活成为新master的slave
Sentinel 进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,此功能在redis2.6+的版本已引用,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本
哨兵(Sentinel) 是一个分布式系统,可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossip protocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master
每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(此项可配置)内未得到回应,则暂时认为对方已离线,也就是所谓的”主观认为宕机” (主观:是每个成员都具有的独自的而且可能相同也可能不同的意识),英文名称:Subjective Down,简称SDOWN
有主观宕机,对应的有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出SDOWN的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”(客观:是不依赖于某种意识而已经实际存在的一切事物),英文名称是:Objectively Down, 简称 ODOWN
通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)
Sentinel 机制可以解决master和slave角色的自动切换问题,但单个 Master 的性能瓶颈问题无法解决,类似于MySQL中的MHA功能
Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,但Sentinel只是配置中心不是代理。
Redis Sentinel 节点与普通redis 没有区别,要实现读写分离依赖于客户端程序
redis 3.0 之前版本中,生产环境一般使用哨兵模式,3.0后推出redis cluster功能,可以支持更大规模的生产环境
sentinel中的三个定时任务:
每10秒每个sentinel对master和slave执行info
发现slave节点
确认主从关系
每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
通过sentinel__:hello频道交互
交互对节点的“看法”和自身信息
每1秒每个sentinel对其他sentinel和redis执行ping
2 实现redis哨兵
准备三台机器:
节点 IPRedis 版本
master Sentinel10.0.0.7 Redis-6.2.4
slave1 Sentinel10.0.0.17 Redis-6.2.4
slave2 Sentinel10.0.0.27 Redis-6.2.4
2.1 哨兵的准备实现主从复制架构
哨兵的前提是已经实现了一个redis的主从复制的运行环境,从而实现一个一主两从基于哨兵的高可用redis架构
注意:master 的配置文件中masterauth 和slave 都必须相同
所有主从节点的redis.conf中关健配置
#在所有主从节点执行
[root@master ~]#vim /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456
#在所有从节点执行
[root@slave1 ~]#vim /apps/redis/etc/redis.conf
replicaof 10.0.0.7 6379
#在所有主从节点执行
[root@master ~]#systemctl restart redis.service
查看master服务器状态
[root@master ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.17,port=6379,state=online,offset=182,lag=0
slave1:ip=10.0.0.27,port=6379,state=online,offset=182,lag=1
master_failover_state:no-failover
master_replid:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182
查看slave1状态
[root@slave1 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.7
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:308
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:308
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:308
查看slave2状态
[root@slave2 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.7
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:406
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:406
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:406
2.2 编辑哨兵的配置文件
Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持。默认监听在26379/tcp端口
哨兵可以不和Redis服务器部署在一起,但一般部署在一起以节约成本
所有redis节点使用相同的以下示例的配置文件
#如果是编译安装,在源码目录有sentinel.conf,复制到安装目录即可,如:/apps/redis/etc/sentinel.conf
[root@master ~]#cd redis-6.2.4/
[root@master redis-6.2.4]#ls
00-RELEASENOTES CONTRIBUTING INSTALL README.md runtest-cluster sentinel.conf TLS.md
BUGS COPYING Makefile redis.conf runtest-moduleapi src utils
CONDUCT deps MANIFESTO runtest runtest-sentinel tests
[root@master redis-6.2.4]#cp sentinel.conf /apps/redis/etc/
[root@master redis-6.2.4]#vim /apps/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile /apps/redis/run/redis-sentinel.pid
logfile /apps/redis/log/sentinel_26379.log
dir /tmp
sentinel monitor mymaster 10.0.0.7 6379 2
#mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口
#2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有
sentinel节点(一般总数是>=3的奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,
取整为2,是master的ODOWN客观下线的依据
sentinel auth-pass mymaster 123456
#mymaster集群中master的密码,注意此行要在上面行的下面
sentinel down-after-milliseconds mymaster 3000
#(SDOWN)判断mymaster集群中所有节点的主观下线的时间,单位:毫秒,建议3000
sentinel parallel-syncs mymaster 1
#发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力
sentinel failover-timeout mymaster 180000
#所有slaves指向新的master所需的超时时间,单位:毫秒
sentinel deny-scripts-reconfig yes #禁止修改脚本
[root@master redis-6.2.4]#scp /apps/redis/etc/sentinel.conf 10.0.0.17:/apps/redis/etc/
[root@master redis-6.2.4]#scp /apps/redis/etc/sentinel.conf 10.0.0.27:/apps/redis/etc/
三个哨兵服务器的配置都如下
[root@master redis-6.2.4]#grep -vE "^#|^$" /apps/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile /apps/redis/run/redis-sentinel.pid
logfile /apps/redis/log/sentinel_26379.log
dir /tmp
sentinel monitor mymaster 10.0.0.7 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 3000
acllog-max-len 128
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
SENTINEL resolve-hostnames no
SENTINEL announce-hostnames no
2.3 启动哨兵
三台哨兵服务器都要启动
#如果是编译安装在所有节点生成新的service文件
[root@master redis-6.2.4]#vim /lib/systemd/system/redis-sentinel.service
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
[root@master redis-6.2.4]#scp /lib/systemd/system/redis-sentinel.service 10.0.0.17:/lib/systemd/system/redis-sentinel.service
[root@master redis-6.2.4]#scp /lib/systemd/system/redis-sentinel.service 10.0.0.27:/lib/systemd/system/redis-sentinel.service
#注意所有节点的目录权限,否则无法启动服务
[root@master redis-6.2.4]#chown -R redis.redis /apps/redis/
[root@master redis-6.2.4]#ll /apps/redis/etc/sentinel.conf
-rw-r--r-- 1 redis redis 14292 May 5 13:03 /apps/redis/etc/sentinel.conf
[root@slave1 ~]#chown -R redis.redis /apps/redis/
[root@slave1 ~]#ll /apps/redis/etc/sentinel.conf
-rw-r--r-- 1 redis redis 14291 May 5 13:03 /apps/redis/etc/sentinel.conf
[root@slave2 ~]#chown -R redis.redis /apps/redis/
[root@slave2 ~]#ll /apps/redis/etc/sentinel.conf
-rw-r--r-- 1 redis redis 14291 May 5 13:03 /apps/redis/etc/sentinel.conf
#重新加载配置文件
[root@master redis-6.2.4]#systemctl daemon-reload
[root@slave1 ~]#systemctl daemon-reload
[root@slave2 ~]#systemctl daemon-reload
#如果是编译安装,在所有哨兵服务器执行下面操作启动哨兵
[root@master redis-6.2.4]#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf
2.4 验证三台哨兵服务器端口
[root@master redis-6.2.4]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:26379 *:*
LISTEN 0 511 *:6379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 511 [::1]:6379 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
[root@slave1 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:26379 *:*
LISTEN 0 511 *:6379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 511 [::1]:6379 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
[root@slave2 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 511 *:26379 *:*
LISTEN 0 511 *:6379 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
LISTEN 0 511 [::1]:6379 [::]:*
2.5 查看哨兵日志
master的哨兵日志
[root@master ~]#tail -f /apps/redis/log/sentinel_26379.log
2759:X 05 May 2022 11:23:51.222 * Removing the pid file.
2759:X 05 May 2022 11:23:51.223 # Sentinel is now ready to exit, bye bye...
2811:X 05 May 2022 11:35:03.800 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2811:X 05 May 2022 11:35:03.800 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=2811, just started
2811:X 05 May 2022 11:35:03.800 # Configuration loaded
2811:X 05 May 2022 11:35:03.810 * Increased maximum number of open files to 10032 (it was originally set to 1024).
2811:X 05 May 2022 11:35:03.810 * monotonic clock: POSIX clock_gettime
2811:X 05 May 2022 11:35:03.815 * Running mode=sentinel, port=26379.
2811:X 05 May 2022 11:35:03.817 # Sentinel ID is e432c1d2045d68f260da2f755fb706ed889ee3d9
2811:X 05 May 2022 11:35:03.817 # +monitor master mymaster 10.0.0.7 6379 quorum 2
slave的哨兵日志
[root@slave1 ~]#tail -f /apps/redis/log/sentinel_26379.log
2712:X 05 May 2022 11:35:00.115 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2712:X 05 May 2022 11:35:00.116 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=2712, just started
2712:X 05 May 2022 11:35:00.116 # Configuration loaded
2712:X 05 May 2022 11:35:00.121 * Increased maximum number of open files to 10032 (it was originally set to 1024).
2712:X 05 May 2022 11:35:00.122 * monotonic clock: POSIX clock_gettime
2712:X 05 May 2022 11:35:00.123 * Running mode=sentinel, port=26379.
2712:X 05 May 2022 11:35:00.124 # Sentinel ID is 19e17c40424e15f994f98592c9d2957171603a10
2712:X 05 May 2022 11:35:00.124 # +monitor master mymaster 10.0.0.7 6379 quorum 2
2712:X 05 May 2022 11:35:03.153 # +sdown sentinel e432c1d2045d68f260da2f755fb706ed889ee3d9 10.0.0.7 26379 @ mymaster 10.0.0.7 6379
2712:X 05 May 2022 11:35:04.369 # -sdown sentinel e432c1d2045d68f260da2f755fb706ed889ee3d9 10.0.0.7 26379 @ mymaster 10.0.0.7 6379
[root@slave2 ~]#tail -f /apps/redis/log/sentinel_26379.log
2752:X 05 May 2022 11:34:50.876 # Configuration loaded
2752:X 05 May 2022 11:34:50.878 * Increased maximum number of open files to 10032 (it was originally set to 1024).
2752:X 05 May 2022 11:34:50.880 * monotonic clock: POSIX clock_gettime
2752:X 05 May 2022 11:34:50.889 * Running mode=sentinel, port=26379.
2752:X 05 May 2022 11:34:50.890 # Sentinel ID is 6e3c75087dcb5e35aceee95db2854f4e1cb18bee
2752:X 05 May 2022 11:34:50.890 # +monitor master mymaster 10.0.0.7 6379 quorum 2
2752:X 05 May 2022 11:34:53.925 # +sdown sentinel 19e17c40424e15f994f98592c9d2957171603a10 10.0.0.17 26379 @ mymaster10.0.0.7 6379
2752:X 05 May 2022 11:34:53.926 # +sdown sentinel e432c1d2045d68f260da2f755fb706ed889ee3d9 10.0.0.7 26379 @ mymaster 10.0.0.7 6379
2752:X 05 May 2022 11:35:00.252 # -sdown sentinel 19e17c40424e15f994f98592c9d2957171603a10 10.0.0.17 26379 @ mymaster10.0.0.7 6379
2752:X 05 May 2022 11:35:04.557 # -sdown sentinel e432c1d2045d68f260da2f755fb706ed889ee3d9 10.0.0.7 26379 @ mymaster 10.0.0.7 6379
2.6 查看sentinel状态
在sentinel状态中尤其是最后一行,涉及到master IP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量
[root@master ~]#redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.7:6379,slaves=2,sentinels=3
#两个slave,三个sentinel服务器,如果sentinels值不符合,检查myid可能冲突
2.7 测试数据同步
[root@master ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> set date 20220505
OK
[root@slave1 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> get date
"20220505"
[root@slave2 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> get date
"20220505"
2.8 停止Redis Master 节点测试故障转移
[root@master ~]#systemctl stop redis.service
查看各节点上哨兵信息:
[root@master ~]#redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.27:6379,slaves=2,sentinels=3
#10.0.0.27 slave2自动切换为master
故障转移时sentinel的信息:
[root@slave1 ~]#tail -f /apps/redis/log/sentinel_26379.log
2712:X 05 May 2022 13:03:56.875 # +failover-state-reconf-slaves master mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:56.940 * +slave-reconf-sent slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:57.152 * +slave-reconf-inprog slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:57.331 # -odown master mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:58.228 * +slave-reconf-done slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:58.461 # +failover-end master mymaster 10.0.0.7 6379
2712:X 05 May 2022 13:03:58.461 # +switch-master mymaster 10.0.0.7 6379 10.0.0.27 6379
2712:X 05 May 2022 13:03:58.462 * +slave slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.27 6379
2712:X 05 May 2022 13:03:58.462 * +slave slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2712:X 05 May 2022 13:04:01.469 # +sdown slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
[root@master ~]#tail -f /apps/redis/log/sentinel_26379.log
2811:X 05 May 2022 11:35:03.817 # Sentinel ID is e432c1d2045d68f260da2f755fb706ed889ee3d9
2811:X 05 May 2022 11:35:03.817 # +monitor master mymaster 10.0.0.7 6379 quorum 2
2811:X 05 May 2022 13:03:55.957 # +sdown master mymaster 10.0.0.7 6379
2811:X 05 May 2022 13:03:56.184 # +new-epoch 1
2811:X 05 May 2022 13:03:56.245 # +vote-for-leader 19e17c40424e15f994f98592c9d2957171603a10 1
2811:X 05 May 2022 13:03:56.944 # +config-update-from sentinel 19e17c40424e15f994f98592c9d2957171603a10 10.0.0.17 26379 @ mymaster 10.0.0.7 6379
2811:X 05 May 2022 13:03:56.945 # +switch-master mymaster 10.0.0.7 6379 10.0.0.27 6379
2811:X 05 May 2022 13:03:56.945 * +slave slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.27 6379
2811:X 05 May 2022 13:03:56.983 * +slave slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2811:X 05 May 2022 13:04:00.055 # +sdown slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
[root@slave2 ~]#tail -f /apps/redis/log/sentinel_26379.log
2752:X 05 May 2022 13:03:56.083 # +new-epoch 1
2752:X 05 May 2022 13:03:56.084 # +try-failover master mymaster 10.0.0.7 6379
2752:X 05 May 2022 13:03:56.132 # +vote-for-leader 6e3c75087dcb5e35aceee95db2854f4e1cb18bee 1
2752:X 05 May 2022 13:03:56.153 # 19e17c40424e15f994f98592c9d2957171603a10 voted for 19e17c40424e15f994f98592c9d2957171603a10 1
2752:X 05 May 2022 13:03:56.244 # e432c1d2045d68f260da2f755fb706ed889ee3d9 voted for 19e17c40424e15f994f98592c9d2957171603a10 1
2752:X 05 May 2022 13:03:56.938 # +config-update-from sentinel 19e17c40424e15f994f98592c9d2957171603a10 10.0.0.17 26379 @ mymaster 10.0.0.7 6379
2752:X 05 May 2022 13:03:56.939 # +switch-master mymaster 10.0.0.7 6379 10.0.0.27 6379
2752:X 05 May 2022 13:03:56.940 * +slave slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 13:03:56.940 * +slave slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 13:03:59.963 # +sdown slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2.9 故障转移后的redis配置文件会被自动修改
故障转移后redis.conf中的replicaof行的master IP会被修改
[root@slave1 ~]#grep ^replicaof /apps/redis/etc/redis.conf
replicaof 10.0.0.27 6379
哨兵配置文件的sentinel monitor IP 同样也会被修改
[root@slave1 ~]#grep "monitor mymaster" /apps/redis/etc/sentinel.conf
sentinel monitor mymaster 10.0.0.27 6379 2 #自动修改此行
[root@slave2 ~]#grep "monitor mymaster" /apps/redis/etc/sentinel.conf
sentinel monitor mymaster 10.0.0.27 6379 2
[root@master ~]#grep "monitor mymaster" /apps/redis/etc/sentinel.conf
sentinel monitor mymaster 10.0.0.27 6379 2
2.10 查看当前 redis状态
新的master 状态
[root@slave2 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:master #提升为master
connected_slaves:1
slave0:ip=10.0.0.17,port=6379,state=online,offset=1867449,lag=0
master_failover_state:no-failover
master_replid:58f2e7e6203f5dea3021a3ad6b627849cd1a80c6
master_replid2:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_repl_offset:1867449
second_repl_offset:1112913
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:818874
repl_backlog_histlen:1048576
[root@slave1 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.27 #指向新的master
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1826043
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:58f2e7e6203f5dea3021a3ad6b627849cd1a80c6
master_replid2:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_repl_offset:1826043
second_repl_offset:1112913
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:777468
repl_backlog_histlen:1048576
2.11 测试数据同步
[root@slave2 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> set fruit orange
OK
[root@slave1 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> get fruit
"orange"
2.12 恢复故障的原master重新加入redis集群
[root@master ~]#systemctl start redis.service
[root@master ~]#grep ^replicaof /apps/redis/etc/redis.conf
replicaof 10.0.0.27 6379
在原 master上观察状态
[root@master ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.27
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:2398880
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:58f2e7e6203f5dea3021a3ad6b627849cd1a80c6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2398880
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2325269
repl_backlog_histlen:73612
127.0.0.1:6379> get fruit
"orange"
[root@master ~]#redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.27:6379,slaves=2,sentinels=3
观察新master上状态和日志
[root@slave2 ~]#redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.17,port=6379,state=online,offset=3034646,lag=0
slave1:ip=10.0.0.7,port=6379,state=online,offset=3034646,lag=1
master_failover_state:no-failover
master_replid:58f2e7e6203f5dea3021a3ad6b627849cd1a80c6
master_replid2:1067b30c7ff6a77e0b2655096cb057d0ffea30e1
master_repl_offset:3034646
second_repl_offset:1112913
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1986071
repl_backlog_histlen:1048576
[root@slave2 ~]#tail -f /apps/redis/log/sentinel_26379.log
2752:X 05 May 2022 13:03:56.939 # +switch-master mymaster 10.0.0.7 6379 10.0.0.27 6379
2752:X 05 May 2022 13:03:56.940 * +slave slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 13:03:56.940 * +slave slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 13:03:59.963 # +sdown slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 14:46:15.590 # -sdown slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379
2752:X 05 May 2022 14:46:25.578 * +convert-to-slave slave 10.0.0.7:6379 10.0.0.7 6379 @ mymaster 10.0.0.27 6379