Redis主从架构单机redis可以承载几万到上万的QPS。对于缓存,一般用于支持高读并发。因此,将架构做成主从(master-slave)架构,一主多从,master负责写,将数据复制到其他slave节点,slave节点负责读。所有读取请求都转到从属节点。这样可以轻松实现水平扩展,支持高读并发。redis复制->主从架构->读写分离->水平扩展支持读高并发redis复制的核心机制redis采用异步方式向从节点复制数据,但是从redis2.8开始,从节点会定期确认自己每一次复制的数据量;一个主节点可以配置多个从节点;从节点也可以连接到其他从节点;从节点在复制时,不会阻塞主节点的正常工作;从节点在复制时,不会阻止自己的查询操作,会使用旧的数据集提供服务;但是当复制完成后,需要删除旧的数据集,加载新的数据集,此时会暂停对外服务;slave节点主要用于横向扩展和读写分离。扩展的从节点可以提高读取的吞吐量。注意,如果采用主从架构,建议必须开启主节点的持久化。不建议将slave节点作为master节点的数据热备份,因为那样的话,如果关闭master的持久化,master可能会宕机。重启时,数据为空,然后从节点复制后可能数据丢失。另外,还需要做master的各种备份方案。万一本地文件全部丢失,从备份中选择一个rdb恢复master,保证启动时有数据。即使采用后面解释的高可用机制,从节点也可以自动接管主节点。但是也有可能是sentinel没有检测到master故障,master节点会自动重启,仍然可能导致上面的slave节点数据全部被清除。Redis主从复制的核心原理当启动一个从节点时,它会向主节点发送一个PSYNC命令。如果这是从节点第一次连接到主节点,则会触发一次完全重同步全复制。这时master会启动一个后台线程开始生成RDB的快照文件,同时也会把客户端新收到的所有写命令缓存到内存中。RDB文件生成后,master将RDB发送给slave,slave先写入本地磁盘,然后从本地磁盘加载到内存中,master再发送写命令缓存在内存中给slave,slave也会同步这些数据。如果从节点与主节点发生网络故障断开连接,它会自动重连。连接后,主节点只会将丢失的数据复制到从节点。主从复制断点续传从redis2.8开始支持主从复制断点续传。如果主从复制过程中网络连接断开,可以从上次复制的地方继续复制,而不是从头开始复制。主节点将在内存中维护一个积压。master和slave都会保存一个copyoffset和一个masterrunningid,offset保存在backlog中。如果master和slave之间的网络连接断开,slave将允许master从最后一个副本偏移量开始继续复制。如果没有找到相应的偏移量,将执行重新同步。根据host+ip来定位master节点是不靠谱的。如果master节点重启或者数据发生变化,slave节点需要根据不同的runningid来区分。无盘复制master直接在内存中创建RDB,然后发送给slave,这样就不会在本地登陆磁盘。只需在配置文件中启用repl-diskless-syncyes即可。repl-diskless-syncyes#等待5s再开始复制,因为更多的slave要等待重连repl-diskless-sync-delay5过期key处理slave不会让key过期,只会等待master过期钥匙。如果master使一个key过期,或者通过LRU淘汰了一个key,就会模拟一个del命令发送给slave。复制的完整过程从节点启动时,会在本地保存主节点的信息,包括主节点的host和ip,但是复制过程还没有开始。从节点内部有一个定时任务,每秒检查是否有新的主节点连接复制,如果找到,则与主节点建立socket网络连接。然后从节点向主节点发送ping命令。如果master设置了requirepass,那么slave节点必须发送masterauth密码进行认证。主节点第一次执行全量拷贝,将所有数据发送给从节点。后续主节点会继续异步复制写命令给从节点。全量复制master,执行bgsave在本地生成rdb快照文件。主节点将rdb快照文件发送给从节点。如果rdb复制时间超过60秒(repl-timeout),从节点会认为复制失败,可以适当调整这个参数(对于千兆网卡的机器,一般每秒传输100MB,6G文件,可能更多than60s)当主节点生成rdb时,会将所有新的写命令缓存在内存中,从节点保存rdb后,将新的写命令复制到从节点。如果在复制过程中,内存缓冲区连续消耗超过64MB,或者一次超过256MB,则停止复制,复制失败。client-output-buffer-limitslave256MB64MB60slave节点收到rdb后,清除自己的旧数据,然后重新加载rdb到自己的内存中,并基于旧数据版本对外提供服务。如果从节点开启了AOF,会立即执行BGREWRITEAOF重写AOF。增量复制如果在全量复制过程中主从网络连接断开,当slave重新连接到master时会触发增量复制。master直接从自己的backlog中获取一些丢失的数据发送给slave节点。默认积压为1MB。msater根据slave发送的psync中的offset从backlog中获取数据。心跳主从节点会互相发送心跳信息。master默认每10秒发送一次心跳,slave节点每1秒发送一次心跳。异步复制master每次收到写命令后,首先在内部写入数据,然后异步发送给slave节点。redis如何做到高可用如果系统能够在365天内99.99%的时间内对外提供服务,那么就可以说这个系统是高可用的。一个slave挂了,不影响可用性,同一个数据下还有其他slave提供同样的外部查询服务。但是,如果主节点挂掉了怎么办?没办法写入数据,写入缓存时,全部无效。从节点有什么用?没有master给他们复制数据,系统相当于不可用。Redis的高可用架构叫做failover故障转移,也可以叫做主备切换。当主节点出现故障时,它会自动检测并自动切换一个从节点为主节点,称为主备倒换。这个过程在redis的主从架构下实现了高可用。Redis的基于sentinel的高可用,后面会详细介绍。
