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