天天看点

Redis 集群、哨兵、主从同步

目录

      • redis集群简介
      • 搭建redis集群
      • redis集群原理
        • 哨兵(Sentinel)机制
        • 客户端请求处理流程
        • 故障迁移 failover
        • 晋升机制 | 选举机制
        • 集群不可用
      • 主从同步
        • 主从同步的作用
        • redis常见的主从结构
        • redis的主从同步机制
        • 注意点

redis集群简介

单机版redis server,redis server容量受单机内存限制,往往需要redis server集群来扩容,提升redis数据库的容量。

redis 5.0之前通过执行redis-trib.rb创建redis集群,redis-trib.rb是ruby语言写的脚本,需要配置ruby环境,还需要安装redis.gem来管理集群。redis 5.0开始用redis-cli代替redis-trib.rb,虽然redis-trib.rb现在还能用(向下兼容),但后续会被取消掉,建议使用redis-cli来创建集群。

此处以redis 5.x为例创建redis集群。

# 查看redis server版本
./redis-server -v
./redis-server --version
           

搭建redis集群

1、redis集群至少要3个master,且每个master至少要有一个slave,所以最少要6个节点

如果节点数量不满足要求,后续会报错

Redis 集群、哨兵、主从同步

2、编辑所有集群节点的redis.conf,允许集群

Redis 集群、哨兵、主从同步

参加集群的所有节点都不能是slave,如果配置了replicaof,将其注释掉。

哪些节点作为master、哪些节点作为slave,由集群自动分配,不能手动设置。

3、参与集群的节点,数据库必须是空的,如果有.rdb、.aof等数据库文件,需先删除

如果集群搭建失败,重试时需要先删除之前生成的数据库文件(.rdb、.aof)。如果数据库不为空,后续会报错

Redis 集群、哨兵、主从同步

4、先启动参与集群的每个redis server,再使用某个redis-cli创建集群

指定参加集群的节点(ip、port),参数cluster-replicas指定每个master分配几个slave。自动分配时,一般是前面的节点都作为master,后面的都作为slave。

会给出集群配置方案。(图是以前我在本地模拟时截的,所以ip都是127.0.0.1,只修改了端口。)

Redis 集群、哨兵、主从同步

M是master,S是slave,slot(槽点)是用来执行写指令的,只分配给master,各个master的槽点数差不多。slave只是作为备份,不执行写指令,不分配槽点。

输入yes按方案执行

5、连接到集群中的某个节点即可连接到整个redis集群,查看集群信息

# 连接到集群时,不管是连接到master还是slave,都要加-c,c即cluster
redis1/bin/redis-cli -h 192.168.1.1 -p 6379 -c  

# 查看集群信息
cluster info
           
Redis 集群、哨兵、主从同步

集群状态、槽点数、节点数都可以看到,其中集群大小cluster_size只算master。

# 查看当前连接到的节点的主从信息
info replication
           
Redis 集群、哨兵、主从同步

可以看到当前节点的角色,如果是master会显示其从节点的信息,如果是slave会显示如果其master的信息。此外还能看到数据同步的偏移量。

设置值、取值

Redis 集群、哨兵、主从同步

先根据key的哈希值确定槽点位置,自动转到该槽点所在的节点,然后在该槽点处设置值、取值。

redis集群原理

Redis Cluster 是一种redis服务器的Sharding技术,集成了主从复制和哨兵 功能,提供了redis的高可用支持。

redis集群是把数据分散存储在多个master上,这些master共同组成一个完整的redis数据库,每个master上只存储部分key,也叫作分片。每个master都可以处理请求,slave只用于所属master的数据备份,不处理请求。整个redis集群共有16384个槽点(hash slot)。

redis集群的优势

  • 提高扩展性,可增加master节点数量,以分散存储压力
  • 提高可用性,master故障时,可自动切换到对应的slave节点

哨兵(Sentinel)机制

哨兵是redis server附带的程序,每个redis server(master、slave)都自带得有,默认未配置哨兵。redis server默认使用6379,哨兵默认使用26379。

创建redis集群时,会自动给每个节点配置哨兵,用于监控集群中各个节点(master+slave)的状态。每个节点(master+slave)上都有一个节点信息文件记录集群各节点的信息

Redis 集群、哨兵、主从同步

包括各个节点的ip、port,角色(master、slave),是集群中的第几个节点,和当前节点之间是否能ping通(是否connected)。如果是master,还包括槽点区间。

Sentinel的主要功能

  • 集群监控:监控master、slave节点是否正常工作
  • 消息通知:redis节点故障时,哨兵负责发送警告消息通知管理员
  • 故障迁移:master故障时自动迁移到slave上
  • 配置中心:发生故障转移时,通知refis客户端新的master地址

客户端请求处理流程

redis客户端可以向redis集群的任意一个节点发送请求,节点接收到请求后会对其进行解析,先根据key的hash值确定槽点位置,再根据节点信息文件确定该槽点所在节点(ip、port),转发给该节点进行处理。

redis.conf

Redis 集群、哨兵、主从同步

第一个配置是节点信息文件的保存路径,默认保存路径是数据存储目录(.aof、.rdb所在目录)下的nodes.conf文件。

创建集群时会往每个节点的nodes.conf中写入集群初始配置,集群创建后,每个节点的哨兵每秒都会ping一下其它节点,确定其它节点的状态,来维护|更新节点信息文件。

第二个配置指定超时时间,默认15000ms,即15s。如果哨兵在15s内都没有ping通某个节点,就主观认为该节点down掉了,将该节点的状态标识为sdown,s即subjectively 主观。

如果超过一半的master都将某个master的状态标识为sdown,就认为客观上该master节点确实down掉了,将该master节点的状态标识为odown,o即objectively ,客观。哨兵会自动将从该master的所有slave中选一个新的master。注意是哨兵确定新的master,不是由其它master确定。

故障迁移 failover

故障迁移是指:master故障,sentinel从附属slave中选出新master,其它附属slave从新master同步数据的过程。具体过程如下

  • try-failover  master的状态被标识odown,集群尝试进行故障转移
  • elected-leader  从该master的附属slave中选出新master
  • selected-slave  已选出新的master
  • send-slaveof-noone  向新master发送slaveof no one命令,摆脱slave地位
  • wait-promotion  等待新master完成配置更新,晋升为master。配置更新有2个方面:一是去掉replicaof配置摆脱slave角色,二是继承原master的槽点、得到写权限(slave默认只读)
  • promoted  晋升完成
  • 其它附属slave从新master同步全量数据

故障迁移期间,整个redis集群不对外提供服务。redis集群和zk集群很相似,数据一致性强,但可用性得不到保证。

晋升机制 | 选举机制

redis.conf

Redis 集群、哨兵、主从同步

优先级有3个值:10,25,100,默认100,数值越小,优先级越高。

master选举算法

  • 选择优先级高的(数值小的)
  • 如果优先级相同,选择主从复制偏移量offset靠后的,偏移量越靠后,数据越新;
  • 如果便宜量相同,选择 run id 小的。

集群不可用

以下2种情况都会使redis集群不可用(集群状态为fail)

  • 某个master节点及其所有slave节点都down掉
  • master节点短时间内down掉一半以上,不管有没有代替的slave,整个集群直接不可用

主从同步

创建redis集群时会自动设置哨兵、主从关系,slave会自动从master同步数据,sentinel 的多实例部署保证了sentinel 本身的可用性,slave+sentinel保证了redis集群的高可用。

sentinel虽然提高了redis集群的可用性,但又是master又是slave又是sentinel,增加了redis集群的复杂性,部署、扩容麻烦。

主从同步的作用

  • 数据冗余(备份)
  • 提高可用性:master故障,可将某个slave作为新的master

至于读写分离,用master处理写请求(、读请求),slave处理读请求,这对redis来说没必要。

读写分离主要有2个作用:减轻master读写压力,提高整体负载;提高性能。

关系数据库读写数据要进行文件IO,耗时、性能差,需要读写分离提高性能;redis本身是内存数据库,性能极高,不需要读写分离来提高性能。

关系数据库集群通常是一主多从,需要从库分担读请求的压力,redis集群本身就有多个master,通过多个master来分担读写压力、存储压力,不需要slave来分担。

因此redis集群一般不做读写分离,没必要,slave只作数据备份,读写请求都由master处理。

redis常见的主从结构

Redis 集群、哨兵、主从同步

如果slave太多,都从master同步数据,master IO压力会很大,此时可以使用第三种层级结构,从其它slave同步数据。

redis的主从同步机制

master节点之间存储不同的数据,同步指的是主从节点之间的同步。

redis的同步机制如下

  • 主从刚连接时做全量同步,后续做增量同步
  • 如果尝试增量同步时失败,则进行全量同步
  • 如果有需要,slave随时可以发起全量同步
  • 同步过程中出现网络问题时会自动重连,重连之后会自动补上缺少的数据
  • 主从同步默认采用异步复制方式,不会阻塞master,master在主从复制时仍可以处理客户端请求

全量同步

  • slave发送sync命令给master
  • master执行bgsave命令,启动一个后台进程,将内存中的全量数据同步到rdb文件中,并将此后执行的写指令记录到缓冲区中
  • master完成bgsave命令后,将rdb文件发送给slave
  • slave使用新接收到的rdb文件替换旧的rdb文件,重新载入数据
  • master发送rdb文件完毕后继续向slave发送缓冲区中的写指令
  • slave接收并执行master发送的缓存区中的写命令

增量同步

  • master接收并执行写指令
  • 将写指令记录到aof文件中,并将写指令发送给slave执行

注意点

  • 如果master压力很大,这时候增加slave数量会加大master的IO压力,尽量不要先增加slave数量,先增加master节点数量以分散现有master的压力。
  • slave启动后会立刻发送sync命令与master进行全量同步,如果多个slave同时进行重启,可能导致master IO压力骤增甚至宕机。
  • slave和master尽量在同一个局域网内,以保证网络的稳定性、网络传输的速度

继续阅读