关于Redis的主从复制(上)
在分布式系统中,往往希望有多个服务器来部署redis服务,从而构成一个redis集群。此时就可以让这个集群给整个分布式系统中的其他的服务,提供更稳定/更高效的数据存储功能。
在分布式系统中,希望使用多个服务器来部署redis,存在以下几种redis的部署方式:
1、主从模式
2、主从+哨兵模式
3、集群模式
主从模式
在若干个redis节点中,有的是“主”节点,有的是“从”节点。
假设有三个物理服务器(称为三个节点),分别部署了一个redis-server进程。此时就可以把其中的一个节点,作为“主节点”,另外两个节点作为“从节点”。从节点上的数据要跟随主节点变化,从节点的数据要和主节点保持一致。
本来,在主节点上保存一堆数据,引入从节点之后,就是要把主节点上的数据,复制出来,放到从节点中。后续,主节点这边对于数据有任何修改,都会把这样的修改给同步到从节点上。从节点就是主节点的副本。
Redis的主从模式中,从节点上的数据,不允许修改。只能读取数据。
如果有客户端来读取数据,只需要从上述节点中随机挑一个节点,就可以给客户端提供服务。使用主从模式可以有效提升性能/并发量。
主从模式主要是针对“读操作”进行并发量&可用性的提高。而写操作,无论是可用性还是并发,都是非常依赖主节点,主节点又不能搞多个。
配置主从结构
要想配置成主从结构,就需要使用slaveof,有三种方法:
1、在配置文件中加入slaveof{masterHost}{masterPort} 随Redis启动生成。(推荐,会一直生效)
2、在redis-server启动命令时加入 --slaveof{masterHost}{masterPort} 生效。
3、直接使用redis命令,slaveof{masterHost}{masterPort}生效。
查看当前主从结构的状态:info replication
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=0
master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
断开主从结构: slaveof no one
表示直接使用这个命令断开现有的主从复制关系。当从节点断开主从关系,它就不再属于其他节点了,里面已经有的数据,是不会抛弃的。但是,后续主节点如果针对数据进行修改,从节点就无法再自动同步数据了。
通过 slaveof 命令还可以实现切主操作,将当前从节点的数据源切换到另⼀个主节点。执⾏
slaveof {newMasterIp} {newMasterPort} 命令即可。
安全性:对于数据⽐较重要的节点,主节点会通过设置 requirepass 参数进⾏密码验证,这时所有的客⼾端访问必须使⽤ auth 命令实⾏校验。
只读:默认情况下,从节点使⽤ slave-read-only=yes 配置为只读模式。可以修改,但不建议。
传输延迟:主从节点⼀般部署在不同机器上,复制时的⽹络延迟就成为需要考虑的问题,Redis 为我们提供了 repl-disable-tcp-nodelay 参数⽤于控制是否关闭 TCP_NODELAY,默认为 no,即开启 tcp-nodelay 功能,说明如下:
• 当关闭时,主节点产⽣的命令数据⽆论⼤⼩都会及时地发送给从节点,这样主从之间延迟会变⼩,但增加了⽹络带宽的消耗。适⽤于主从之间的⽹络环境良好的场景,如同机房部署。
• 当开启时,主节点会合并较⼩的 TCP 数据包从⽽节省带宽。默认发送时间间隔取决于 Linux 的内
核,⼀般默认为 40 毫秒。这种配置节省了带宽但增⼤主从之间的延迟。适⽤于主从⽹络环境复杂
的场景,如跨机房部署。
主从复制的拓扑结构
Redis 的复制拓扑结构可以⽀持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:⼀主⼀
从、⼀主多从、树状主从结构。
⼀主⼀从结构:⼀主⼀从结构是最简单的复制拓扑结构,⽤于主节点出现宕机时从节点提供故障转移⽀持。如果写数据请求太多,此时也会给主节点造成压力,可以通过关闭主节点的AOF,只在从节点上开启AOF。但是这种方式有一个缺陷:主节点一旦挂了,不能自动重启(如果自动重启,此时没有AOF文件,就会丢失数据,进一步主从同步,会把从节点的数据也删了)改进方法:当主节点挂了之后,就需要让主节点从从节点这里获取到AOF文件,再启动。
⼀主多从结构:对于读⽐重较⼤的场景,可以把读命令负载均衡到不同的从节点上来分担压⼒。随着从节点的增加,同步一条数据,就需要传输多次。主节点的带宽压力比较大。
树形主从结构:树形主从结构(分层结构)使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主节点继续向下层复制。通过引⼊复制中间层,主节点就不需要那么高的网卡带宽了。但是同步的延迟会比较长。
数据同步
主从复制的基本流程
复制过程⼤致分为 6 个过程:
1)保存主节点信息:先保存主节点的ip和端口。
2)主从建立连接:建立TCP的连接(三次握手)。是在系统层面验证双方是否能正确读写数据。
3)发送ping命令:验证主节点是否能够正常工作。是在应用程序层面验证双方能否正常工作。
4)权限验证:redis主节点开启了密码,从节点将保存的密码发送给主节点,密码匹配才能继续
5、6)同步数据集 & 命令持续复制:全量同步:建立连接的时候,将数据全部传输。增量同步:后续数据变化,数据继续同步。
数据同步
Redis 使⽤ psync 命令完成主从数据同步,同步过程分为:全量复制和部分复制。
redis服务器会在建立好主从同步关系之后,自动执行psync。从节点负责执行psync,从节点从主节点这边拉取数据。psync语法:
PSYNC replicationid offset
replicationid:主节点启动的时候就会生成(或者从节点晋升成主节点的时候)。即使是同一个主节点,每次重启,生成的replicationid也是不同的。从节点和主节点建立了复制关系,就会从主节点获取到replicationid。可用info replication 命令获取到当前replicationid的值。
一般情况下replid2是用不上的,除了以下情况:主节点A生成replid,从节点B获取到A的replid。如果A和B通信过程中出现了一些网络抖动,B可能就会认为A挂了,B就会自己成为主节点(给自己生成一个replid)。此时B还会记得之前旧的replid,就是通过replid2。后续网络稳定了,B还可以根据replid2重新回到A的怀抱。
offset:偏移量。主节点和从节点都会维护偏移量。主节点上会收到很多的修改操作的命令。每个命令都要占据几个字节。主节点会把这些修改命令,每个命令的字节数进行累加。
从节点的偏移量就描述了从节点这里数据同步到哪里了。
replicationid和offset共同描述了一个“数据集合”。如果发现两个机器,replicationid和offset都一样,就可以认为这两个redis机器上存储的数据是完全一样的。