Redis集群(主从、哨兵、分片)

Redis集群

当满足需求时,我们可以只在一台服务器上部署Redis数据库,其他的服务器通过IP、端口等访问这台服务器即可。

但是当一台服务器难以满足时,我们就需要在多台机器上部署一个Redis集群,来满足需求。

Redis集群中主要有如下几种核心功能:

  1. 主从复制
  2. 哨兵模式
  3. 分片分区

主从复制

需求
为了避免单点故障,可选的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。

分工
主从复制集群中由Master节点提供读写服务,Slave节点负责同步Master节点中的数据,提供只读的功能。当Master节点发生故障时,不影响slave节点的读功能,可以手动选择Slave节点充当Master对外提供服务(自动选择是哨兵模式)。

工作机制
当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的写命令,然后将保存的快照文件和缓存的写命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的写命令。复制初始化结束。

之后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。这时是乐观复制,当客户端发送写执行给主机,主机执行完立即将结果返回客户端,并异步的把命令发送给从库,从而不影响性能。也可以设置至少同步给多少个从主才可写。

部分复制
redis 2.8之后的版本,当主从服务器之间出现断开重连后,master可以采用部分同步的方式,将断线期间的命令传给重数据库。
它的工作原理是这样:
主服务器端为复制流维护一个内存缓冲区(in-memory backlog)。主从服务器都维护一个复制偏移量(replication offset)和master run id ,
当连接断开时,从服务器会重新连接上主服务器,然后请求继续复制,假如主从服务器的两个master run id相同,并且指定的偏移量在内存缓冲区中还有效,复制就会从上次中断的点开始继续。如果其中一个条件不满足,就会进行完全重新同步(在2.8版本之前就是直接进行完全重新同步)。
因为主运行id不保存在磁盘中,如果从服务器重启了的话就只能进行完全同步了。

无磁盘复制
通常来讲,一个完全重新同步需要在磁盘上创建一个RDB文件,然后加载这个文件以便为从服务器发送数据。

如果使用比较低速的磁盘,这种操作会给主服务器带来较大的压力。Redis从2.8.18版本开始尝试支持无磁盘的复制。
使用这种设置时,子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储。

注意
如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

master故障时
当主机出现故障时,可以手动进行故障转移,从slave中指定新的master。步骤如下。

  1. 将其中一个存活的Slave节点断开与Master节点的连接,并使其成为新的Master节点(slaveof no one)
  2. 将其他的Slave节点与该新的Master节点建立连接(slaveof ip port)
  3. 修改各个节点的redis.conf配置文件,更新主从映射关系,保证下次重启时使用最新的主从关系启动,避免主从数据不一致问题。

哨兵模式

哨兵模式就是为了解决上面出现的master故障的情景,只不过不需要手动,Redis集群可以自动选master。

Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。

哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

在这里插入图片描述
工作机制

  1. 每个哨兵节点每隔10s会向Master发送info replication命令,获取当前集群最新的拓扑结构,此时每个哨兵就能获取到各个Slave节点的连接信息。
  2. 每个哨兵每隔1s会向集群中的Master和各个Slave节点发送心跳,根据心跳来判断节点是否存活,若在一定时间内节点没有回复,那么该哨兵认为该节点已经故障。
  3. 每个哨兵每隔2s会向Redis中的指定频道发布其对Master节点的判断,同时每个哨兵会订阅该频道,因此每个哨兵都能知道其他哨兵对Master节点的判断。
  4. 投票,当其中一个哨兵发现Master节点故障后,会查看其他哨兵对Master节点的判断,若超过指定个数个哨兵都认为该节点故障,那么由该哨兵充当哨兵集群的Leader进行故障转移,故障转移的步骤与手动转移的一致。
  5. 选举,挑选其中一个存活的Slave节点断开与Master节点的连接,并使其成为新的Master节点
  6. 然后将其他Slave节点与该新的Master节点建立联系
  7. 最后修改各个节点的redis.conf配置文件,更新主从映射关系

为什么要那么多哨兵组成网络呢?
当只有一个sentinel的时候,如果这个sentinel挂掉了,那么就无法实现自动故障切换了。
在sentinel网络中,只要还有一个sentinel活着,就可以实现故障切换。

客户端怎么知道master变了
客户端不与Redis数据节点打交道,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。

若原master上线
当原Master节点重新上线后,自动转为当前Master节点的从节点。

分片分区

只有一个服务器是master的话,会导致集群的总数据存储量受限,因而如果出现存储空间不足的情况,我们需要用到Redis的分片分区。

在redis3.0之前,我们是通过在客户端去做的分片,通过hash环的方式对key进行分片存储。分片虽然能够解决各个节点的存储压力,但是导致维护成本高、增加、移除节点比较繁琐。

Redis在3.0版本后推出了RedisCluster用于搭建数据分片集群。

使用集群,只需要将redis配置文件中的cluster-enable配置打开即可。
在这里插入图片描述

工作机制
RedisCluster使用虚拟槽的方式进行数据分片,Redis中虚拟槽的范围为0~16383(共16384个槽),每个Master节点负责指定范围的槽以及槽范围内的数据(每个槽与很多Key进行关联,这些Key都在该Master节点的内存中)
在这里插入图片描述

所有Key在进行读取和写入操作时,都需要根据H(K) = CRC16[K] & 16383散列函数计算出Key所坐落的槽,然后找到其对应处理的Master节点,最后自动跳转到该节点进行操作。

特点:

  1. 使用RedisCluster时,Master节点的个数至少需要三个,每个Master可以有任意个Slave节点。
  2. 所有的节点都是一主一从(也可以是一主多从),其中从库不提供服务,仅作为备用
  3. 支持在线增加、删除节点
  4. 客户端可以连接任何一个主节点进行读写

不允许的操作

因为数据将分散到各个节点中,因此有些操作是不允许的

  1. 涉及多个Key的操作,比如mset、sinter等,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为。
  2. 事务不能跨节点。
  3. 不支持多数据库,每个Master节点只能有一个数据库。
  4. 不支持Pipeline(管道)
发布了67 篇原创文章 · 获赞 32 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43751710/article/details/104670498