1、总结tomcat优化方法
在目前流行的互联网架构中,Tomcat在目前的网络编程中是举足轻重的,由于Tomcat的运行依赖于JVM,从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分
1.1 JVM调优
1.1.1调优指标:
- 吞吐量:运行用户代码的时间占用总运行时间的比例(总运行时间=程序的运行时间+内存回收的时间);
- 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间;
- 内存占用:java堆区所占用的内存大小;
这三者共同构成一个“不可能三角”。三者总体的表现会随着技术进步而越来越好。一款优秀的收集器通常最多同时满足其中的两项。
简单来说,主要抓住两点:
- 吞吐量
吞吐量优先,意味着在单位时间内,STW的时间最短 - 暂停时间
暂停时间优先,意味着尽可能让单次STW的时间最短
1.1.2 各项设置:
- 堆设置
- 参数-Xms和-Xmx,通常设置为相同的值,避免运行时要不断扩展JVM内存,建议扩大至3-4倍FullGC后的老年代空间占用。
- 年轻代设置
- 参数-Xmn,1-1.5倍FullGC之后的老年代空间占用。
- 避免新生代设置过小,当新生代设置过小时,会带来两个问题:一是minor GC次数频繁,二是可能导致 minor GC对象直接进老年代。当老年代内存不足时,会触发Full GC。
- 避免新生代设置过大,当新生代设置过大时,会带来两个问题:一是老年代变小,可能导致Full GC频繁执行;二是 minor GC 执行回收的时间大幅度增加。
- 老年代设置
- 注重低延迟的应用
- 老年代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数,如果堆设置偏小,可能会造成内存碎片、高回收频率以及应用暂停,如果堆设置偏大,则需要较长的收集时间
- 吞吐量优先的应用
- 一般吞吐量优先的应用都有一个较大的年轻代和一个较小的老年代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而老年代尽可能存放长期存活对象
- 方法区设置
- 基于jdk1.7版本,永久代:参数-XX:PermSize和-XX:MaxPermSize;
- 基于jdk1.8版本,元空间:参数 -XX:MetaspaceSize和-XX:MaxMetaspaceSize;
- 通常设置为相同的值,避免运行时要不断扩展,建议扩大至1.2-1.5倍FullGc后的永久带空间占用。
- GC设置
- 截至jdk1.8 ,一共有7款不同垃圾收集器。每一款不同的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选择不同的垃圾回收器
- Serial➡Parallel(并行) ➡CMS(并发)➡ G1➡ZGC
GC | 分类 | 作用位置 | 使用算法 | 特点 | 使用场景 |
Serial | 串行 | 新生代 | 复制算法 | 响应速度优先 | 单CPU环境下client模式 |
ParNew | 并行 | 新生代 | 复制算法 | 响应速度优先 | 多CPU环境下Server模式下与CMS配合使用 |
Parallel | 并行 | 新生代 | 复制算法 | 吞吐量优先 | 适用于后台运算而不需要太多交互的场景 |
Serial Old | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单CPU环境下client模式 |
Parallel Old | 并行 | 老年代 | 标记-整理 | 吞吐量优先 | 适用于后台运算而不需要太多交互的场景 |
CMS | 并行 | 老年代 | 标记-清除 | 响应速度优先 | 互联网或B/S业务 |
G1 | 并行、并发 | 老年代、新生代 | 复制算法、标记-整理 | 响应速度优先 | 面向服务端应用 |
- 如果你想要最小化地使用内存和并行开销,请选择Serial Old(老年代) + Serial(年轻代)
- 如果你想要最大化应用程序的吞吐量,请选择Parallel Old(老年代) + Parallel(年轻代)
- 如果你想要最小化GC的中断或停顿时间,请选择CMS(老年代) + ParNew(年轻代)
1.2 tomcat 调优
1.2.1 采用动静分离
静态资源如果让Tomcat处理的话,Tomcat的性能会损耗很多所以一般采用Nginx+Tomca实现动静分离,让Tomcat只负责jsp文件的解析工作,Nginx是实现静态资源的访问.
1.2.2 内存空间优化
JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
- -server:服务器模式
-Xms:堆内存初始化大小
-Xmx:堆内存空间上限
-XX:NewSize=:新生代空间初始化大小
-XX:MaxNewSize=:新生代空间最大值
1.2.3 线程池调整
常用属性:
- 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?
Out of memory(OOM)是一种操作系统或者程序已经无法再申请到内存的状态。经常是因为所有可用的内存,包括磁盘交换空间都已经被分配了。当JVM因为没有足够的内存来为对象分配空间、并且垃圾回收器也已经没有空间可回收时,就会抛出 java.lang.Out Of Memory Error 错误
2.1 Java heap space
当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出 java.lang.Out Of Memory Error:Java heap space 错误(根据实际生产经验,可以对程序日志中的 Out Of Memory Error 配置关键字告警,一经发现,立即处理)。
原因分析
- 请求创建一个超大对象,通常是一个大数组。
- 超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
- 过度使用终结器(Finalizer),该对象没有立即被 GC。
- 内存泄漏(Memory Leak),大量对象引用没有释放,JVM 无法对其自动回收,常见于使用了 File 等资源没有回收。
解决方案
针对大部分情况,通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决,可以参考以下情况做进一步处理:
- 如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。
- 如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。
- 如果是内存泄漏,需要找到持有的对象,修改代码设计,比如关闭没有释放的连接。
2.2 GC overhead limit exceeded
当 Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次,就会抛出 java.lang.Out Of Memory Error:GC overhead limit exceeded 错误。简单地说,就是应用程序已经基本耗尽了所有可用内存, GC 也无法回收。此类问题的原因与解决方案跟 Java heap space 非常类似
2.3 Permgen space
该错误表示永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大。
原因分析
- 永久代存储对象主要包括以下几类:
- 加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码;
- 常量池;
- 对象数组/类型数组所关联的 class;
- JIT 编译器优化后的 class 信息。
PermGen 的使用量与加载到内存的 class 的数量/大小正相关。
解决方案
根据 Permgen space 报错的时机,可以采用不同的解决方案
- 程序启动报错,修改 -XX:MaxPermSize 启动参数,调大永久代空间。
- 应用重新部署时报错,很可能是没有应用没有重启,导致加载了多份 class 信息,只需重启 JVM 即可解决。
- 运行时报错,应用程序可能会动态创建大量 class,而这些 class 的生命周期很短暂,但是 JVM 默认不会卸载 class,可以设置 -XX:+CMSClassUnloadingEnabled 和 -XX:+UseConcMarkSweepGC这两个参数允许 JVM 卸载 class。
2.4 Metaspace
JDK 1.8 使用 Metaspace 替换了永久代(Permanent Generation),该错误表示 Metaspace 已被用满,通常是因为加载的 class 数目太多或体积太大。
此类问题的原因与解决方法跟 Permgen space 非常类似,需要特别注意的是调整 Metaspace 空间大小的启动参数为 -XX:MaxMetaspaceSize。
2.5 Unable to create new native thread
每个 Java 线程都需要占用一定的内存空间,当 JVM 向底层操作系统请求创建一个新的 native 线程时,如果没有足够的资源分配就会报此类错误。
原因分析
JVM 向 OS 请求创建 native 线程失败,就会抛出 Unable to create new native thread,常见的原因如下:
- 线程数超过操作系统最大线程数 ulimit 限制;
- 线程数超过 kernel.pid_max(只能重启);
- native 内存不足;
该问题发生的常见过程主要包括以下几步:
- JVM 内部的应用程序请求创建一个新的 Java 线程;
- JVM native 方法代理了该次请求,并向操作系统请求创建一个 native 线程;
- 操作系统尝试创建一个新的 native 线程,并为其分配内存;
- 如果操作系统的虚拟内存已耗尽,或是受到 32 位进程的地址空间限制,操作系统就会拒绝本次 native 内存分配;
- JVM 将抛出 java.lang.Out Of Memory Error:Unable to create new native thread 错误。
解决方案
- 升级配置,为机器提供更多的内存;
- 降低 Java Heap Space 大小;
- 修复应用程序的线程泄漏问题;
- 限制线程池大小;
- 使用 -Xss 参数减少线程栈的大小;
- 调高 OS 层面的线程最大数:执行 ulimia-a 查看最大线程数限制,使用 ulimit-u xxx 调整最大线程数限制。
2.6 Out of swap space
该错误表示所有可用的虚拟内存已被耗尽。虚拟内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)两部分组成。当运行时程序请求的虚拟内存溢出时就会报 Outof swap space的错误。
原因分析
- 地址空间不足;
- 物理内存已耗光;
- 应用程序的本地内存泄漏(native leak),例如不断申请本地内存,却不释放。
- 执行 jmap-histo:live 命令,强制执行 Full GC;如果几次执行后内存明显下降,则基本确认为 Direct Byte Buffer 问题。
解决方案
- 升级地址空间为 64 bit;
- 使用 Arthas 检查是否为 Inflater/Deflater 解压缩问题,如果是,则显式调用 end 方法。
- Direct Byte Buffer 问题可以通过启动参数 -XX:MaxDirectMemorySize 调低阈值。
- 升级服务器配置/隔离部署,避免争用。
2.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,寻找评分低的进程,并将其“杀死”,释放内存资源。
解决方案
- 升级服务器配置/隔离部署,避免争用;
- OOM Killer 调优。
2.8 Requested array size exceeds VM limit
JVM 限制了数组的最大长度,该错误表示程序请求创建的数组超过最大长度限制。JVM 在为数组分配内存前,会检查要分配的数据结构在系统中是否可寻址,通常为 Integer.MAX_VALUE-2。此类问题比较罕见,通常需要检查代码,确认业务是否需要创建如此大的数组,是否可以拆分为多个块,分批执行。
2.9 Direct buffer memory
Java 允许应用程序通过 Direct Byte Buffer 直接访问堆外内存,许多高性能程序通过 Direct Byte Buffer 结合内存映射文件(Memory Mapped File)实现高速 IO。
原因分析
Direct Byte Buffer 的默认大小为 64 MB,一旦使用超出限制,就会抛出 Direct buffer memory 错误。
解决方案
- Java 只能通过 Byte Buffer.allocateDirect 方法使用 Direct Byte Buffer,因此,可以通过 Arthas 等在线诊断工具拦截该方法进行排查。
- 检查是否直接或间接使用了 NIO,如 netty,jetty 等。
- 通过启动参数 -XX:MaxDirectMemorySize 调整 Direct Byte Buffer 的上限值。
- 检查 JVM 参数是否有 -XX:+DisableExplicitGC 选项,如果有就去掉,因为该参数会使 System.gc() 失效。
- 检查堆外内存使用代码,确认是否存在内存泄漏;或者通过反射调用 sun.misc.Cleaner 的 clean() 方法来主动释放被 Direct ByteBuffer 持有的内存空间。
- 内存容量确实不足,升级配置。
3、简述redis特点及其应用场景
3.1 redis特点
3.1.1 速度快
- Redis是用C语言实现的,而众所周知,C语言是“距离”操作系统最近的的编程语言,执行速度快
- Redis采用了单线程的架构(这点很容易遗忘,但是是Redis的最重要特性),避免了多线程的资源竞争问题
- Redis的源码非常精简,可以说是集性能和优雅于一身的代码
3.1.2 基于键值对的服务器
Redis的全程是Remote Dictionary Server,是集合了五种数据结构:字符串、列表、哈希、集合、有序集合,可以说五种数据结构都是围绕于key-value的形式,而value不仅仅可以是值,还能是具体的数据结构,这给予了Redis强大的变化性和灵活能力。
3.1.3 丰富的功能
- 数据结构的强大
- 提供了key过期的功能,这能运用于实现缓存
- 提供了发布订阅的功能,可运用于消息队列,如celery
- 支持lua脚本功能,当觉得Redis的命令实现功能不够时,就能利用lua来创建新的功能
- 提供了简单的事务功能,不过不能支持回滚,但也能一定程度上保持事务的特性
- 提供了pipeling功能,这样客户端可以将多条命令一次io,减少了网络的开销
3.1.4 简单稳定
- 一方面是在3.0版本之前源代码仅3万行,后面3.0加入了集群后代码加到了5万行,而5万行的源代码对于开发人员来说,要理解掌握它也显得并不是那么难;
- 另一方面就是Redis是单线程的结构,这使得Redis的服务端处理模型变得简单,客户端开发也显得简单。
- Redis虽然代码少,并且是单线程的,但是它又非常的稳定,很少会出现因为自身bug而down掉的情况。
3.1.5 客户端语言多
Redis目前基本可以说和MySQL的知名度一样高了,太多的运用场景,太多的支持语言,常见的比如:java的jedis,Python的redis、PHP、C、C++等等。
3.1.6 持久化
Redis还支持两种方式的持久化,即将数据写入磁盘的方法,RDB和AOF
3.1.7 主从复制
主从模式(master/slave),可以实现Redis数据的跨主机备份。
3.1.8 高可用和分布式
Redis从2.8版本后提供了高可用实现的Redis Sentinel,即Redis的“哨兵机制”,可以保证Redis节点的故障发现和自动转移,这实现了Redis强大的分布式功能。redis 3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群当中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接。
3.2 典型应用场景
- Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
- 缓存:数据查询、电商网站商品信息、新闻内容
- 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
- 微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
- 消息队列:ELK的日志缓存、部分业务的订阅发布系统
- 地理位置: 基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能
4、对比redis的RDB、AOF模式的优缺点
Redis 虽然是一个内存级别的缓存程序,也就是redis 是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久保存的目的。目前redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF
4.1 RBD模式和方式
RDB(Redis DataBase):基于时间的快照,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前时间点之间未做快照的数据
- save: 同步,会阻赛其它命令,不推荐使用
- bgsave: 异步后台执行,不影响其它命令的执行
- 自动: 制定规则,自动执行
4.1.1 RDB 模式优点
- RDB快照保存了某个时间点的数据,可以通过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操作,不推荐)命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本,很适合备份,并且此文件格式也支持有不少第三方工具可以进行后续的数据分析 。比如:可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
- RDB可以最大化Redis的性能,父进程在保存 RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/0操作。
- RDB在大量数据,比如几个G的数据,恢复的速度比AOF的快
4.1.2 RDB 模式缺点
- 不能实时保存数据,可能会丢失自上一次执行RDB备份到当前的内存数据。如果你需要尽量避免在服务器故障时丢失数据,那么RDB并不适合。虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松快速的操作。因此一般会超过5分钟以上才保存一次RDB文件。在这种情况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。
- 当数据量非常大的时候,从父进程fork子进程进行保存至RDB文件时需要一点时间,可能是毫秒或者秒,取决于磁盘IO性能。在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端。如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或更久。虽然 AOF重写也需要进行fork(),但无论AOF重写的执行间隔有多长,数据的持久性都不会有任何损失。
4.2 AOF 模式
AOF:Append Only File,按照操作顺序依次将操作追加到指定的日志文件末尾.
AOF 和 RDB 一样使用了写时复制机制,AOF默认为每秒钟 fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障最多只丢失1秒钟之内的数据,也可以设置不同的fsync策略
always,即设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的I/O影响
同时启用RDB和AOF,进行恢复时,默认AOF文件优先级高于RDB文件,即会使用AOF文件进行恢复
注意:AOF 模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB,而AOF默认没有数据文件存在,从而导致所有数据丢失
4.2.1 AOF 模式优点
- 数据安全性相对较高,根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次 fsync,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek,即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次操作只是写入了一半数据就出现系统崩溃问题,不用担心,在Redis下一次启动之前,可以通过 redis-check-aof 工具来解决数据一致性的问题
- Redis可以在 AOF文件体积变得过大时,自动地在后台对AOF进行重写,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新 AOF文件的过程中,append模式不断的将修改数据追加到现有的 AOF文件里面,即使重写过程中发生停机,现有的 AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建
- AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此 AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单。举个例子,如果不小心执行了FLUSHALL命令,但只要AOF文件未被重写,那么只要停止服务器,移除 AOF文件末尾的FLUSHAL命令,并重启Redis,就可以将数据集恢复到FLUSHALL执行之前的状态。
4.2.2 AOF 模式缺点
- 即使有些操作是重复的也会全部记录,AOF 的文件大小要大于 RDB 格式的文件
- AOF 在恢复大数据集时的速度比 RDB 的恢复速度要慢
- 根据fsync策略不同,AOF速度可能会慢于RDB
- bug 出现的可能性更多
4.3 RDB和AOF 的选择
- 如果主要充当缓存功能,或者可以承受数分钟数据的丢失,通常生产环境一般只需启用RDB即可,此也是默认值
- 如果数据需要持久保存,一点不能丢失,可以选择同时开启RDB和AOF
- 一般不建议只开启AOF
5 实现redis哨兵,模拟master故障场景
5.1 哨兵Sentinel运行工作原理
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中的三个定时任务
- 每10秒每个sentinel对master和slave执行info
- 发现slave节点
- 确认主从关系
- 每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
- 通过sentinel__:hello频道交互
- 交互对节点的“看法”和自身信息
- 每1秒每个sentinel对其他sentinel和redis执行ping
5.2 实现Redis哨兵,模拟master故障场景
环境介绍
节点 | IP | redis版本 |
redis-n01 Sentinel | 10.10.10.21 | 6.2.4 |
redis-n02 Sentinel | 10.10.10.22 | 6.2.4 |
redis-n03 Sentinel | 10.10.10.23 | 6.2.4 |
5.2.1 redis 6.2.4 安装
# 一键安装脚本
cat install_redis.sh
VERSION=redis-6.2.4
PASSWORD=123456
INSTALL_DIR=/apps/redis
install() {
yum install -y gcc jemalloc-devel wget make &>/dev/null
if [ $? -eq 0 ] ;then
echo "依赖包给成功部署!!"
else
echo "依赖包部署失败!!"
exit 0
fi
echo "redis软件下载中..."
wget http://download.redis.io/releases/${VERSION}.tar.gz &>/dev/null
if [ $? -eq 0 ];then
echo "${VERSION}版本软件下载完成!"
else
echo "请检查网络!!"
exit 0
fi
tar xf ${VERSION}.tar.gz
cd ${VERSION}
echo "编译进行中..."
make PREFIX=${INSTALL_DIR} install &> /tmp/redis_make.log
if [ $? -eq 0 ];then
echo "编译成功!!"
rm -rf /tmp/redis_make.log
else
echo "编译失败!,请查看/tmp/redis_make.log!!"
exit 0
fi
ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf ${INSTALL_DIR}/etc/
sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e "/# requirepass/a requirepass $PASSWORD" -e "/^dir .*/c dir ${INSTALL_DIR}/data/" -e "/logfile .*/c logfile ${INSTALL_DIR}/log/redis_6379.log" -e "/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis_6379.pid" ${INSTALL_DIR}/etc/redis.conf
id redis &>/dev/null
if [ $? -eq 0 ]; then
echo "Redis 用户已存在!"
else
useradd -r -s /sbin/nologin redis
echo "Redis 用户创建成功!"
fi
chown -R redis:redis ${INSTALL_DIR}
cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local
cat > /usr/lib/systemd/system/redis.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start redis
sleep 3
redis-cli -a $PASSWORD INFO Server 2> /dev/null
if [ $? -eq 0 ] ;then
echo "redis 服务安装并启动完成!!,redis密码:${PASSWORD}"
else
echo "redis 服务启动失败!!"
fi
}
install
#脚本执行过程
sh install_redis.sh
依赖包给成功部署!!
redis软件下载中...
redis软件下载完成!
编译进行中...
编译成功!!
Redis 用户创建成功!
net.core.somaxconn = 1024
vm.overcommit_memory = 1
# Server
redis_version:6.2.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:5637745583e2309d
redis_mode:standalone
os:Linux 3.10.0-1160.49.1.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:6240
process_supervised:no
run_id:45cb58083ab95191528d966c1e7ebc3d7ecbf189
tcp_port:6379
server_time_usec:1653029146142787
uptime_in_seconds:3
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:8861978
executable:/apps/redis/bin/redis-server
config_file:/apps/redis/etc/redis.conf
io_threads_active:0
redis 服务安装并启动完成!!redis密码:123456
#三个节点都要执行
5.2.2 主从复制的实现
#配置主从配置,三个节点都执行
sed -i -e 's/^# replicaof .*/replicaof 10.10.10.21 6379/' -e 's/^# masterauth .*/masterauth 123456/' redis.conf
# 重启三个节点redis服务
# 查看redis主从复制信息
[root@redis-n01 ~]# redis-cli -a 123456 INFO Replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2
slave0:ip=10.10.10.22,port=6379,state=online,offset=465580,lag=0
slave1:ip=10.10.10.23,port=6379,state=online,offset=465580,lag=0
master_failover_state:no-failover
master_replid:a37e1e76eae6d90fb54582c690f116f2a9c16002
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:465580
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:465580
[root@redis-n02 redis]# redis-cli -a 123456 INFO Replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.10.10.21
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:465538
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a37e1e76eae6d90fb54582c690f116f2a9c16002
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:465538
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:465538
[root@redis-n03 etc]# redis-cli -a 123456 INFO Replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.10.10.21
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:465636
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a37e1e76eae6d90fb54582c690f116f2a9c16002
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:465636
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:458791
repl_backlog_histlen:6846
##数据同步情况
[root@redis-n01 ~]# redis-cli -a 123456 dbsize
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(integer) 20001
[root@redis-n01 ~]# redis-cli -a 123456 set abc 123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
[root@redis-n02 redis]# redis-cli -a 123456 dbsize
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(integer) 20002
[root@redis-n02 redis]# redis-cli -a 123456 set xyz 456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(error) READONLY You can't write against a read only replica.
[root@redis-n02 redis]#
[root@redis-n03 etc]# redis-cli -a 123456 dbsize
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(integer) 20002
[root@redis-n03 etc]# redis-cli -a 123456 set xyz 456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(error) READONLY You can't write against a read only replica.
5.2.3 哨兵的实现
##准备配置文件
[root@redis-n01 ~]# cp redis-6.2.4/sentinel.conf /apps/redis/etc/
##执行修改命令
[root@redis-n01 ~]# sed -i -e '/^# bind .*/a bind 0.0.0.0' -e '/^pidfile .*/c pidfile /apps/redis/run/redis-sentinel.pid' -e '/^logfile .*/c logfile /apps/redis/log/redis-sentinel.log' -e '/^dir .*/c dir /apps/redis/data' -e '/^sentinel monitor mymaster/,/ 6379 2/s/127.0.0.1/10.10.10.21/ ' -e '1,/^# sentinel auth-pass .*/{s/^# sentinel auth-pass .*/sentinel auth-pass mymaster 123456/}' -e 's/^sentinel .* 30000$/sentinel down-after-milliseconds mymaster 3000/' /apps/redis/etc/sentinel.conf
##编写Service文件
[root@redis-n01 ~]# cat /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@redis-n01 ~]# scp /apps/redis/etc/sentinel.conf 10.10.10.21:/apps/redis/etc/
[root@redis-n01 ~]# scp /apps/redis/etc/sentinel.conf 10.10.10.22:/apps/redis/etc/
[root@redis-n01 ~]# scp /lib/systemd/system/redis-sentinel.service 10.10.10.21:/lib/systemd/system/
[root@redis-n01 ~]# scp /lib/systemd/system/redis-sentinel.service 10.10.10.22:/lib/systemd/system/
##在每个节点上执行
systemctl daemon-reload
chown -R redis:redis /apps/redis/*
##启动redis-sentinel服务
systemctl start redis-sentinel.service
##查看端口
[root@redis-n01 ~]# ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=33226,fd=6))
LISTEN 0 511 *:6379 *:* users:(("redis-server",pid=1679,fd=6))
LISTEN 0 128 *:22 *:* users:(("sshd",pid=1102,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1284,fd=13))
LISTEN 0 511 [::1]:6379 [::]:* users:(("redis-server",pid=1679,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1102,fd=4))
LISTEN 0 100 [::1]:25 [::]:* users:(("master",pid=1284,fd=14))
[root@redis-n02 redis]# ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=14741,fd=6))
LISTEN 0 511 *:6379 *:* users:(("redis-server",pid=13913,fd=6))
LISTEN 0 128 *:22 *:* users:(("sshd",pid=1109,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1293,fd=13))
LISTEN 0 511 [::1]:6379 [::]:* users:(("redis-server",pid=13913,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1109,fd=4))
LISTEN 0 100 [::1]:25 [::]:* users:(("master",pid=1293,fd=14))
[root@redis-n03 ~]# ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=7129,fd=6))
LISTEN 0 511 *:6379 *:* users:(("redis-server",pid=6311,fd=6))
LISTEN 0 128 *:22 *:* users:(("sshd",pid=1101,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1293,fd=13))
LISTEN 0 511 [::1]:6379 [::]:* users:(("redis-server",pid=6311,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1101,fd=4))
LISTEN 0 100 [::1]:25 [::]:* users:(("master",pid=1293,fd=14))
##查看log
[root@redis-n01 ~]# tail -f /apps/redis/log/redis-sentinel.log
33226:X 20 May 2022 19:46:46.123 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
33226:X 20 May 2022 19:46:46.123 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=33226, just started
33226:X 20 May 2022 19:46:46.123 # Configuration loaded
33226:X 20 May 2022 19:46:46.124 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
33226:X 20 May 2022 19:46:46.124 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
33226:X 20 May 2022 19:46:46.124 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
33226:X 20 May 2022 19:46:46.124 * monotonic clock: POSIX clock_gettime
33226:X 20 May 2022 19:46:46.124 * Running mode=sentinel, port=26379.
33226:X 20 May 2022 19:46:46.128 # Sentinel ID is 34467db4c19a7c426dff013fbb123990ad883c0a
33226:X 20 May 2022 19:46:46.128 # +monitor master mymaster 10.10.10.21 6379 quorum 2
33226:X 20 May 2022 19:46:46.128 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 19:46:46.180 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 19:50:42.399 * +sentinel sentinel 43cd0407ef457b2e7f160145251d35f612fcd1e3 10.10.10.22 26379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 19:52:51.239 * +sentinel sentinel ea8392736222bcedf12d811456629667de0067a4 10.10.10.23 26379 @ mymaster 10.10.10.21 6379
[root@redis-n02 ~]# tail -f /apps/redis/log/redis-sentinel.log
14679:X 20 May 2022 19:49:23.661 # Sentinel config file /apps/redis/etc/sentinel.conf is not writable: Permission denied. Exiting...
14741:X 20 May 2022 19:50:40.399 # systemd supervision requested or auto-detected, but Redis is compiled without libsystemd support!
14741:X 20 May 2022 19:50:40.399 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14741:X 20 May 2022 19:50:40.399 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=14741, just started
14741:X 20 May 2022 19:50:40.399 # Configuration loaded
14741:X 20 May 2022 19:50:40.400 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
14741:X 20 May 2022 19:50:40.400 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
14741:X 20 May 2022 19:50:40.400 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
14741:X 20 May 2022 19:50:40.400 * monotonic clock: POSIX clock_gettime
14741:X 20 May 2022 19:50:40.400 * Running mode=sentinel, port=26379.
14741:X 20 May 2022 19:50:40.402 # Sentinel ID is 43cd0407ef457b2e7f160145251d35f612fcd1e3
14741:X 20 May 2022 19:50:40.402 # +monitor master mymaster 10.10.10.21 6379 quorum 2
14741:X 20 May 2022 19:50:40.404 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 19:50:40.406 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 19:50:40.737 * +sentinel sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 19:52:51.245 * +sentinel sentinel ea8392736222bcedf12d811456629667de0067a4 10.10.10.23 26379 @ mymaster 10.10.10.21 6379
[root@redis-n03 ~]# tail -f /apps/redis/log/redis-sentinel.log
7129:X 20 May 2022 19:52:49.196 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
7129:X 20 May 2022 19:52:49.196 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
7129:X 20 May 2022 19:52:49.196 * monotonic clock: POSIX clock_gettime
7129:X 20 May 2022 19:52:49.197 * Running mode=sentinel, port=26379.
7129:X 20 May 2022 19:52:49.202 # Sentinel ID is ea8392736222bcedf12d811456629667de0067a4
7129:X 20 May 2022 19:52:49.202 # +monitor master mymaster 10.10.10.21 6379 quorum 2
7129:X 20 May 2022 19:52:49.203 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 19:52:49.205 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 19:52:49.267 * +sentinel sentinel 43cd0407ef457b2e7f160145251d35f612fcd1e3 10.10.10.22 26379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 19:52:49.359 * +sentinel sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.21 6379
##登录redis sentinel 查看状态
[root@redis-n01 ~]# 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.10.10.21:6379,slaves=2,sentinels=3
5.2.4 模拟matser故障
##关闭redis master 节点
[root@redis-n01 ~]# killall redis-server
##切换log
[root@redis-n01 ~]# tail -f /apps/redis/log/redis-sentinel.log
33226:X 20 May 2022 20:12:58.532 # +promoted-slave slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:12:58.533 # +failover-state-reconf-slaves master mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:12:58.614 # +failover-end master mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:12:58.615 # +switch-master mymaster 10.10.10.23 6379 10.10.10.21 6379
33226:X 20 May 2022 20:12:58.615 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:12:58.615 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:13:01.633 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:13:01.633 # +sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:13:15.241 # -sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:13:25.202 * +convert-to-slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.550 # +sdown master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.627 # +odown master mymaster 10.10.10.21 6379 #quorum 3/2
33226:X 20 May 2022 20:15:14.627 # +new-epoch 4
33226:X 20 May 2022 20:15:14.627 # +try-failover master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.629 # +vote-for-leader 34467db4c19a7c426dff013fbb123990ad883c0a 4
33226:X 20 May 2022 20:15:14.633 # 43cd0407ef457b2e7f160145251d35f612fcd1e3 voted for 34467db4c19a7c426dff013fbb123990ad883c0a 4
33226:X 20 May 2022 20:15:14.634 # ea8392736222bcedf12d811456629667de0067a4 voted for 34467db4c19a7c426dff013fbb123990ad883c0a 4
33226:X 20 May 2022 20:15:14.694 # +elected-leader master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.694 # +failover-state-select-slave master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.796 # +selected-slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.796 * +failover-state-send-slaveof-noone slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:14.875 * +failover-state-wait-promotion slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:15.641 # +promoted-slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:15.641 # +failover-state-reconf-slaves master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:15.719 # +failover-end master mymaster 10.10.10.21 6379
33226:X 20 May 2022 20:15:15.719 # +switch-master mymaster 10.10.10.21 6379 10.10.10.23 6379
33226:X 20 May 2022 20:15:15.719 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:15:15.719 * +slave slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:15:18.805 # +sdown slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
33226:X 20 May 2022 20:15:18.805 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
[root@redis-n02 ~]# tail -f /apps/redis/log/redis-sentinel.log
14741:X 20 May 2022 20:12:57.462 # +vote-for-leader 34467db4c19a7c426dff013fbb123990ad883c0a 3
14741:X 20 May 2022 20:12:57.463 # +odown master mymaster 10.10.10.23 6379 #quorum 2/2
14741:X 20 May 2022 20:12:57.463 # Next failover delay: I will not start a failover before Fri May 20 20:18:57 2022
14741:X 20 May 2022 20:12:58.622 # +config-update-from sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.23 6379
14741:X 20 May 2022 20:12:58.622 # +switch-master mymaster 10.10.10.23 6379 10.10.10.21 6379
14741:X 20 May 2022 20:12:58.622 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:12:58.622 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:13:01.690 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:13:01.690 # +sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:13:15.245 # -sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:15:14.534 # +sdown master mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:15:14.635 # +new-epoch 4
14741:X 20 May 2022 20:15:14.637 # +vote-for-leader 34467db4c19a7c426dff013fbb123990ad883c0a 4
14741:X 20 May 2022 20:15:14.637 # +odown master mymaster 10.10.10.21 6379 #quorum 2/2
14741:X 20 May 2022 20:15:14.637 # Next failover delay: I will not start a failover before Fri May 20 20:21:15 2022
14741:X 20 May 2022 20:15:15.727 # +config-update-from sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.21 6379
14741:X 20 May 2022 20:15:15.727 # +switch-master mymaster 10.10.10.21 6379 10.10.10.23 6379
14741:X 20 May 2022 20:15:15.727 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
14741:X 20 May 2022 20:15:15.727 * +slave slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
14741:X 20 May 2022 20:15:18.776 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
14741:X 20 May 2022 20:15:18.776 # +sdown slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
[root@redis-n03 ~]# tail -f /apps/redis/log/redis-sentinel.log
7129:X 20 May 2022 20:12:57.473 # +vote-for-leader 34467db4c19a7c426dff013fbb123990ad883c0a 3
7129:X 20 May 2022 20:12:57.511 # +odown master mymaster 10.10.10.23 6379 #quorum 3/2
7129:X 20 May 2022 20:12:57.511 # Next failover delay: I will not start a failover before Fri May 20 20:18:57 2022
7129:X 20 May 2022 20:12:58.632 # +config-update-from sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.23 6379
7129:X 20 May 2022 20:12:58.633 # +switch-master mymaster 10.10.10.23 6379 10.10.10.21 6379
7129:X 20 May 2022 20:12:58.633 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:12:58.633 * +slave slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:13:01.694 # +sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:13:01.695 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:13:15.312 # -sdown slave 10.10.10.23:6379 10.10.10.23 6379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:15:14.504 # +sdown master mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:15:14.646 # +new-epoch 4
7129:X 20 May 2022 20:15:14.648 # +vote-for-leader 34467db4c19a7c426dff013fbb123990ad883c0a 4
7129:X 20 May 2022 20:15:15.612 # +odown master mymaster 10.10.10.21 6379 #quorum 3/2
7129:X 20 May 2022 20:15:15.612 # Next failover delay: I will not start a failover before Fri May 20 20:21:15 2022
7129:X 20 May 2022 20:15:15.738 # +config-update-from sentinel 34467db4c19a7c426dff013fbb123990ad883c0a 10.10.10.21 26379 @ mymaster 10.10.10.21 6379
7129:X 20 May 2022 20:15:15.738 # +switch-master mymaster 10.10.10.21 6379 10.10.10.23 6379
7129:X 20 May 2022 20:15:15.738 * +slave slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
7129:X 20 May 2022 20:15:15.738 * +slave slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
7129:X 20 May 2022 20:15:18.739 # +sdown slave 10.10.10.21:6379 10.10.10.21 6379 @ mymaster 10.10.10.23 6379
7129:X 20 May 2022 20:15:18.739 # +sdown slave 10.10.10.22:6379 10.10.10.22 6379 @ mymaster 10.10.10.23 6379
##登录sentinel 查看
[root@redis-n01 ~]# 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.10.10.23:6379,slaves=2,sentinels=3
##master节点切换成功