决战圣地玛丽乔亚Day45----Redis的主从复制
主从复制:
之前说的RDB和AOF,都是为了帮我们尽快从宕机恢复过来,是宕机之后的处理方式。从根本上,我们应该尽可能的避免宕机的可能性
高可用的三大模式:主从复制,哨兵,集群。
首先是要有主节点和从节点,这个根据业务的需求来判断,主从复制就是从主节点同步数据到从节点。
为了减轻服务器的压力,我们采用读写分离的形式来保证数据的一致性
在主从服务器上读,但是写只在主服务器写,主写了数据后同步到从
1.某节点宕机可以用其余节点保证高可用
2.读写分离,提高性能
3.哨兵、集群的前置条件。
主从复制的实现:
在主从节点的配置文件分别进行配置。
主节点配置文件:
1 2 3 4 5 6 7 8 9 10 | # 启用主节点 slaveof no one # 主节点设置 port 6379 daemonize yes pidfile /var/run/redis_6379.pid logfile "/var/log/redis_6379.log" dir /var/lib/redis/ 6379 bind 0.0 . 0.0 |
从节点配置文件:
# 启用从节点 slaveof 主节点ip 主节点端口号 # 从节点设置 port 6380 daemonize yes pidfile /var/run/redis_6380.pid logfile "/var/log/redis_6380.log" dir /var/lib/redis/6380 bind 0.0.0.0
port 6380
:Redis 实例监听的端口号,Redis 默认端口号为 6379。
daemonize yes
:指定是否将 Redis 实例作为守护进程运行。
pidfile /var/run/redis_6380.pid
:指定 Redis 实例的 PID 文件路径和文件名。
logfile "/var/log/redis_6380.log"
:指定 Redis 实例的日志文件路径和文件名。
dir /var/lib/redis/6380
:指定 Redis 实例的数据文件保存目录。
bind 0.0.0.0
:指定 Redis 实例所绑定的 IP 地址,0.0.0.0 表示绑定所有的可用地址,这意味着 Redis 实例可以从任何 IP 地址访问。
在Redis5.0后,slaveof命令可以用replicaof替代。
主从复制的数据同步过程:
如何去同步数据?一次性穿完还是分批次传输,如果一次性传完对性能消耗会不会很大?如果分批次传输,那么数据会不会存在丢失问题?丢失的数据怎么找回来?
所以主从复制针对不同的情况给出了不同的解决策略:
一、配置完毕后,首次进行数据同步。
准备阶段:
1)建立连接:从库发送psync向主库要两个参数,一个是runID(Redis的实例id)一个是offset(从哪个位置开始复制)
2)主库数据同步给从库:执行bgsave生成RDB文件给从库,从库保存RDB到磁盘,清空Redis内存加载RDB文件。
(主库给每个从库一个缓冲区,记录RDB后产生的写命令,这样主库不需要阻塞的进行RDB)
3)发送新的写命令给从库:继续执行从缓存区发过来的数据,避免数据断层
二、运行期间的准实时同步(长链接+增量复制)
保持主从长链接:
完成第一次RDB之后,主从之间通过长链接保持数据通信。
主-->从(PING):
主通过Ping去检测从的健康状态(时间间隔自定义,默认1min)。
从-->主(REPLCONFIG ACK):
从以每秒1次频率给主发送REPLCONFIG ACK。 把复制偏移量发送给主
1 | REPLCONF ACK <replication_offset> |
这条命令的作用:
1.检测主从服务器的网络通路是否正常。
2.辅助实现 min-slaves 选项,使用Redis的 min-slaves-to-write(少于n个从实例时,拒绝执行写命令) 和 min-slaves-max-lag(主从延迟大于等于n秒时,拒绝执行写命令)两个选项可以防止主服务器在不安全的情况下执行写命令。
3.检测命令丢失, 从节点发送了 slave_replication_offset,主节点会对比 master_replication_offset ,如果不一致,说明从节点数据缺失,主节点会从 repl_backlog_buffer缓冲区中找到并推送缺失的数据。
网络断开或从库重启等,只将中断期间主节点执行的写命令发送给从节点,更高效。
master_repl_offset: master写入的偏移量
slave_repl_offset: slave读数据的偏移量
左图:正常同步状态
右图:主从断连,主库写的比从读的快,有数据断层
repl_backlog_buffer也是有内存大小限制,满了从初始位置开始覆盖。
增量复制的流程:
和全量一样,从要先和主建立联系。 从发送psync给主,同时高速主自己的runid和slave_repl_offset,主看只需要把断开这一期间的数据,即slave_repl_offset~master_repl_offset的数据发送给从即可
repl_backlog的大小要合理:太大太小都不行。太小会被覆盖掉,太大不如RDB。
公式:size = seconds * write_size_per_second +(预留)
从断开到连接需要的时间 * 这段时间内每秒写数据大小
主服务器如何分辨什么时候全量复制,什么时候增量复制?
根据从发送的psync:
如果是初始化,从发送psync -1给主,主全量复制
如果非初始化,执行官aof,发送psync带两个参数 runId(主id)和offset(复制偏移量)
如果主runid和从发送的runid一致,且slave_repl_offset之后数据没有丢失(因为backlog环形,可能被覆盖或者等待时间长导致断连等等),则通过增量复制同步。
如果主的runid和从发送的runid不一致:或者从发送的psync参数的offset偏移量在主的backlog缓存中找不到了,则主发送fullresync<runid><offset>,重新进行全量复制。同时把主的runid和offset重新发给从
一主多从:
replication buffer:主从进行RDB时,为了方便主从同步产生的一个缓存。
repl_backlog:为了AOF存在,主把自己的操作信息放入,所有需要AOF的从进行共享。
他们的区别是什么:
replication buffer是主节点将待复制数据发送到从节点的缓冲区,它的大小是由repl-backlog-size
配置项决定的,主节点会将待复制数据写入该缓冲区,然后异步地发送给从节点。当从节点与主节点断开连接或者从节点复制数据太慢时,replication buffer会在一定程度上缓解主从复制过程中的数据传输压力。
repl_backlog是主节点用于记录从节点丢失的数据的环形缓冲区。在主从复制的过程中,主节点会将待复制数据写入repl_backlog缓冲区,并在发送给从节点后逐步地从缓冲区中删除。当从节点断开连接后,主节点会将repl_backlog缓冲区中的数据发送给从节点,以保证从节点数据的完整性。repl_backlog的大小由repl-backlog-size
和repl-backlog-ttl
两个配置项决定,前者是缓冲区的大小,后者是缓冲区中数据的最大保存时间。
因此,replication buffer和repl_backlog在Redis主从复制中扮演不同的角色。replication buffer是主节点用于缓存待复制的数据,而repl_backlog则是用于保证从节点数据的完整性。
主从复制是比较低级的的可用性优化,也是后面哨兵和集群的基础。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY