提升Redis性能的关键:深入探讨主从复制

01Redis部署与主从复制

在实际生产环境中,为了确保Redis的高可用性和容错性,通常不会将Redis部署为单机模式,而是会采用多机部署的方式。Redis多机部署的实现方式主要有三种:主从复制、Sentinel和集群。本文将深入探讨主从复制的原理和实现方法。

标题

02主从复制的实现

▣ 旧版复制功能

在旧版Redis(2.8版本之前),复制功能主要包含两个操作:同步和命令传播。同步操作旨在将从服务器的数据库状态与主服务器保持一致,而命令传播则确保主服务器上的写命令能够被从服务器正确执行,从而维持主从数据库的一致性。

当从服务器执行SLAVEOF命令时,会触发同步操作。这个操作包括从服务器向主服务器发送SYNC命令,主服务器在收到该命令后开始执行BGSAVE命令以生成RDB文件。在RDB文件生成过程中,主服务器会将期间的写命令记录在一个缓冲区中。一旦RDB文件生成完毕,主服务器会将其发送给从服务器进行载入,同时还将缓冲区中的写命令发送给从服务器进行重放。这样,从服务器的状态就会与主服务器保持一致,同步操作也就此完成。尽管旧版复制功能在初次复制时表现良好,但当主从服务器因网络问题短暂掉线后重新连接时,它仍会触发完整的复制过程。这种方式虽然能够使主从数据库重新同步,但性能和效率却相对较低。

▣ 新版复制功能

为了提高效率 ,Redis在2.8版本后引入了PSYNC命令来替代原有的SYNC命令进行同步操作。PSYNC命令提供了两种模式:完整重同步部分重同步。在处理初次复制时,完整重同步模式与旧版的SYNC命令相似,主服务器会生成并发送RDB文件及在此期间的写命令给从服务器。

对于掉线后的重复制情况,部分重同步模式则更为高效:当从服务器重新连接主服务器时,如果条件允许,主服务器只需将掉线期间执行的写命令发送给从服务器,即可实现主从数据库状态的重新一致。

▣ PSYNC命令的引入

PSYNC 命令有两种调用方式:如果从服务器之前未复制过任何主服务器,那么在开始新复制时,它会主动发送 PSYNC ? -1 命令,请求进行完整重同步。如果从服务器已复制过主服务器,那么在新复制开始时,它会发送 PSYNCrunid>offset> 命令,其中runid> 和offset> 参数由主服务器使用来确定复制方式。

▣ 部分重同步的实现

部分重同步功能的核心在于三个关键组件:复制偏移量复制积压缓冲区 ,以及服务器运行ID

复制偏移量在执行复制的过程中,主服务器和从服务器各自维护一个复制偏移量。每当主服务器向从服务器传播一定量的数据时,其复制偏移量会相应增加;同样,从服务器在收到数据时也会增加自己的偏移量。如果主从数据库的状态保持一致,那么这两个偏移量应该是相等的。在掉线重连的情况下,由于数据库状态可能已经发生变化,这两个偏移量将不再相等。

复制积压缓冲区:主服务器维护一个固定大小的先进先出(FIFO)队列,即复制积压缓冲区,用于保存最近传播的写命令。这个缓冲区的默认大小为1MB,并且为每个字节都记录了相应的复制偏移量。当从服务器重连后,它会通过PSYNC命令将自己的复制偏移量发送给主服务器。主服务器根据这个偏移量来决定是采用部分重同步还是完整重同步。如果偏移量之后的数据仍然保存在复制积压缓冲区中,那么将采用部分重同步;否则,将采用完整重同步。

服务器运行ID:每个Redis服务器都有一个独特的运行ID,它在服务器启动时生成并由40位随机字符组成。当从服务器进行初次复制时,它会保存对应主服务器的运行ID。这个运行ID在从服务器重连时非常有用,因为它可以帮助确定是否连接的是之前掉线前的主服务器。如果是,则尝试之前的部分重同步;如果不是,则执行完整重同步。

03主要挑战

主从复制虽然在数据备份和性能提升方面发挥了重要作用,但仍然面临一些挑战。当RDB文件过大时,同步过程会变得非常耗时,影响效率。此外,在一主一从或一主多从的架构中,如果主服务器发生故障,整个服务将不可用,单点问题依然存在。通常,手动切换从服务器为主服务器的操作既繁琐又耗时,还可能导致短暂的服务中断。

相关推荐
倔强的石头_1 小时前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
LinXunFeng10 小时前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
DayDaydream15 小时前
7 天涨了 8000+ Star,Agent Reach 想给 AI 装上互联网眼睛
github
天衍四九2 天前
Git从0到实战(四):冲突解决与版本回退 —— 别怕,出错了也能救
github
大刚测试开发实战2 天前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
uhakadotcom3 天前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github
用户3169353811833 天前
Java连接Redis
redis
倔强的石头_3 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
Avan_菜菜3 天前
AI 能写代码了,为什么我反而开始要求它先写文档?
前端·github·ai编程
冬奇Lab3 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm