Java架构直通车:Redis 主从/哨兵/集群 架构详解


Redis一主多从

和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。

一个最经典的Redis单体架构是这样的:一主二从的模式,以实现读写分离。

master节点:提供写服务
slave节点:提供读服务

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第1张图片

主从复制过程:
主从刚刚连接的时候,进行全量同步;全同步结束后,之后进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第2张图片

无磁盘化复制:
master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了。

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第3张图片

Redis哨兵

Sentinel(哨兵)是用于监控Redis集群中Master状态的工具,是 Redis 高可用解决方案,哨兵可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务宕机后,会把这个master下的某个从服务升级为master来替代已宕机的master继续工作:当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master。

之所以使用哨兵,是因为一主多从有个弊端:一旦master节点挂掉后,slave节点是不能提供一个写服务的。

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第4张图片


为了保证Redis的可用性,就引入了哨兵。哨兵可以是一个也可以是多个,sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群。这里介绍一个经典的一主二从三哨兵的场景:

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第5张图片

这里每一个哨兵都会对master和slave做一个监控,每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令 。
现在如果master挂掉:

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第6张图片

哨兵1检测到了,但是此时不能去切换这个master,因为网络可能会有波动,哨兵1检测master挂掉,但是如果仅仅是网络波动,也会表明是挂掉的,在网络波动里,哨兵2和哨兵3也许检测到master仍然存活,所以仅仅靠一个哨兵是不能决定master存活与否的。

这里就引入了少数服从多数的机制,如果哨兵里面一半以上检测到了master挂掉,那么就开始切换master。

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第7张图片

现在就需要选举learder,也是通过哨兵来进行少数服从多数的投票,来将slave变成master。新上任的master需要和剩下的slave进行同步。

最后当前任master恢复后,会成为slave,并与现任master同步。

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第8张图片


tips:

所以,哨兵的部署一定要分布式的部署在不同的节点,其健壮性才能更高。
哨兵模式其实也是一种集群,他能够提高读请求的并发,但是容错方面可能会有一些问题,比如master同步数据给slave的时候,这其实是异步复制吧,这个时候master挂了,那么slave上的数据就没有master新,数据同步需要时间的,1-2秒的数据会丢失。master恢复并转换成slave后,新数据则丢失。


Redis集群(无中心/多中心)

sentinel模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。

下面是三主三从的模式:

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第9张图片
特点

  • 每个节点知道彼此之间的关系,也会知道自己的角色,当然他们也会知道自己存在与一个集群环境中,他们彼此之间可以交互和通信,比如ping pong。那么这些关系都会保存到某个配置文件中,每个节点都有,这个我们在搭建的时候会做配置的。
  • 客户端要和集群建立连接的话,只需要和其中一个建立关系就行。
  • 某个节点挂了,也是通过超过半数的节点来进行的检测,客观下线后主从切换,和我们之前在哨兵模式中提到的是一个道理。

分片:

  • Redis中存在很多的插槽,又可以称之为槽节点,用于存储数据。
  • Redis通过Hash函数来决定数据会被存储到哪个redis节点或者从哪个redis节点读取数据。每个节点包含了多个槽,数据也就是保存在这些槽上的。如下图所示:

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第10张图片

Java架构直通车:Redis 主从/哨兵/集群 架构详解_第11张图片

使用哈希槽的好处就在于可以方便的添加或移除节点。

  • 当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;
  • 当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了。

总结
使用单机/主从或者哨兵的架构模式,都没有解决master 写的压力,

从redis 3.0之后版本支持redis集群架构,Redis集群架构采用无中心/多中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接:

  1. 数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
  2. 高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本。
  3. 实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
  4. 可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
  5. 可以解决master的写压力。

 

你可能感兴趣的:(CentOS7)