Redis主从复制
- 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库;
- 从数据库一般都是只读的,并且接收主数据库同步过来的数据;
- 一个master可以拥有多个slave,但是一个slave只能对应一个master;
- slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来;
- master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务;
- master挂了以后,不会在slave节点中重新选一个master。
更改作为从实例的Redis配置文件
replicaof <masterip>\
如主实例Redis设置密码,则更改从实例Redis的配置文件
masterauth <master-password>
-
Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构。下面是关于redis主从复制的一些特点:
1.master可以有多个slave;
2.除了多个slave连到相同的master外,slave也可以连接其他slave形成图状结构;
3.主从复制不会阻塞master。也就是说当一个或多个slave与master进行初次同步数据时,master可以继续处理client发来的请求。相反slave在初次同步数据时则会阻塞不能处理client的请求;
4.主从复制可以用来提高系统的可伸缩性,我们可以用多个slave 专门用于client的读请求,比如sort操作可以使用slave来处理。也可以用来做简单的数据冗余;
5.可以在master禁用数据持久化,只需要注释掉master配置文件中的所有save配置,然后只在slave上配置数据持久化;
6.Redis的键过期机制是由主实例驱动的。也就是说,当主实例中的键到期时,它会向所有的从实例发送一个DEL命令。 -
主从复制的过程:
当设置好slave服务器后,slave会建立和master的连接,然后发送sync命令。无论是第一次同步建立的连接还是连接断开后的重新连接,master都会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存起来。后台进程完成写文件后,master就发送文件给slave,slave将文件保存到磁盘上,然后加载到内存恢复数据库快照到slave上。接着master就会把缓存的命令转发给slave。而且后续master收到的写命令都会通过开始建立的连接发送给slave。从master到slave的同步数据的命令和从 client发送的命令使用相同的协议格式。当master和slave的连接断开时slave可以自动重新建立连接。如果master同时收到多个 slave发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有slave。
-
在Redis的复制机制中存在两种重新同步机制:部分重新同步和完全重新同步。
-
当一个Redis的从实例启动并连接到主实例时,从实例总是会尝试通过发送(mastr_replid,master_repl_offset)请求进行部分重新同步。其中(master_replid,mastr_repl_offset)表示与主实例同步的最后一个快照。如果主实例接受部分重新弄同步,那么它会从从实例停止时的最后一个偏移处开始增量的进行命令同步。否则,则需要进行完全重新同步。当从实例第一次连接到主实例时总是需要进行完全重新同步。在进行完全重新同步时为了将所有的数据复制到从实例中,主实例需要将数据转储到一个RDB文件中,然后将这个文件发送给从实例。从实例接收到RDB文件后,会将内存中的所有数据清除,再将RDB文件中的数据导入。主实例上复制过程是完全异步的,因此并不会阻塞服务器处理客户端的请求。
-
在Redis中使用缓冲区(这个缓冲区称为replication backlog)决定究竟是进行完全重新同步还是部分重新同步。更具体的说,在发出slaveof命令后,从实例使用最后一个offset和最后一个主实例的ID(master_replid)向主实例发送一个部分重新同步请求。当主实例和从实例之间的连接建立后,主实例首先检查请求中的master_replid是否与自己的master_replid一致。然后主实例会检查请求的master_repl_offset是否能从backlog缓冲区中获取。如果offset位于backlog的范围内,那么就可以从中获得连接断开期间的所有写入命令,也就意味着能够进行部分重新同步。否则,如果主实例在连接断开期间接受的写入命令的数量超过了backlog缓冲区的容量,那么部分重新同步请求会被拒绝,此时完全重新同步将会被启动。默认情况下backlog缓冲区的大小是1M。
-
只有在执行重新同步时主从实例之间没有输数据传输,或者在超时时间内主/从实例无法接收PING/REPLCONF ACK时,复制超时才会触发。
Redis哨兵模式
- sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义
- 当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master
- 当master重新启动后,它将不再是master而是做为slave接收新的master的同步数据
- sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群
- 多sentinel配置的时候,sentinel之间也会自动监控
- 当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心
- 一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis
- sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了
- 每个sentinel以每秒一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令
- 如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线。
- 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态
- 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线
- 在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令
- 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次
- 若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;
若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除
- 哨兵模式Sentinel(哨兵)充当了Redis主实例和从实例的守卫者。因为单个哨兵本身也可能失效,所以一个哨兵显然不足以保证高可用。对于主实例进行迁移的决策是基于仲裁系统的。所以至少需要三个哨兵进程才能构成一个健壮的分布式系统来持续地监控Redis主实例的状态。如果有多个哨兵进程检测到主实例下线,其中的一个哨兵进程会被选举出来负责推选一个从实例替代原来的主实例。
哨兵模式配置步骤:(演示1主2从3哨兵演示)
服务类型 | 服务角色 | ip | Port | passwd | 配置文件 | 日志文件 |
---|---|---|---|---|---|---|
Redis | master | 192.168.176.133 | 6379 | redis_133 | ./conf/redis.conf | ./logs/redis.log |
Redis | slave1 | 192.168.176.130 | 6379 | redis_133 | ./conf/redis.conf | ./logs/redis.log |
Redis | slave2 | 192.168.176.128 | 6379 | redis_133 | ./conf/redis.conf | ./logs/redis.log |
Sentinel | sentinel1 | 192.168.176.133 | 26379 | ./conf/sentinel.conf | ./logs/sentinel.log | |
Sentinel | sentinel2 | 192.168.176.130 | 26379 | ./conf/sentinel.conf | ./logs/sentinel.log | |
Sentinel | sentinel3 | 192.168.176.128 | 26379 | ./conf/sentinel.conf | ./logs/sentinel.log |
- 根据上图信息修改Redis相关配置(redis.conf,sentinel.conf);
针对master修改的地方(redis.conf):
- 取消只能本地访问的限制;
- 配置端口(port),6379为默认端口;
- 配置密码(requirepass),默认不需要密码;
- 如果主实例开启密码,则需要配置主实例密码;
- 配置日志文件,如果是后台运行默认输出到/dev/null
- 配置数据目录,默认为当前目录;
- 开启AOF持久化,默认关闭;
- 设置后台启动,默认否;
针对slave修改的地方(redis.conf): - 配置主实例ip,port;
- 如果主实例开启密码,则需要配置主实例密码;
注:如果主实例开启密码验证,则从实例也必须开启密码验证并与主实例的密码一样。
针对sentinel修改的地方(sentinel.conf): - 设置端口,默认26379;
- 设置后台启动,默认否;
- 设置日志文件,如后台运行,则默认输出到/dev/null;
- 配置监控的主实例ip,端口
<quorum>指在采取故障迁移(failover)操作前,发现并同意主实例不可达的最少哨兵数。 - 监控主实例配置密码,则需要配置主实例的密码;