0
点赞
收藏
分享

微信扫一扫

第二十周学习作业

追风骚年 2022-05-20 阅读 87

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 配置关键字告警,一经发现,立即处理)。

原因分析

  1. 请求创建一个超大对象,通常是一个大数组。
  2. 超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
  3. 过度使用终结器(Finalizer),该对象没有立即被 GC。
  4. 内存泄漏(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 数目太多或体积太大。

原因分析

  1. 永久代存储对象主要包括以下几类:
  2. 加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码;
  3. 常量池;
  4. 对象数组/类型数组所关联的 class;
  5. JIT 编译器优化后的 class 信息。

PermGen 的使用量与加载到内存的 class 的数量/大小正相关。

解决方案

根据 Permgen space 报错的时机,可以采用不同的解决方案

  1. 程序启动报错,修改 -XX:MaxPermSize 启动参数,调大永久代空间。
  2. 应用重新部署时报错,很可能是没有应用没有重启,导致加载了多份 class 信息,只需重启 JVM 即可解决。
  3. 运行时报错,应用程序可能会动态创建大量 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,常见的原因如下:

  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 调整最大线程数限制。

2.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. 升级服务器配置/隔离部署,避免争用。

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,寻找评分低的进程,并将其“杀死”,释放内存资源。

解决方案

  1. 升级服务器配置/隔离部署,避免争用;
  2. 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 错误。

解决方案

  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特点及其应用场景

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
#!/bin/bash

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节点切换成功





举报

相关推荐

0 条评论