在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡等需求。
参与复制等Redis实例划分为主节点(master)和从节点(slave)。默认情况下,Redis都是主节点。每个从节点只能有一个主节点,而主节点可以同时具有多个从节点。复制的数据流是单向的,只能由主节点复制到从节点。
(切换主节点会清空之前所有的数据,线上人工操作时小心slaveof在错误的节点上执行或者指向错误的主节点)
主从复制过程:
1)在从节点执行slaveof命令后,保存主节点的地址信息(ip和port)就直接返回;
2)从节点(slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接;
从节点会建立一个socket套接字,专门用于接受主节点发送的复制命令。
如果从节点无法建立连接,定时任务会无限重试直到连接成功或者执行slaveof no one取消复制。
3)发送ping命令;
连接建立成功后从节点发送ping请求进行首次通信,ping请求的主要目的:(1)检测主从之间网络套接字是否可用;(2)检测主节点当前是否可接受处理命令。
如果发送ping命令后,从节点没有收到主节点的pong回复或者超时,比如网络延时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会发起重连。
4)权限验证;
如果主节点设置了requirepass参数,则需要密码验证,从节点必须配置masterauth参数保证与主节点相同的密码才能通过验证。如果验证失败复制将终止,从节点重新发起复制流程。
5)同步数据集;
主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最久的步骤。
6)命令持续复制。
当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地 把写命令发送给从节点,保证主从数据一致性。
主从节点之间维护心跳和偏移量检查机制,保证主从节点通信正常和数据一致。
Redis为了保证高性能,复制过程是异步的,写命令处理完后直接返回给客户端,不等待从节点复制完成。因此从节点数据集会有延迟情况。
当使用从节点用于读写分离时会存在数据延迟、过期数据、从节点可用性等问题,需要根据自身业务提前做出规避。
在运维过程中,主节点存在多个从节点或一台机器上部署大量主节点等情况下,会有复制风暴的风险。