Redis学习之主从复制(二)

主从复制

在Redis复制的基础上(不包括由Redis Cluster或Redis Sentinel做为附加层提供的高可用性功能),有一个很是简单的使用和配置leader follower(主从)复制:它容许从属Redis实例准确主实例的副本。每次连接断开时,slave将自动从新链接到master,而且不管master发生什么状况,它都会尝试成为它的精确副本。java

该系统使用三种主要机制:redis

  1. 当主实例和从属实例链接良好时,主设备经过向从设备发送命令流来保持从设备更新,以便复制对主设备端发生的数据集的影响,缘由是:客户端写入,key已过时或驱逐,更改主数据集的任何其余操做。
  2. 当主设备和从设备之间的链路中断时,对于网络问题或者因为主设备或从设备中检测到超时,从设备从新链接并尝试继续部分从新同步:这意味着它将尝试仅获取部件它在断开链接时错过的命令流。
  3. 当没法进行部分从新同步时,slave将要求彻底从新同步。这将涉及一个更复杂的过程,其中主机须要建立其全部数据的快照,将其发送到从机,而后在数据集更改时继续发送命令流。

Redis默认使用异步复制,即低延迟和高性能,是绝大多数Redis用例的天然复制模式。可是,Redisslave异步确认它们与master按期收到的数据量。所以主设备不会每次等待从设备处理命令,可是若是须要,它知道哪一个从设备已经处理了什么命令。这容许具备可选的同步复制。算法

客户端可使用WAIT命令请求某些数据的同步复制。可是,WAIT只能确保在其余Redis实例中存在指定数量的已确认副本,但它不会将一组Redis实例转换为具备强一致性的CP系统:在故障转移期间,确认的写入仍然可能丢失,具体取决于关于Redis持久性的确切配置。然而,对于WAIT,在失败事件以后丢失写入的几率大大下降到某些难以触发的故障模式。数据库

您能够查看Sentinel或Redis集群文档,以获取有关高可用性和故障转移的更多信息。本文档的其他部分主要描述了Redis基本复制的基本特征。安全

如下是有关Redis复制的一些很是重要的事实:bash

  • Redis使用异步复制,异步slave到master确认处理的数据量。
  • 主设备能够有多个从设备。
  • Slaves可以接受来自其余Slaves的链接。除了将多个从设备链接到同一主设备以外,从设备还能够以相似级联的结构链接到其余从设备。从Redis 4.0开始,全部子slave将从master接收彻底相同的复制流。
  • Redis复制在主端是非阻塞的。这意味着当一个或多个从服务器执行初始同步或部分从新同步时,主服务器将继续处理查询。
  • 复制在从属端也很大程度上是非阻塞的。当slave正在执行初始同步时,它可使用旧版本的数据集处理查询,假设您在redis.conf中配置了Redis。不然,您能够将Redis从属配置为在复制流关闭时向客户端返回错误。可是,在初始同步以后,必须删除旧数据集而且必须加载新数据集。slave将在此简短窗口期间阻止传入链接(对于很是大的数据集,可能长达数秒)。从Redis 4.0开始,能够配置Redis,以便删除旧数据集在不一样的线程中发生,可是加载新的初始数据集仍然会在主线程中发生并阻塞slave。
  • 复制能够用于可伸缩性,以便为只读查询提供多个slave(例如,能够将慢速O(N)操做卸载到slave),或者仅用于提升数据安全性和高可用性。
  • 可使用复制来避免让主服务器花费巨大的开支将完整数据集写入磁盘:典型的技术是配置主服务器redis.conf以免持久存储到磁盘,而后链接配置为save from time to time的从服务器,或者启用AOF。可是,必须当心处理此设置,由于从新启动的主服务器将以空数据集开始:若是从服务器尝试与其同步,则从服务器也将被清空。

工做原理

每一个Redis主服务器都有一个replication ID:它是一个大的伪随机字符串,用于标记数据集的给定叙述。每一个主服务器还会为生成的每一个复制流字节递增一个偏移量,以便将其发送到从属服务器,方便使用修改数据集的新更改来更新从属服务器的状态。即便没有实际链接的slave,复制偏移也会增长,以下:服务器

Replication ID, offset
复制代码

用来标识主数据集的确切版本。网络

命令./redis-cli -p 6379 -a 你的密码 info server | grep run能够查看具体的id:并发

当slave链接到master时,它们使用PSYNC命令发送它们的旧主replication ID以及它们到目前为止处理的偏移量。这样master只用发送所需的增量部分。可是,若是主缓冲区中没有足够的backlog,或者从属设备指不知道历史记录(复制ID),则发生彻底从新同步:在这种状况下,从属设备将得到数据集的完整副本, 从头开始。less

这是彻底同步在更多细节中的工做方式:

主服务器启动后台保存过程以生成RDB文件。同时它开始缓冲从客户端收到的全部新写命令。后台保存完成后,主服务器将数据库文件传输到从服务器,从服务器将其保存在磁盘上,而后将其加载到内存中。而后,主设备将全部缓冲的命令发送到从设备。这是做为命令流完成的,而且与Redis协议自己的格式相同。

您能够经过telnet本身尝试。在服务器执行某些工做时链接到Redis端口并发出SYNC命令。您将看到批量传输,而后主服务器接收的每一个命令都将在telnet会话中从新发出。实际上,较新的Redis实例再也不使用SYNC旧协议,但其仍然存在向后兼容性:它不容许部分从新同步,所以如今用PSYNC代替。

如前所述,当主 - 从链路因为某种缘由而关闭时,从设备可以自动从新链接。若是主设备接收到多个并发从属同步请求,它将执行单个后台保存以便为全部这些请求提供服务。

全量复制

开销

1)bgsave时间。

2)RDB文件网络传输时间。

3)从节点清空数据时间。

4)从节点加载RDB的时间。

5)可能的AOF重写时间。

部分复制

配置

配置基本Redis复制很简单:只需将如下行添加到从属配置文件:

slaveof 192.168.1.1 6379
复制代码

固然,您须要将192.168.1.1 6379替换为您的主IP地址(或主机名)和端口。或者,您能够调用SLAVEOF命令,主控主机将启动与slave的同步。

还有一些参数用于调整主机在内存中采起的replication backlog以执行部分从新同步。

可使用repl-diskless-sync配置参数启用无盘复制。传输开始后,等待在第一个slave以后到达的更多slaves的延迟由repl-diskless-sync-delay 参数控制。

具体步骤

1)进入redis目录,复制redis.conf文件为redis-6380.conf

cp redis.conf redis-6380.conf
复制代码

2)修改redis-6380.conf的端口号,保存的rdb文件名,日志名等参数。

3)找到REPLICATION模块,修改以下:

replicaof 127.0.0.1 6379

4)若是主节点redis设置了密码,修改masterauth属性:

在箭头处填上密码。

5)启动从结点:

./redis-server ../redis-6380.conf
复制代码

6)使用命令./redis-cli -p 6380 -a 你的密码 info replication查看从节点状态:

能够发现role为slave,而且master_link_status为up,说明启动成功。说明一下,上图的slave_repl_offset就是所谓的偏移量。

尝试使用redis-cli在主节点中写入一个值:

./redis-cli -p 6379 -a 你的密码
> set hello world
复制代码

进入从节点,输入get hello,能够发现已经可以正确获取值。

7)可使用命令slaveof no one取消从节点模式。

只读slave

从Redis 2.6开始,slave支持默认启用的只读模式。此行为由slave-read-onlyredis.conf文件中的选项控制,能够在运行时使用CONFIG SET启用和禁用。

只读slave将拒绝全部写入命令,所以因为错误而写入slave是不可能的。这并不意味着该功能旨在将从属实例暴露给互联网,或者更广泛地意味着将不受信任的客户端存在的网络,由于管理命令喜欢DEBUGCONFIG仍然启用。可是,经过使用该rename-command指令禁用redis.conf中的命令,能够提升只读实例的安全性。

您可能想知道为何能够恢复只读设置并具备能够经过写入操做做为目标的从属实例。若是slave和master从新同步或者slave从新启动,那么这些写操做将被丢弃,但有一些合法的用例可用于在可写slave中存储短暂数据。

例如,计算慢速设置或排序集合操做并将它们存储到本地key中是屡次观察可写slave的用例。

可是请注意,版本4.0以前的可写slave没法设置到期时间。这意味着若是您使用EXPIRE或为key设置最大TTL的其余命令,key将泄漏,虽然您在使用读取命令访问key时可能再也看不到它,您将在key计数中看到它仍在使用内存。所以,一般混合可写slave(之前的版本4.0)和带有TTL的键会产生问题。

Redis 4.0 RC3及更高版本彻底解决了这个问题,如今可写的从设备可以像主设备那样用TTL删除key,但用DB编号大于63的key除外(但默认状况下Redis实例只有16个数据库)。

另请注意,因为Redis 4.0从属写入仅是本地的,而且不会传播到附加到实例的子从属。相反,子slave将始终接收与顶层master向中间slave发送的复制流相同的复制流。例如,在如下设置中:

A ---> B ---> C
复制代码

即便B是可写的,C也不会看到B写入,而是具备与主实例相同的数据集A

开发中运维的常见问题

读写分离

1)读写分离:读流量分摊到从节点,写流量分摊到主节点。

2)可能遇到的问题

一、复制数据延迟。

二、读到过时数据(3.2已解决)。

三、从节点故障。

规避全量复制

1)第一次全量复制

一、第一次不可避免。

二、小主节点、低峰。

2)节点运行ID不匹配

一、主节点重启(运行ID变化)。

二、故障转移,例如哨兵或集群。

3)复制积压缓冲区不足

一、网络中断,部分复制没法知足。

二、增大复制缓冲区配置rel_backlog_size,网络“加强”。

规避复制风暴

1)单节点复制风暴

问题:主节点重启,多从节点复制。

解决:更换复制拓扑。

2)单机器复制风暴

问题:机器宕机后,大量全量复制。

解决:主节点分散多机器。

Redis Sentinel

Redis Sentinel为Redis提供高可用性。实际上,这意味着使用Sentinel能够建立一个Redis部署,能够在没有人为干预的状况下抵御某些类型的故障。

Redis Sentinel还提供其余附属任务,如监控,通知,并充当客户端的配置提供程序。

这是宏观级别的Sentinel功能的完整列表(即大图):

  • 监控。Sentinel会不断检查主实例和从属实例是否按预期工做。
  • 通知。Sentinel能够经过API通知系统管理员,另外一台计算机程序,其中一个受监控的Redis实例出现问题。
  • 自动故障转移。若是主服务器未按预期工做,Sentinel能够启动故障转移过程,其中从服务器被提高为主服务器,其余服务器将从新配置为新主服务器,而且使用Redis服务器的应用程序会通知有关新服务器的地址。链接。
  • 配置提供商。Sentinel充当客户端服务发现的权限来源:客户端链接到Sentinels,以便询问负责给定服务的当前Redis主服务器的地址。若是发生故障转移,Sentinels将报告新地址。

Sentinel的分布式特性

Redis Sentinel是一个分布式系统:

Sentinel自己设计为在多个Sentinel进程协同工做的配置中运行。让多个Sentinel进程协做的优点以下:

  1. 当多个Sentinels认为给定主设备再也不可用时,将执行故障检测。这下降了误报的可能性。
  2. 即便并不是全部Sentinel进程都正常工做,Sentinel也能正常工做,从而使系统可以抵御故障。毕竟,拥有故障转移系统自己就是一个单一的故障点并非一件好事。

Sentinels,Redis实例(主服务器和从服务器)以及链接到Sentinel和Redis的客户端的总和也是具备特定属性的更大的分布式系统。在本文档中,将逐步介绍概念,从了解Sentinel的基本属性所需的基本信息,到更复杂的信息(可选),以了解Sentinel的工做原理。

得到哨兵

Sentinel的当前版本称为Sentinel 2。它是使用更强大和更简单的预测算法(本文档中解释)重写初始Sentinel实现。

自Redis 2.8发布Redis Sentinel的稳定版本。

不稳定的分支中进行了新的开发,一旦它们被认为是稳定的,新的特征有时会被反导到最新的稳定分支中。

Redis 2.6附带的Redis Sentinel版本1已弃用,不该使用。

运行Sentinel

若是您正在使用redis-sentinel可执行文件(或者若是您的可执行文件具备该名称的符号连接redis-server),则可使用如下命令行运行Sentinel:

redis-sentinel /path/to/sentinel.conf
复制代码

或者,您能够直接使用redis-server在Sentinel模式下启动它的可执行文件:

redis-server /path/to/sentinel.conf --sentinel
复制代码

两种方式都是同样的。

可是**,在运行Sentinel时必须**使用配置文件,由于系统将使用此文件以保存从新启动时将从新加载的当前状态。若是没有给出配置文件或配置文件路径不可写,Sentinel将拒绝启动。

默认状况下,Sentinels会侦听与TCP端口26379的链接,所以要使 Sentinels正常工做,必须打开服务器的端口26379 以接收来自其余Sentinel实例的IP地址的链接。不然,Sentinels没法通话,也没法就该怎么作达成一致,所以永远不会执行故障转移。

在部署以前要了解Sentinel的基本知识

  1. 您须要至少三个Sentinel实例才能实现强大的部署。
  2. 应将三个Sentinel实例放入被认为不能以独立方式启动的计算机或虚拟机中。例如,在不一样的可用区域上执行的不一样物理服务器或虚拟机。
  3. Sentinel + Redis分布式系统不保证在故障期间保留已确认的写入,由于Redis使用异步复制。可是,有一些方法能够部署Sentinel,使窗口丢失限制在某些时刻的写入,同时还有其余不太安全的方式来部署它。
  4. 您须要在客户端得到Sentinel支持。流行的客户端库具备Sentinel支持,但不是所有。
  5. 若是您不在开发环境中实时进行测试,则没有HA设置是安全的,在生产环境中,若是它们能够工做,则更好。您可能有一个错误的配置,只有在为时已晚(凌晨3点,当您的master节点中止工做)时才会变得明显。
  6. Sentinel,Docker或其余形式的网络地址转换或端口映射应谨慎使用:Docker执行端口从新映射,中断其余Sentinel进程的Sentinel自动发现以及主服务器的从属列表。有关详细信息,请查看本文档后面有关Sentinel和Docker的部分。

配置Sentinel

Redis源代码分发包含一个名为sentinel.conf的文件 ,它是一个能够用来配置Sentinel的自我记录的示例配置文件,可是典型的最小配置文件以下所示:

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
复制代码

您只须要指定要监视的主服务器,为每一个单独的主服务器(可能有任意数量的从服务器)提供不一样的名称。无需指定可被自动发现的slaves。Sentinel将自动更新配置有关slaves的其余信息(以便在从新启动时保留信息)。每次在故障转移期间将slave升级为master而且每次发现新的Sentinel时,也会重写该配置。

上面的示例配置基本上监视两组Redis实例,每组实例由主设备和未定义数量的从设备组成。一组实例被调用mymaster,另外一组被调用resque

sentinel monitor语句参数的含义以下:

sentinel monitor <master-group-name> <ip> <port> <quorum>
复制代码

为清楚起见,让咱们逐行检查配置选项的含义:

第一行用于告诉Redis监视一个名为mymaster的主服务器,它位于地址127.0.0.1和端口6379,链接数为2。一切都很明显,可是quorum参数:

  • quorum是认为master不可达的哨兵的数量,为了真正把slave标志为失败,并最终启动关闭做业。
  • 可是**,quorum仅用于检测故障**。为了实际执行故障转移,其中一个Sentinels须要被选为故障转移的领导者并被受权继续进行。其由大多数Sentinel进程的投票而来。

所以,例如,若是您有5个Sentinel进程,而且给定主服务器的quorum设置为值2,则会发生如下状况:

  • 若是两个Sentinels同时认定主服务器没法访问,则其中一个将尝试启动故障转移。
  • 若是至少总共有三个Sentinel可达,则故障转移将被受权并实际开始。

实际上,这意味着在故障期间,若是大多数Sentinel进程没法通话(在少数分区中也没有故障转移),Sentinel永远不会启动故障转移

其余Sentinel选项

其余选项几乎老是如下列形式:

sentinel <option_name> <master_name> <option_value>
复制代码

并用于如下目的:

  • down-after-milliseconds 是对于Sentinel开始认为它已关闭而且实例不能到达的(不管是不回复咱们的PING仍是回复错误)以毫秒为单位的时间。
  • parallel-syncs设置可在同一故障转移后从新配置以使用新主服务器的从服务器数。数字越小,故障转移过程完成所需的时间就越多,可是若是从属服务器配置为提供旧数据,则可能不但愿全部从属服务器同时与主服务器从新同步。虽然复制过程对于从属设备大部分是非阻塞的,可是有一段时间它中止从主设备加载批量数据。您可能但愿经过将此选项设置为值1来确保一次只能访问一个slave。

其余选项在本文档的其他部分中进行了描述,并记录在sentinel.confRedis发行版附带的示例文件中。

可使用该SENTINEL SET命令在运行时修改全部配置参数。有关详细信息,请参阅“ **在运行时从新配置Sentinel”**部分。

示例Sentinel部署

如今您已了解Sentinel的基本信息,您可能想知道应该在哪里放置Sentinel进程,须要多少Sentinel进程等等。本节介绍几个示例部署。

  • Masters称为M1,M2,M3,...,Mn。
  • Slaves称为R1,R2,R3,...,Rn(R表明复制品)。
  • Sentinels称为S1,S2,S3,...,Sn。
  • Clients称为C1,C2,C3,...,Cn。
  • 当实例因为Sentinel操做而更改角色时,咱们将其放在方括号内,所以[M1]表示因为Sentinel干预而如今成为主实例的实例。

请注意,咱们永远不会显示仅使用两个Sentinels的设置,由于Sentinels老是须要与大多数人交谈才能启动故障转移。

例1:只有两个哨兵,不要这样作

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

Configuration: quorum = 1
复制代码
  • 在此设置中,若是主M1发生故障,R1将被提高,由于两个Sentinels能够就故障达成协议(显然将quorum设置为1),而且还能够受权故障转移,由于大多数是两个。因此显然它能够表面上工做,但请检查下一点,看看为何这个设置被打破。
  • 若是M1运行的框中止工做,S1也中止工做。在另外一个框S2中运行的Sentinel将没法受权故障转移,所以系统将没法使用。

请注意,为了执行不一样的故障转移,须要多数,而后将最新配置传播到全部Sentinels。另请注意,在没有任何协议的状况下,在上述设置的单个方面进行故障转移的能力将很是危险:

+----+           +------+
| M1 |----//-----| [M1] |
| S1 |           | S2   |
+----+           +------+
复制代码

在上面的配置中,咱们以彻底对称的方式建立了两个主服务器(假设S2能够在未经受权的状况下进行故障转移)。客户端能够无限期地向双方写入,而且没法理解分区什么时候恢复正确的配置,以防止永久性的裂脑状况

因此请始终在三个不一样的盒子中至少部署三个Sentinels

示例2:具备三个框的基本设置

这是一个很是简单的设置,其优势是易于调整以得到额外的安全性。它基于三个框,每一个框都运行Redis进程和Sentinel进程。

+----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2
复制代码

若是主M1发生故障,S2和S3将赞成故障,而且可以受权故障转移,使客户可以继续。

在每一个Sentinel设置中,Redis被异步复制,老是存在丢失一些写入的风险,由于给定的已确认写入可能没法到达被提高为主设备的从设备。可是在上面的设置中,因为客户端使用旧主服务器进行分区,所以风险较高,以下图所示:

+----+
         | M1 |
         | S1 | <- C1 (writes will be lost)
         +----+
            |
            /
            /
+------+    |    +----+
| [M2] |----+----| R3 |
| S2   |         | S3 |
+------+         +----+
复制代码

在这种状况下,网络分区隔离了旧的主M1,所以从属R2被提高为主。可是,与旧主服务器位于同一分区的客户端(如C1)可能会继续将数据写入旧主服务器。这个数据将永远丢失,由于当分区将愈合时,主机将被从新配置为新主机的从机,丢弃其数据集。

使用如下Redis复制功能能够缓解此问题,若是主服务器检测到再也不可以将其写入传输到指定数量的从服务器,则容许中止接受写入。

min-slaves-to-write 1
min-slaves-max-lag 10
复制代码

使用上述配置(请参阅redis.confRedis发行版中的自注释示例以获取更多信息)Redis实例做为主服务器时,若是没法写入至少1个从服务器,将中止接受写入。因为复制是异步的,所以没法实际写入意味着从属设备已断开链接,或者未向咱们发送超过指定max-lag秒数的异步确认。

使用此配置,上例中的旧Redis主M1将在10秒后变为不可用。当分区恢复时,Sentinel配置将收敛到新的配置,客户端C1将可以获取有效配置并继续使用新主设备。

可是没有免费的午饭。经过这种改进,若是两个从属设备关闭,主设备将中止接受写入。这是一个折衷。

具体步骤

1)将三个redis(一主二从)启动。

2)配置sentinel.conf文件:

一、去掉protected-mode no的注释,即让它生效

二、将daemonize改为yes

三、修改logfile为26379.log

四、写入redis密码:sentinel auth-pass mymaster 你的密码(注意这里须要将其配置在sentinel monitor mymaster 你的服务器ip 6379 2语句之下,否则会报“No such master with specified name.”的错误。

五、修改dir

3)进入src目录,使用命令./redis-sentinel ../sentinel.conf进行启动。

4)使用命令:

./redis-cli -p 26379
>info
复制代码

获得结果以下:

5)复制sentinel.conf为sentinel-26380.conf与sentinel-26381.conf,修改端口等信息,重复上述步骤。而且须要将myid注释,最终,sentinels的数目将等于3。

Java客户端

1)Sentinel地址集合。

2)masterName。

3)不是代理模式。

RedisUtils

package com.lamarsan.sentinel.util;

import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisConnectionException;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

/**
 * className: RedisUtil
 * description: TODO
 *
 * @author hasee
 * @version 1.0
 * @date 2018/12/26 10:57
 */
public class RedisUtil {
    private static final Logger myLogger = Logger.getLogger("com.lamarsan.sentinel.util");

    private static JedisSentinelPool pool = null;

    static {
        try {
            Set<String> sentinels = new HashSet<String>();
            sentinels.add("你的ip:26380");
            sentinels.add("你的ip.140:26379");
            sentinels.add("你的ip:26381");
            String masterName = "mymaster";
            String password = "123456";
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMinIdle(8);
            config.setMaxTotal(100);
            config.setMaxIdle(100);
            config.setMaxWaitMillis(10000);
            pool = new JedisSentinelPool(masterName, sentinels, config, password);
            try {
                pool.getResource();
            } catch (JedisConnectionException e) {
                myLogger.info(e.getMessage());
                e.printStackTrace();
            }
        } catch (Exception e) {
            myLogger.info(e.getMessage());
            e.printStackTrace();
        }
    }

    private static void returnResource(JedisSentinelPool pool, Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * <p>经过key获取储存在redis中的value</p>
     * <p>并释放链接</p>
     *
     * @param key
     * @return 成功返回value 失败返回null
     */
    public static String get(String key) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            if (jedis != null) {
                jedis.close();
            }
            e.printStackTrace();
        } finally {
            returnResource(pool, jedis);
        }
        return value;
    }

    /**
     * <p>向redis存入key和value,并释放链接资源</p>
     * <p>若是key已经存在 则覆盖</p>
     *
     * @param key
     * @param value
     * @return 成功 返回OK 失败返回 0
     */
    public static String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.set(key, value);
        } catch (Exception e) {
            if (jedis != null) {
                jedis.close();
            }
            e.printStackTrace();
            return "0";
        } finally {
            returnResource(pool, jedis);
        }
    }
    
    .....
}

复制代码

main

package com.lamarsan.sentinel;

import com.lamarsan.sentinel.util.RedisUtil;

/**
 * className: Test
 * description: TODO
 *
 * @author hasee
 * @version 1.0
 * @date 2019/9/13 15:54
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        RedisUtil.setnx("hello", "world");
        while (true) {
            Thread.sleep(10000);
            String result = RedisUtil.get("hello");
            System.out.println(result);
        }
    }
}
复制代码

结果

三个定时任务

1)每10秒每一个sentinel对master和slave执行info

一、发现slave结点。

二、确认主从关系。

2)每2秒每一个sentinel经过master结点的channel交换信息(pub/sub)

一、经过_sentinel_:hello频道交互。

二、交互对节点的”见解“和自身信息。

3)每1秒每一个sentinel对其余sentinel和redis执行ping。

节点运维

1)机器下线:例如过保等状况。

2)机器性能不足:例如CPU、内存、硬盘、网络等。

3)节点自身故障:例如服务不稳定等。

主节点

sentinel failover <masterName>

从节点

临时下线仍是永久下线,例如是否作一些清理工做,也要考虑读写分离的状况。

相关文章
相关标签/搜索