0
点赞
收藏
分享

微信扫一扫

linux驱动开发面试题

菜头粿子园 03-26 20:00 阅读 2

接上次博客:Redis(四):持久化和事务:RDB(定期备份)【触发机制、流程说明、文件的处理、优缺点】、AOF(实时备份)【使用AOF、命令写入、文件同步、重写机制、启动时数据恢复】、Redis 事务【操作】-CSDN博客

目录

主从模式介绍

配置

建立复制

断开复制

安全性

只读

传输延迟

拓扑

一主一从结构

一主多从结构

树形主从结构

原理

复制过程

数据同步 psync

replicationid/replid (复制id)

offset (偏移量)

全量复制

replication id 和 run id 的辨别

部分复制

复制积压缓冲区​​​​​​​

实时复制

划分工作目录

总结

主从复制解决的问题

主从复制的特点

主从复制的优缺点


分布式系统中的单点问题是一个至关重要的挑战。传统的单节点服务器部署存在着诸多限制,主要包括可用性问题和性能瓶颈。

首先,单点故障会导致服务不可用。如果某个服务器发生故障,整个服务就会中断,给用户和系统带来不便和损失。这种单一点的脆弱性是需要尽量避免的。

其次,单节点的性能和并发能力有限。服务器资源的局限性限制了服务的扩展性和处理能力,难以应对高并发和大规模数据的挑战。这可能导致服务的响应变慢甚至崩溃。

为了解决这些问题,引入分布式系统是必要的。在分布式系统中,常见的做法是利用多个服务器来部署 Redis 服务,从而构成一个 Redis 集群,为分布式系统提供更稳定、更高效的数据存储服务,从而解决了单点问题带来的挑战,为系统的可靠性和性能提升提供了重要支持。

在分布式系统中,部署 Redis 有几种常见的方式,包括:

  1. 主从模式(Master-Slave): 主从模式是最简单的部署方式之一。在这种模式下,一个 Redis 主节点(Master)负责处理写操作和读操作,而一个或多个 Redis 从节点(Slave)则复制主节点的数据,并且只负责处理读操作。主节点负责处理所有写操作,并将写操作同步到所有从节点。主从模式提高了读取性能和可用性,但写入性能仍受限于主节点。

  2. 主从+哨兵模式(Master-Slave with Sentinel): 主从+哨兵模式在主从模式的基础上增加了哨兵(Sentinel)节点的部署。哨兵节点负责监控主节点和从节点的健康状态,并在主节点不可用时自动将一个从节点晋升为新的主节点,以保证系统的高可用性。这种方式可以自动处理主节点的故障转移,提高了系统的可靠性。

  3. 集群模式(Cluster): 集群模式是用于横向扩展 Redis 的方式之一。在集群模式中,数据被分片存储到多个节点上,每个节点负责存储部分数据片段。集群模式提供了更好的水平扩展性和负载均衡能力,可以处理大规模数据和高并发请求。此外,集群模式还具备数据自动重分布和故障转移等特性,以保证数据的高可用性和一致性。

选择适合的部署方式取决于具体的业务需求和系统规模。主从模式适合简单的读写分离场景,主从+哨兵模式适用于需要自动故障转移和高可用性的场景,而集群模式则适用于大规模数据和高并发请求的场景。

接下来我们先来探讨主从模式。

在分布式系统中,为了提高系统的可用性和容错性,常常会采用数据复制的策略,将数据的多个副本部署到不同的服务器上,以实现故障恢复和负载均衡等需求。Redis 也支持数据复制功能,允许我们创建相同数据的多个 Redis 副本。复制功能是构建高可用 Redis 的基础,Redis Sentinel 和 Redis Cluster 都是基于复制功能实现的。接下来的内容主要包括以下几个方面:

  1. 复制的使用方式: 介绍如何建立或断开复制关系,复制过程中的安全性控制以及只读副本的使用方法等。

  2. 支持的复制拓扑结构: 说明复制功能支持的不同拓扑结构,包括主从复制、主主复制等,以及每种拓扑结构适用的场景和特点。

  3. 复制原理分析: 对复制过程中涉及的关键原理进行分析,包括建立复制关系的流程、全量复制和增量复制的区别、心跳检测机制等。具体内容包括:

    • 建立复制关系:介绍主从节点之间建立复制关系的过程,包括从节点发起复制请求、主节点生成复制数据、从节点进行数据同步等步骤。
    • 全量复制:解释全量复制的概念和过程,即从节点在初始阶段需要获取主节点的全部数据。
    • 部分复制:说明部分复制的情况,即在全量复制之后,从节点只需要获取主节点更新的部分数据。
    • 心跳检测:介绍心跳检测机制,即主节点和从节点之间定期发送心跳消息,以检测节点的存活状态,并及时处理异常情况。

通过对复制功能的介绍和原理分析,我们可以更好地理解 Redis 复制的工作机制,从而更好地配置和管理 Redis 集群,保障系统的高可用性和稳定性。

主从模式介绍

主从模式是一种常见的 Redis 部署方式,主要用于优化读操作的并发处理能力和提高系统的可用性。在这种模式下,主节点负责存储数据并处理所有的写操作,而从节点则作为主节点的副本,负责复制主节点上的数据并处理读操作。从节点的数据与主节点保持同步,确保数据一致性。主从模式的优势在于有效提升了读操作的性能和系统的可用性,但需要注意的是,从节点上的数据只允许进行读取操作,不允许进行写入操作。

在主从模式下,从节点的数据与主节点保持一致,因此无论是从主节点还是从节点读取数据,在数据内容上没有区别。这使得客户端可以从任意一个节点读取数据,而不必局限于主节点。

通过允许客户端从任何节点读取数据,可以实现负载均衡,从而提高系统的并发处理能力。当有多个客户端需要读取数据时,可以随机选择一个可用节点来为客户端提供服务,有效地分散了负载,提高了系统的整体性能和可伸缩性。

同时,这种方式引入了更多的计算资源,即从节点,可以进一步增强系统的并发处理能力。每个节点都能够独立地响应客户端的请求,从而提高了系统的处理能力,使其能够支持更多的并发访问。因此,主从模式的部署可以通过引入从节点来增加计算资源,从而有效地提高系统的并发量。

那么如果为了避免主节点崩溃而引入多个主节点呢?

如果引入了多个主节点,即存在多个主节点的情况,数据同步会变得复杂,因为主节点之间需要进行数据同步,这可能会带来一些问题和挑战:

  1. 数据一致性问题: 多个主节点之间需要保持数据一致性,即确保它们存储的数据是相同的。数据同步可能会引入延迟或者数据丢失的风险,导致节点之间的数据不一致。

  2. 冲突解决: 当多个主节点同时对同一数据进行写入时,可能会发生数据冲突。解决数据冲突需要一套有效的冲突解决策略,以确保数据的一致性和正确性。

  3. 网络通信成本: 数据同步需要通过网络进行数据传输,可能会引入额外的网络通信成本和延迟,尤其是在跨地域或者跨网络的情况下。

  4. 复杂性增加: 引入多个主节点会增加系统的复杂性,需要更多的配置和管理工作。此外,更多的节点也意味着更多的故障可能性,需要更强大的监控和管理机制。

综上,通过从节点提供读取数据的服务,可以有效分担主节点的负载,提高系统的整体性能。当从节点出现故障时,对系统的影响相对较小,因为其他从节点或主节点仍然可以提供服务。然而,如果主节点出现故障,将会影响系统的写入能力,因为从节点无法执行写操作。但是不用太过担心,因为在实际业务场景中,读操作通常比写操作更频繁,因此主从模式适用于这类读多写少的场景,这一点可以减轻对写入能力的担忧。

你可能还有疑问,分布式系统确实降低了因为节点崩溃而造成损失的可能性,但是如果我们一整个机房都毁了呢?

所以我们可以考虑将 Redis 服务器部署在多个不同的机房中,实现异地多活。这样即使一个机房发生故障,其他机房仍然可以继续提供服务,从而确保系统的高可用性。这种部署方式虽然可以增加一定的成本和复杂性,但对于对可用性要求较高的系统来说是非常值得的。

配置

配置 Redis 主从结构时,首先需要启动多个 Redis 服务器实例。通常情况下,每个 Redis 服务器应该在不同的主机上以实现分布式架构。然而,在当前情况下,考虑到大家应该只拥有一个云服务器,我们可以选择在同一个云服务器主机上运行多个 Redis 服务器进程。

在启动多个 Redis 服务器实例时,需要确保每个实例使用不同的端口号,以避免端口冲突。通常情况下,Redis 服务器的默认端口号是 6379,但在这种情况下,我们需要确保新启动的 Redis 服务器实例不使用 6379 端口。

要指定 Redis 服务器的端口号,有两种常见的方法:

  1. 通过命令行选项指定端口号:在启动 Redis 服务器时,可以使用 --port 选项来指定端口号。例如,可以通过以下命令启动一个 Redis 服务器,并将其端口号设置为 6380:

    redis-server --port 6380
    
  2. 通过配置文件设定端口号:另一种常见的方法是通过修改 Redis 的配置文件来设定端口号。可以编辑 Redis 的配置文件 redis.conf,找到并修改 port 参数为所需的端口号。例如,将端口号设置为 6380:

    port 6380
    

    然后,可以使用以下命令启动 Redis 服务器,并指定配置文件路径:

    redis-server /path/to/redis.conf
    

    注意:无论使用哪种方法,都要确保每个 Redis 服务器实例使用的端口号是唯一的,以确保系统的正常运行。

建立复制

在 Redis 复制机制中,参与复制的 Redis 实例被划分为两种角色:主节点(master)和从节点(slave)。每个从节点只能有一个主节点,而一个主节点可以同时拥有多个从节点。

在进行下一步操作之前,首先需要执行以下步骤:

  1. 复制 redis.conf 配置文件两份,分别命名为 slave1.conf 和 slave1.conf。



    我们打算创建一个主节点、两个从节点。主节点的配置不需要修改,只需要修改从节点的配置,也就是我们刚刚复制好的两份配置文件。
  2. 修改 slave1.conf 和 slave2.conf 中的端口号为6380和6381,然后确保daemonize 参数为 yes。
    ​​​​​​​





    按照后台进程的方式运行:



然后,我们要确保启动了主 Redis 实例。如果已经启动了主 Redis,我们不需要对其进行任何修改。

接下来,我们通过命令行启动一个 Redis 实例作为从 Redis。在启动从 Redis 实例之前,需要确保修改了 redis-slave.conf 中的配置项,以确保它连接到正确的主节点,并且端口不与主节点冲突。

接下来的步骤是:

  1. 通过 netstat -nlpt 命令确保两个 Redis 实例已经正确启动,并且监听了相应的端口。
  2. 使用 redis-cli 连接主 Redis 实例,确认连接正常。
  3. 使用 redis-cli -p 6380 连接从 Redis 实例,确认连接正常。
  4. 观察复制关系,可以通过 INFO replication 命令来查看从节点的复制状态。确保从节点正确地复制了主节点的数据。

通过以上步骤,我们可以验证复制关系已经建立成功,并且主节点对数据的修改可以同步到从节点中。这样就实现了 Redis 的主从复制功能。

但是此时这几个节点并没有构成主从结构,而是各自为政:

 、

可以看出来,选择两个客户端之间的数据没有共享。

要想成为主从结构,还需要进一步的配置:

 数据流是单向的,即只能由主节点向从节点传输数据。配置复制的方式有以下三种:

  1. 配置文件方式: 切到配置文件最末尾,在 Redis 的配置文件中添加如下配置:

    slaveof {masterHost} {masterPort}

    这样配置后,当 Redis 服务器启动时,会自动将该实例配置为从节点,并连接到指定的主节点,开始复制数据。

  2. 命令行参数方式: 在启动 Redis 服务器时,通过命令行参数指定主节点的地址和端口:

    redis-server --slaveof {masterHost} {masterPort}

    使用这个命令启动 Redis 服务器后,该实例将作为从节点运行,并复制指定主节点的数据。

  3. Redis 命令方式: 在 Redis 客户端中直接使用以下命令进行配置:

    slaveof {masterHost} {masterPort}

    通过在 Redis 客户端中执行这个命令,可以将当前 Redis 实例配置为从节点,并开始复制指定主节点的数据。

无论是哪种方式,一旦配置成功,从节点将会与主节点建立连接,并开始复制主节点的数据。这些配置方式为用户提供了灵活的选择,可以根据实际情况和需求来选择最适合的方式进行配置。

但是我们还是建议采用修改配置文件的方式,因为修改配置文件以解决问题是更为可靠和持久的解决方案。

修改完配置文件,一定要记得重启!!!

注意,ki11 -9 这种停止 redis-server 的方式,是与之前直接运行 redis-server 命令启动的方式相对应的。如果使用 service redis-server start 这种方式启动了 Redis 服务器,那么通常最好使用 service redis-server stop 命令来停止它。

需要注意的是,如果使用 kill -9 命令强制终止了 Redis 服务器进程,Redis 将无法执行正常的清理和关闭操作,也不会在下次系统启动时自动重新启动。因此,如果希望在进程终止后自动重启 Redis 服务器,我们应该使用正常的服务管理命令来停止它。

使用 service redis-server stop 命令将以正常的方式终止 Redis 服务器,并处理相关的清理工作,包括释放占用的资源和关闭连接。这样可以确保服务器的数据安全和服务的稳定性。

此时再次运行redis客户端:

 

从节点无法进行写入操作: 

 

Redis 主从节点复制过程:

当使用 Redis 命令行客户端连接到 Redis 服务器后,可以通过 INFO replication 命令来查看复制相关的状态信息。

下面分别是主节点 6379 和从节点 6380 的复制状态信息:

1)主节点 6379 复制状态信息:

根据提供的信息,我们可以得出以下分析:

  1. Role: Redis 的角色是主服务器 (master),这意味着这个 Redis 实例充当了主节点的角色。

  2. Connected Slaves: 有两个从节点(connected_slaves:2),它们分别是端口号为6380和6381的从节点。这表示该主节点与两个从节点建立了连接。

  3. Slave0和Slave1: 两个从节点的信息如下:

    • Slave0: IP地址为127.0.0.1,端口号为6380,状态为在线(state=online),当前复制偏移量为734,滞后(lag)为1。
    • Slave1: IP地址为127.0.0.1,端口号为6381,状态为在线(state=online),当前复制偏移量为734,滞后(lag)为1。
  4. Master Replid和Master Repl Offset: 主节点的复制ID为291f44989b8b324ec5d26f7f4decbb0c72319367,当前复制偏移量为734。这些信息用于从节点与主节点进行复制同步。

    在Redis中,偏移量(offset)表示从节点在主节点上复制数据的进度。主节点持续地接收写入操作,并将这些修改同步到连接的从节点。从节点需要不断地从主节点获取新的修改,并将其应用到本地数据集上。因此,偏移量可以看作是从节点和主节点之间数据同步的进度指示器,表示从节点已经复制了主节点的数据到哪个位置。随着数据的不断写入,从节点的偏移量也会不断增加,直到它与主节点的数据完全一致

    lag 表示从节点落后于主节点的数据复制延迟。当主节点接收到写入操作时,它会将这些操作同步到连接的从节点。lag 值表示从节点当前的复制偏移与主节点的复制偏移之间的差异,这个差异代表了从节点的复制延迟。lag 值越大,表示从节点与主节点之间的数据同步越滞后,即复制延迟越严重。

    通常情况下,从节点的 lag 值应该保持在一个较低的水平,以确保数据同步的及时性和准确性。如果 lag 值持续增长,可能会导致从节点无法及时获取主节点的最新数据,从而影响系统的实时性和数据一致性。因此,在分布式系统中,及时监控 lag 值并采取必要的措施来降低复制延迟是非常重要的。

  5. Repl Backlog相关参数:

    • Repl Backlog Active: 复制后备日志是激活的,表示主节点正在使用后备日志缓冲区来保存复制期间产生的数据。
    • Repl Backlog Size: 后备日志缓冲区的大小为1048576字节(即1MB)。
    • Repl Backlog First Byte Offset: 后备日志缓冲区的第一个字节的偏移量为1。
    • Repl Backlog Histlen: 后备日志缓冲区历史长度为734,表示主节点和从节点之间的同步历史记录了734个字节。

综上所述,该 Redis 主节点正常运行,并且已经成功与两个从节点建立了连接,复制同步也在进行中。

2)从节点 6380 复制状态信息: 

根据提供的信息,我们可以得出以下分析:

  1. Role: Redis 的角色是从服务器 (slave),这意味着这个 Redis 实例充当了从节点的角色。

  2. Master Host和Master Port: 该从节点的主节点是位于127.0.0.1地址,端口号为6379的主节点。

  3. Master Link Status: 主节点的连接状态为正常(master_link_status:up),表示从节点与主节点之间的连接处于可用状态。

  4. Master Last IO Seconds Ago: 从节点最近一次与主节点进行IO操作的时间为0秒,即最近一次通信是在当前时间内完成的。

  5. Master Sync in Progress: 从节点当前没有进行同步操作(master_sync_in_progress:0),说明它与主节点的数据已经同步完成。

  6. Slave Repl Offset: 从节点当前的复制偏移量为776,表示从节点已经成功复制了主节点的数据,且复制偏移量为776。

  7. Slave Priority和Slave Read Only: 从节点的优先级为100(slave_priority:100),并且只读模式已启用(slave_read_only:1)。

  8. Connected Slaves: 从节点当前没有连接其他从节点(connected_slaves:0),说明该节点没有其他从节点连接到它。

  9. Master Replid和Master Repl Offset: 主节点的复制ID和复制偏移量与上一个示例中相同,表示主节点的信息保持一致。

  10. Repl Backlog相关参数: 同上一个示例中相同,后备日志缓冲区已激活,大小为1MB,历史长度为776字节。

综上所述,该 Redis 从节点已经成功连接到主节点,并且已经完成了数据同步,正处于与主节点同步数据的状态。

这些具体的信息其实不需要全部记得,可以从官网上进行查阅,里面对每个属性都进行了详细的解释说明:INFO | Redis

通过查看这些复制状态信息,我们可以了解主从节点之间的复制关系、复制延迟等信息,以及判断复制是否正常工作。

断开复制

在 Redis 中,slaveof 命令不仅可以用于建立复制关系,还可以在从节点上执行 slaveof no one 命令(不需要配置在配置文件中,而是直接在redis客户端输出)来断开与主节点的复制关系。

下面是断开复制和切换主节点的主要流程:

断开复制的主要流程:

  1. 断开与主节点的复制关系:从节点执行 slaveof no one 命令,通知 Redis 服务器断开与主节点的连接。

  2. 从节点晋升为主节点:断开复制后,从节点将成为独立的主节点,不再受主节点控制。

需要注意的是,从节点断开复制后并不会丢弃原有数据,它仍然保留着原来从主节点同步过来的数据,但是无法再获取主节点上的数据变化。

通过 slaveof 命令还可以实现切主操作,将当前从节点的数据源切换到另⼀个主节点。 

切换主节点的主要流程:

  1. 断开与旧主节点的复制关系:从节点执行 slaveof no one 命令,断开与当前主节点的连接。

  2. 与新主节点建立复制关系:从节点执行 slaveof {newMasterIp} {newMasterPort} 命令,与新的主节点建立复制关系。

  3. 删除从节点当前所有数据:为了避免数据混乱,从节点在切换主节点时需要清空当前数据,以确保从新主节点同步到的数据是最新的。

  4. 从新主节点进行复制操作:建立了新的复制关系后,从节点会开始从新主节点同步数据,以保持与新主节点的数据一致性。

 

此时数据同步过程就是由6379同步给6380,然后6380再同步给6381。

最后,需要注意的是,slaveof 命令是用于临时性地修改 Redis 主从结构的,但是这种修改只在当前运行时有效,不会永久改变配置。一旦 Redis 服务器重启,就会按照配置文件中指定的方式重新建立主从结构。因此,如果需要永久修改主从结构,应该在配置文件中进行设置,而不是依赖于临时性的命令修改。

通过上述步骤,我们可以实现在 Redis 中对主从节点进行复制关系的动态管理,包括断开复制关系、晋升为独立主节点、切换主节点等操作。这些功能使得 Redis 集群在面对变化的情况下能够灵活地调整复制关系,以保证系统的可用性和稳定性。

安全性

在 Redis 中,对于数据比较重要的节点,例如主节点,可以通过设置 requirepass 参数来进行密码验证。这意味着所有的客户端连接到该节点时都必须提供密码,并通过验证后才能执行操作。客户端需要使用 AUTH 命令来进行密码校验。

在主从复制场景中,从节点需要连接到主节点进行数据复制。为了保证连接的安全性,从节点需要配置 masterauth 参数,该参数的值应该与主节点的密码保持一致。这样,从节点才能通过提供正确的密码来与主节点建立连接,并启动复制流程。

通过配置主节点的密码验证和从节点的 masterauth 参数,可以有效地提高 Redis 节点的安全性。这样可以确保只有经过授权的客户端才能访问和操作 Redis 数据库,从而保护重要数据免受未经授权的访问。

只读

在 Redis 中,默认情况下,从节点被配置为只读模式,即参数 slave-read-only 的值为 yes。这意味着从节点只能接收来自主节点的复制数据,而不能对数据进行修改。由于复制只能从主节点到从节点,主节点无法感知从节点的任何修改,因此在从节点上进行的任何修改都会导致主从数据不一致的情况发生。

因此,建议在线上环境中不要修改从节点的只读模式。通过保持从节点的只读状态,可以确保主节点与从节点之间的数据一致性,并避免可能引起数据不一致的情况发生。此外,只读模式还有助于提高系统的安全性,防止误操作或恶意操作导致数据的不一致性或损坏。

总之,只有在特定情况下确实需要对从节点进行修改,并且能够确保这些修改不会影响到主从数据的一致性时,才应该考虑修改从节点的只读模式。

传输延迟

TCP内部支持的Nagle算法是一种优化网络传输的机制,默认情况下是开启的。开启该算法后,TCP会在发送数据时进行延迟,以尝试合并小的数据包,从而减少网络传输中的包数量,节省带宽。然而,这也会增加传输的延迟。相反,如果关闭了Nagle算法,TCP会立即发送数据,降低传输延迟,但会增加网络带宽的使用。

在 Redis 中,主节点和从节点通常部署在不同的机器上,因此复制过程中的网络延迟是一个需要考虑的重要问题。为了帮助控制网络延迟,Redis 提供了 repl-disable-tcp-nodelay 参数,用于控制是否关闭 TCP_NODELAY 功能,默认情况下该参数的值为 no,即开启 TCP_NODELAY 功能。

在主从同步通信过程中,通过设置repl-disable-tcp-nodelay选项来实现关闭TCP的Nagle算法。这样做的目的是让从节点能够更快地与主节点进行同步。通过禁用Nagle算法,我们可以减少同步数据时的延迟,加快数据传输速度,从而更快地将主节点的数据复制到从节点上。

具体说明如下:

  • 当关闭 TCP_NODELAY 功能时,主节点产生的命令数据无论大小都会及时地发送给从节点。这样可以减少主从之间的延迟,但会增加网络带宽的消耗。这种配置适用于主从节点之间的网络环境较好的场景,例如同一机房内部署。
  • 当开启 TCP_NODELAY 功能时,主节点会合并较小的 TCP 数据包,以节省带宽。默认情况下,Linux 内核决定默认发送时间间隔,通常为 40 毫秒。这种配置节省了带宽,但会增加主从之间的延迟。这种配置适用于主从节点之间的网络环境复杂的场景,例如跨机房部署。

通过合理配置 repl-disable-tcp-nodelay 参数,可以根据实际场景和需求来平衡网络带宽的消耗和主从节点之间的延迟,从而更好地优化 Redis 复制的性能。

拓扑

Redis 的复制拓扑结构在实践中可以灵活地适应各种需求,它可以简单地以单层或多层的方式进行构建。

根据复制关系的复杂性和连接方式的不同,可以将 Redis 的复制拓扑结构划分为以下三种主要类型:

  1. 一主一从(Master-Slave): 这是最简单的复制拓扑结构,其中一个 Redis 主节点(Master)负责接收写入操作并将数据复制到一个从节点(Slave)。主节点负责处理写入请求,而从节点则复制主节点的数据。这种结构适合于需要数据备份和读取分离的场景,如负载均衡和故障恢复。

  2. 一主多从(Master-Multiple Slaves): 在这种结构中,一个 Redis 主节点可以有多个从节点。主节点负责接收写入请求并将数据复制到所有从节点上。多个从节点可以同时提供读取服务,从而增加了读取性能和可用性。这种结构适用于需要横向扩展读取能力的场景,如高并发读取和数据分析。

  3. 树状主从结构(Tree-like Master-Slave): 这种结构是一种更复杂的拓扑结构,其中从节点可以作为其他从节点的主节点。也就是说,从一个主节点复制数据的从节点可以再将数据复制给其他从节点,形成了一种树状结构。这种结构可以用于构建更灵活的数据复制网络,适用于需要更复杂数据流动和分发的场景,如多级数据中心的部署和地域性复制需求。

总的来说,Redis 的复制拓扑结构可以根据实际需求灵活选择,不同的结构可以满足不同的性能、可用性和数据一致性要求。

一主一从结构

一主一从结构是 Redis 复制拓扑中最基本的一种,通常用于提供故障转移支持,确保系统在主节点发生宕机时仍能保持可用性。这种结构适用于对数据一致性要求较高的场景,如金融交易系统或在线支付平台等。

在应用的写命令并发量较高且需要数据持久化时,可以选择在从节点上启用 AOF(Append Only File)持久化方式。AOF 持久化会将每个写操作以追加的方式记录到日志文件中,以确保数据的持久性和安全性。将 AOF 仅在从节点上启用的好处在于可以减少对主节点性能的影响。因为主节点通常负责处理更多的写入操作,开启持久化可能会导致主节点的性能下降。而将持久化操作放在从节点上则可以将这种影响降到最低,从而提高系统的整体性能和稳定性。

然而,需要注意的是,当主节点关闭持久化功能时,需要谨慎处理主节点的自动重启设置。如果主节点因为宕机而自动重启,而在重启时没有持久化的数据,可能会导致数据的丢失或不一致。因此,在关闭主节点的持久化功能时,需要同时关闭自动重启功能,确保在发生宕机时不会自动重启。这样可以确保在主节点宕机时,管理员可以手动介入进行数据恢复操作,以避免数据的丢失和系统的不稳定。

改进方法:

针对一主一从架构,当主节点挂掉后,可以通过以下步骤实现从节点接管成为新的主节点,并确保数据的完整性:

  1. 检测主节点故障: 从节点定期检测主节点的健康状态。一旦发现主节点不可用,从节点启动自动故障转移流程。

  2. 启动自动故障转移: 从节点检测到主节点不可用后,它开始自动故障转移流程。从节点会将自己升级为新的主节点,并通知其他节点主节点的变更。

  3. 停止服务: 在自动故障转移期间,原先的从节点(现在的新主节点)停止对外提供服务,防止数据不一致或损坏。

  4. 获取AOF文件: 新的主节点从现在的从节点获取最新的AOF文件,以确保数据的完整性。这可以通过Redis复制功能实现。

  5. 加载AOF文件并重启: 新的主节点加载从现在的从节点获取的AOF文件,并重启Redis服务。

  6. 通知其他节点: 新的主节点通知其他节点主节点的变更情况,以便它们能够更新配置并与新的主节点重新建立复制关系。

  7. 恢复服务: 当新的主节点成功重启并开始对外提供服务后,整个系统恢复正常运行状态。

通过这个自动故障转移流程,一主一从架构下的系统可以在主节点故障时实现自动切换,并确保数据的一致性和可用性。

一主一从拓扑:

一主多从结构

一主多从结构(星型结构)允许应用程序利用多个从节点来实现读写分离,从而提高系统的读取性能和可用性。在这种结构中,主节点负责处理所有的写入操作,而多个从节点则负责复制主节点的数据并提供读取服务。这种结构特别适用于读取操作比重较大的场景,比如社交网络应用或内容展示类网站。

对于读取操作较为频繁的场景,可以通过负载均衡将读命令分发到不同的从节点上,以分担读取压力。通过将读命令分散到不同的从节点上执行,可以有效地提高系统的读取性能,并降低主节点的负载。此外,对于一些耗时的读取命令,可以将其分配给专门负责处理的某个从节点执行,以避免影响整个系统的稳定性。

然而,在面对写入并发量较高的情况下,多个从节点可能会导致主节点需要多次发送写命令,从而增加主节点的负载。因为每个从节点都必须接收主节点的写入操作,并将其复制到自己的数据中。因此,在设计一主多从结构时,需要特别注意主节点的负载情况,以避免主节点的性能成为系统的瓶颈。

总的来说,一主多从结构可以有效地提升系统的读取性能和可用性,但在设计时需要充分考虑实际情况,合理规划和管理各个节点的负载,以确保系统的稳定运行。

一主多从拓扑:

树形主从结构

树形主从结构(分层结构)为 Redis 复制拓扑增加了更灵活的复制路径,使得从节点不仅可以复制主节点的数据,还可以作为其他从节点的主节点,进一步向下层复制。这种结构在数据复制过程中引入了复制的中间层,有效降低了主节点的负载,并减少了需要传输给从节点的数据量,从而提高了系统的性能和可扩展性。

在树形主从结构中,数据写入主节点 A 后会同步给 B 和 C 节点,而 B 节点则进一步将数据同步给 D 和 E 节点。这样,主节点的数据传输负载会得到分散,且数据传输路径更为灵活。这种结构的主要优势在于能够有效地降低主节点的负载压力,尤其是在需要挂载多个从节点时,可以减少对主节点性能的干扰,保证系统的稳定性。

特别是在大规模分布式系统中,树形主从结构表现得尤为出色。它能够更好地适应系统的扩展性需求,因为它可以根据系统规模的增长动态地调整复制层次和复制路径,从而保证系统的性能和稳定性。

但是,在树形主从结构中,一旦数据进行修改,同步延时往往会变得更长。这是因为在这种结构中,数据的变动可能需要通过多个层级传递和更新,从而增加了同步所需的时间。特别是在较大的树形结构中,数据的传播和更新可能需要经过多个节点,每个节点都需要相应的处理和确认,这就导致了同步延迟的增加。此外,如果网络连接或者节点之间的通信出现问题,也会进一步延长同步的时间。因此,在树形主从结构中,及时考虑和优化同步机制是非常重要的,以确保数据的一致性和及时性。

总的来说,树形主从结构是一种高度灵活和可扩展的 Redis 复制拓扑结构,能够有效地提高系统的性能、可靠性和可扩展性。这种拓扑结构适用于处理大规模数据、需要保证系统稳定性和可用性的场景,是构建高性能分布式系统的重要选择。

树形拓扑:

原理

复制过程

下图详细介绍了建立复制的完整流程。

从图中可以看出复制过程⼤致分为 6 个过程:

主从节点建立复制流程图:

  1. 保存主节点信息: 在配置主从同步关系之前,从节点只保存主节点的地址信息。这通常包括主节点的 IP 地址和端口号。此时,主节点的连接状态被标记为下线(down)。

  2. 从节点维护复制逻辑、创建TCP连接: 从节点内部通过定时任务(通常每秒执行一次)来维护复制相关的逻辑。该定时任务会尝试连接主节点,建立基于 TCP 的网络连接。如果连接失败,则定时任务会无限重试直到连接成功或者管理员手动停止主从复制。

  3. 发送 Ping 命令: 如果连接建立成功,从节点会发送 Ping 命令给主节点,以确认主节点在应用层上正常工作。主节点在收到 Ping 命令后,会回复 Pong,表示主节点正常运行。如果 Ping 命令的回复超时或者出现其他异常,从节点会断开 TCP 连接,并在下一次定时任务中再次尝试连接。

  4. 权限验证: 如果主节点设置了密码(requirepass 参数),则从节点需要进行密码验证。从节点在连接主节点时会使用配置的 masterauth 参数来传递密码信息。如果密码验证失败,则从节点的复制过程将被终止。

  5. 同步数据集——全量同步: 当连接成功并通过权限验证后,主节点开始向从节点发送数据。对于首次建立复制的情况,主节点会向从节点发送完整的数据集。这个过程称为全量同步。全量同步确保了从节点与主节点的数据一致性。全量同步完成后,从节点已经拥有了主节点的所有数据,可以接收后续的写入命令。

  6. 命令持续复制——增量同步: 全量同步完成后,主节点会持续地将后续的写入命令发送给从节点。这样,从节点就可以实时地接收并执行主节点的写入操作,保证了主从数据的一致性。主节点会将每个写入命令发送给所有从节点,从节点则按顺序执行相同的写入操作,以保持数据的一致性。

通过以上步骤,Redis 主从复制完成后,从节点将与主节点保持同步,确保了数据的可用性和一致性。这种复制方式提供了系统的高可用性和容错能力,可以应对主节点宕机或数据丢失等情况,确保了系统的稳定运行。

数据同步 psync

Redis提供了psync命令来完成主从节点之间的数据同步过程。

psync命令不需要由用户手动执行,而是由Redis服务器在建立好主从同步关系之后自动执行。在主从节点建立了同步关系后,从节点会主动发起psync命令,向主节点请求数据同步。主节点收到从节点的psync请求后,会将缺失的数据传输给从节点,从而完成数据的同步。这种自动化的同步机制使得Redis主从复制更加方便和高效,从而保证了数据在不同节点之间的一致性和可靠性。

PSYNC 的语法格式:PSYNC replicationid offset

通过psync命令,可以进行全量复制或部分复制,具体取决于replicationid和offset的设置。

  1. 如果将replicationid设为"?",并且将offset设为-1,那么就是在尝试进行全量复制。这意味着从节点会要求主节点重新传输所有的数据,以确保从节点与主节点的数据完全一致。

  2. 如果将replicationid设为具体的数值,并且将offset设为某个特定的数值,那么就是在尝试进行部分复制。在这种情况下,从节点会向主节点发送psync命令,请求从指定的复制ID和偏移量处开始的数据同步。这种部分复制通常在主从节点之间存在部分数据差异时使用,以节省网络带宽和加快同步速度。

通过这两种方式,Redis提供了灵活的数据同步机制,可以根据实际情况选择全量或部分复制,以满足不同的需求和场景。

Redis使用psync命令完成主从数据同步,其中同步过程分为全量复制和部分复制两种方式:

  1. 全量复制: 全量复制通常用于首次建立主从复制关系的场景。在全量复制中,主节点会将全部数据一次性发送给从节点,以确保从节点与主节点的数据完全一致。虽然全量复制能够保证数据的完整性,但当数据量较大时,会对主节点、从节点和网络造成较大的负担和开销。因此,全量复制通常适用于初始复制的场景,而不适用于频繁的数据同步。

  2. 部分复制: 部分复制用于处理在主从复制中由于网络闪断等原因导致的数据丢失场景。当从节点再次连接上主节点后,如果条件允许,主节点会补发丢失的数据给从节点。部分复制的特点是只传输丢失的数据,因此补发的数据量远远小于全量数据,可以有效避免全量复制带来的高开销。部分复制能够提高数据同步的效率和速度,减少了对网络带宽的占用和对系统资源的消耗。

总的来说,全量复制适用于初次建立主从复制关系的场景,而部分复制则适用于处理主从复制过程中的数据丢失问题。通过灵活运用全量复制和部分复制两种方式,Redis可以有效地实现主从数据的同步,确保了系统的可用性和数据的一致性。

我们接下来就看看这两个参数的具体介绍。

replicationid/replid (复制id)

在 Redis 中,replicationid 或 replid 是主节点的复制 ID。每个主节点都有一个唯一的复制 ID,它用于标识主节点的身份。当主节点重新启动或者从节点晋级成为主节点时,都会生成一个新的复制 ID。值得注意的是,同一个节点每次重启时生成的复制 ID 也会发生变化。

从节点在与主节点建立连接后,会获取到主节点的复制 ID。获取主节点的复制 ID 是建立主从关系的重要步骤之一,因为复制 ID 是从节点识别主节点的一种重要方式。通过复制 ID,从节点可以确认与之通信的是特定的主节点,从而建立起主从之间的通信和数据同步关系。

在主从复制过程中,复制 ID 扮演了重要的角色,它是主节点身份的唯一标识符,用于确保主节点与从节点之间的一致性和可靠性。每次主节点的重启或者晋级都会生成新的复制 ID,这种设计确保了主从复制系统的安全性和稳定性。

# 使用 info replication 命令查看主节点的复制信息
info replication

返回信息:

在这段返回的复制信息中,有两个与复制 ID 相关的参数:master_replid 和 master_replid2。

  • master_replid:主节点的当前复制 ID。该值表示当前主节点的身份标识。
  • master_replid2:备用的复制 ID。当主节点的复制 ID 发生变化时,原先的复制 ID 将会被保存在 master_replid2 中。这是为了解决在网络抖动等情况下发生的主节点切换问题。

解释:

当涉及到Redis主从复制时,每个节点(包括主节点和从节点)需要具备一些机制来处理不可预测的情况,例如网络中断或节点失效。复制ID的设置正是为了应对这些情况而设计的。

让我们来更详细地解释这一点:

  1. 主从复制中的角色: 在一个典型的主从架构中,有一个主节点(Master)和一个或多个从节点(Slave)。主节点负责接收写入操作并将其传播给所有从节点,而从节点则负责复制主节点的数据。

  2. 复制ID的作用: 复制ID是用来标识主节点的唯一标识符。每当主节点发生变化,例如主节点重启或者主节点发生切换(比如从节点晋升为主节点),都会生成一个新的复制ID。这个复制ID对于从节点来说是非常重要的,因为它帮助从节点识别和连接正确的主节点。

  3. 处理网络抖动的情况: 假设现在有两个节点,A是主节点,B是从节点。B记录了A的主复制ID(master_replid)。但如果网络发生抖动,B可能会误以为A挂掉了,并尝试将自己晋升为主节点,于是为自己分配了一个新的复制ID记住原先旧的replid。这样一来,B就有了两个复制ID,一个是之前A的,另一个是自己的。

  4. 备用复制ID(master_replid2)的作用: 为了避免混淆,B将之前A的复制ID保存在master_replid2中。这个备用复制ID在后续网络恢复后非常有用。即使网络重新连接后,B仍然可以根据master_replid2找回之前的主节点,继续进行数据同步。如果网络没有恢复,B则会按照新的复制ID自成一派,继续处理后续的数据。

  5. 保障主从复制的可靠性和稳定性: 通过这样的设置,即使发生了网络中断或主节点切换,从节点仍然能够保持与正确的主节点的连接,从而保障了主从复制过程的可靠性和稳定性。这种备用复制ID的设计确保了主从复制系统能够在不可预测的情况下正常运行,从而提高了系统的可用性和容错能力。

offset (偏移量)

在Redis中,主节点(Master)在处理完写入命令后,会记录每个命令的字节长度,并将这些字节长度累加到主节点的复制偏移量中。这个复制偏移量表示了主节点处理写入命令的总字节量,可以用来跟踪主节点的复制进度。

要查看主节点的复制信息,包括主节点的复制偏移量,可以在主节点上执行 info replication 命令。这个命令会返回关于主节点复制状态的详细信息,包括主节点的角色、已连接的从节点数量以及主节点的复制偏移量等。

127.0.0.1:6379> info replication

执行该命令后,会返回关于主节点的复制信息,其中包括主节点的复制偏移量(master_repl_offset)的值。这个值表示了主节点当前的复制偏移量,即主节点处理写入命令的总字节量 

主节点的复制信息如下所示:

# Replication
role:master
...
master_repl_offset:1055130

从节点(Slave)每秒钟会向主节点报告自己的复制偏移量,因此主节点也会保存从节点的复制偏移量。在主节点上执行 info replication 命令时,可以查看连接的从节点信息,包括从节点的 IP 地址、端口号、状态以及复制偏移量。

info replication
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1055214,lag=1

从节点在接收到主节点发送的命令后,也会累加记录自己的偏移量。在从节点上执行 info replication 命令时,可以查看从节点的复制偏移量。

info replication
# Replication
role:slave
...
slave_repl_offset:1055214

复制偏移量的维护如图所示。通过比较主从节点的复制偏移量,可以判断主从节点的数据是否一致。

在 Redis 中,主从节点都会维护自身的复制偏移量。这个复制偏移量是一个关键的指标,用于跟踪主节点和从节点之间数据同步的进度。主节点在处理写入命令后,会记录每个命令的字节长度,并将这些字节长度累加到主节点的复制偏移量中。同时,从节点会每秒向主节点报告自己的复制偏移量。通过比较主从节点的复制偏移量,可以判断主从节点的数据是否一致。如果两个节点的复制偏移量相同,意味着它们的数据是一致的。

所以,在Redis中,replication id和offset共同描述了一个数据集合的状态。如果两台Redis机器的replication id相同,并且offset也相同,那么可以确信这两台Redis机器上存储的数据集合是完全一样的。这是因为replication id标识了数据集合的版本,而offset则标识了数据集合的偏移量。当两个机器的replication id和offset完全匹配时,意味着它们的数据集合版本和数据内容都是一致的,因此可以推断它们存储的数据是完全相同的。

这种复制偏移量的机制对于确保主从节点之间的数据同步和一致性非常重要。它可以帮助管理员监测主从节点之间的复制状态,并及时发现数据同步的延迟或者不一致的情况。在实际应用中,管理员可以通过定期检查主从节点的复制偏移量来确保系统的可靠性和稳定性。

复制偏移量维护:

这个偏移量可以类比为“学习进度”。

在这个类比中,主节点就好比是老师,负责向学生传授知识,即处理写入命令并记录它们的字节长度,这些字节长度就代表了传授的知识量。主节点的复制偏移量则相当于老师的课程进度,记录了老师已经讲授的知识量。

而从节点则类比为学生,负责接收主节点传递的知识,即处理主节点发送的命令并报告自己的复制偏移量,这相当于学生在学习过程中不断记录自己的学习进度。

通过比较主节点和从节点的复制偏移量,就好比比较老师和学生的学习进度。如果两者的偏移量相同,就说明主节点和从节点的数据是一致的,类似于老师和学生学习的内容是完全一致的。而如果从节点的偏移量落后于主节点,就意味着从节点的学习进度没有跟上主节点,可能存在数据未同步的情况,类似于学生没有完全学习老师传授的内容。

因此,这个偏移量确实可以很形象地比喻为“学习进度”,有助于理解主从节点之间数据同步的机制。

✍再次强调:replid 和 offset 共同标识了一个数据集,它们在主从复制中扮演着重要角色。当两个节点的 replid 和 offset 都相同时,就意味着这两个节点上持有的数据是一致的。

  • replid(复制 ID)是用来标识一个节点的唯一标识符。每个节点都有自己的 replid,它会在节点启动时生成,并且在节点重新启动时会改变。replid 用于识别节点的身份,即使在节点重新启动后,它们的数据集仍然可以被正确地识别。
  • offset(偏移量)则用于标识数据集的偏移量或者进度。它表示了在主节点上处理写入命令的总字节量,也就是数据集的进度。主节点会不断地更新自己的 offset,从节点则会报告自己的 offset给主节点,以便主节点知道从节点的复制进度。

当两个节点的 replid 和 offset 都相同时,意味着它们具有相同的身份标识并且复制进度一致,因此它们持有的数据集就一定相同。这种情况下,可以确保主从节点之间的数据是同步的,数据一致性得到了保证。

psync 运行流程:

当从节点向主节点发送 psync 命令时,通常会带有参数,其中包括从节点当前的复制 ID(replid)和复制偏移量(offset)。但是在初始阶段,从节点可能还没有与任何主节点建立连接,或者从节点刚刚启动,此时它还没有任何关于主节点的复制信息。在这种情况下,从节点发送 psync 命令时,它的 replid 默认为一个空字符串,表示尚未与任何主节点建立复制关系;而 offset 默认为 -1,表示还没有复制任何数据。

主节点在收到从节点发送的 psync 命令后,会根据当前自身的情况来决定如何响应:

  • 如果主节点判断从节点需要进行全量复制,主节点会回复给从节点 +FULLRESYNC replid offset,其中 replid 和 offset 表示主节点当前的复制 ID 和复制偏移量。从节点收到这个回复后,会启动全量复制流程,从主节点重新获取所有数据。
  • 如果主节点判断从节点可以进行部分复制,主节点会回复给从节点 +CONTINUE,表示从节点可以从上次同步的偏移量继续进行增量复制。从节点收到这个回复后,会根据主节点发送的增量数据进行同步。
  • 如果主节点的版本过低,不支持 psync 命令,或者出现其他错误情况,主节点会回复给从节点 -ERR,表示无法执行 psync 命令。此时,从节点可以选择使用 sync 命令进行全量复制。

需要注意的是,psync 命令通常不需要手动执行,因为 Redis 在主从复制模式下会自动调用执行。另外,与 sync 命令不同的是,psync 命令不会阻塞 Redis 服务器处理其他请求,因为它仅在需要同步数据时才会被调用,而不会影响其他客户端请求的处理。

全量复制

全量复制是 Redis 最早支持的复制方式,也是主从第一次建立复制关系时必须经历的阶段。

在全量复制过程中,主节点会将自身的整个数据集发送给从节点。这意味着从节点会完整地复制主节点的所有数据,无论是已存在的数据还是在复制过程中新写入的数据。全量复制通常发生在从节点第一次连接到主节点或者从节点重新连接到主节点时。

全量复制的过程可以确保从节点和主节点的数据完全一致,从而建立起主从复制关系后,从节点可以通过增量复制来同步主节点的后续写入操作,保持数据的一致性。虽然全量复制会消耗较多的网络带宽和时间,但它是建立主从复制关系的基础,也是确保数据可靠性和一致性的重要手段。

因此,在主从复制的初始阶段,全量复制是不可避免的步骤,只有通过全量复制,从节点才能获取到主节点的完整数据集,并开始后续的增量复制流程。

全量复制的运行流程:

 

当从节点首次与主节点建立复制关系时,或者主节点不方便进行部分复制的时候,需要进行全量复制流程。

全量复制的详细步骤:

  1. 从节点发送 psync 命令给主节点,由于是第一次复制,从节点还没有主节点的复制 ID 和复制偏移量,因此发送 psync 命令时,会使用 ? 表示未知的复制 ID,-1 表示未知的偏移量。

  2. 主节点接收到 psync 命令后,解析命令并发现需要进行全量复制,于是回复给从节点 +FULLRESYNC 响应,并在响应中附带自身的复制 ID 和复制偏移量。

  3. 从节点接收到主节点的运行信息后进行保存,以备后续使用。

  4. 主节点执行 bgsave 命令进行 RDB 文件(二进制文件)的持久化,将当前内存中的数据保存到磁盘上。这一步骤可以确保主节点在发送数据给从节点时不会丢失数据。这里不能使用已有的RDB文件,而是必须重新生成,因为已有的RDB文件可能会和当前的最新数据存在较大差异。

  5. 主节点将生成的 RDB 文件发送给从节点,从节点接收并保存 RDB 数据到本地硬盘。从节点在接收到完整的 RDB 数据后,可以确保已经获取到了主节点当前的数据快照。

  6. 在从节点保存完整的 RDB 文件后,主节点开始将在 RDB 文件生成到发送完成期间执行的写命令缓存起来(生成和传输RDB文件的过程中也在不断地接收新的修改操作,都需要同步给从节点)。这些写命令会以主节点发送给从节点的格式被缓存,并等待从节点准备就绪。

  7. 主节点等待从节点确认已接收完整的 RDB 数据,并已准备好接收增量数据。一旦从节点准备好,主节点会将缓存中的写命令数据按照 RDB 文件的二进制格式追加写入到已接收的 RDB 文件中,以保持主从一致性。

  8. 从节点在接收到主节点发送的所有数据后,会清空自身原有的旧数据。

  9. 从节点加载 RDB 文件,从而获取与主节点一致的数据。

  10. 如果从节点在加载完整的 RDB 文件后开启了 AOF 持久化功能,它会执行 bgrewrite 操作,生成最新的 AOF 文件。这样可以确保从节点在主节点复制数据后,也能够持久化到磁盘中。由于当前收到的是大批量的数据,AOF日志可能会包含大量的冗余信息,这可能会导致AOF文件过大,影响Redis服务器性能和可用磁盘空间。因此,对AOF日志进行整理和优化是非常必要的。

上述步骤展示了全量复制的过程,它确保了主节点和从节点之间的数据完整性和一致性,但也因为涉及大量数据传输和处理,所以应该尽可能地避免对已有大量数据的 Redis 实例进行全量复制。

全量复制是一项高成本的操作,主要原因包括以下几个方面:

  1. 主节点的 bgsave 时间:在全量复制过程中,主节点需要执行 bgsave 命令将当前内存中的数据持久化到磁盘中,生成 RDB 文件。这个过程可能会占用大量的 CPU 和内存资源,尤其是在数据集较大的情况下,可能会导致主节点性能下降。

  2. RDB 在网络传输的时间:生成的 RDB 文件需要通过网络发送给从节点。在网络传输过程中,如果网络带宽有限或者存在网络拥堵,传输时间可能会较长,尤其是对于大规模数据集的情况下。

  3. 从节点清空旧数据的时间:在接收到主节点发送的 RDB 文件后,从节点需要清空旧数据。这个过程可能会引起从节点的阻塞,特别是当从节点处于高负载状态时。

  4. 从节点加载 RDB 的时间:从节点在接收完整的 RDB 文件后,需要加载这个文件并恢复数据。这个过程可能会占用较多的磁盘和内存资源,并可能导致从节点在加载期间无法处理其他请求。

综上所述,全量复制过程涉及到多个步骤,每个步骤都可能会带来一定的性能开销和时间消耗。因此,在已经存在大量数据集的情况下,尽量避免进行全量复制是一个明智的选择。可以通过增量复制或其他方式实现主从节点之间的数据同步,以减少对系统性能的影响。

replication id 和 run id 的辨别

 

在Redis服务器上,Replication ID(replid)和Run ID(runid)是两个不同的标识符,它们用于不同的目的。

  1. Replication ID(replid)

    • Replication ID是Redis用于标识主从节点关系的标识符。当一个Redis从节点(Slave)连接到一个主节点(Master)时,主节点会向从节点发送它的Replication ID,以便从节点能够识别它的主节点。
    • Replication ID对于具有主从关系的节点是相同的。在一个主节点与多个从节点的情况下,所有从节点的Replication ID都将与主节点的Replication ID相同。
    • Replication ID的长度是40个字符,通常表示为40个十六进制字符。
    • Replication ID是在主节点角色中创建的,因为它与主节点的复制功能直接相关。
  2. Run ID(runid)

    • Run ID是Redis实例的唯一标识符,无论它是作为主节点、从节点还是哨兵运行。它用于识别Redis服务器的实例。每个Redis服务器的Run ID是唯一的,并且在该实例的生命周期内保持不变。
    • Run ID的长度也是40个字符,通常表示为40个十六进制字符。
    • Run ID通常用于唯一标识一个Redis实例,无论它是作为主节点还是从节点运行。

虽然在长度和格式上Replid和Runid看起来相似,但是它们的用途不同,且Replication ID在具有主从关系的节点之间是相同的,而Run ID是用于唯一标识一个Redis实例的。

部分复制

部分复制是Redis为了优化全量复制的高开销而引入的一种机制。在部分复制中,Redis利用psync命令以及复制ID(replication ID)和偏移量(offset)来实现。当从节点正在复制主节点时,如果出现网络闪断、命令丢失等异常情况,当从节点和主节点恢复重新建立连接之后,从节点会向主节点请求补发丢失的命令数据。如果主节点的复制积压缓冲区中存在这些数据,主节点会直接将其发送给从节点,从而保持主从节点复制的一致性。

部分复制的关键优势在于补发的数据量通常远远小于全量数据,因此相比全量复制,它的开销更小。这种优化措施有效地降低了全量复制过程中可能出现的网络异常或命令丢失带来的影响,有助于保障主从节点之间复制的稳定性和一致性。部分复制机制的引入使得Redis在处理复制过程时更加高效和可靠。

部分复制过程:

从节点之前已经从主节点上复制过数据,但是因为网络抖动或者从节点重启了,需要重新向主节点这边同步数据,此时请求是否能只同步一小部分(大部分数据都是一致的)

  1. 当主从节点之间发生网络中断时,主节点启动一个计时器,计时器的时长由配置的repl-timeout参数决定。若在设定的时间内未收到从节点的响应,主节点将判定从节点故障,并终止复制连接,以确保系统的稳定性和数据的一致性。
  2. 在主从连接中断期间,尽管主节点可以继续接收客户端发送的命令,但由于复制通道中断,主节点产生的复制命令无法即时发送给从节点。这些待发送的复制命令被暂存在复制积压缓冲区中,等待后续从节点重新连接并请求复制数据时发送给它们,以保证主从节点间数据同步不会中断。
  3. 一旦主从节点的网络连接恢复,从节点会重新尝试连接到主节点,以继续进行复制过程。
  4. 从节点重新连接后,会将之前保存的复制ID(replication ID)和复制偏移量作为psync命令的参数发送给主节点,请求进行部分复制。这些参数用于确定从节点需要同步的数据的起始位置。
  5. 主节点收到psync请求后,首先进行验证以确保主从节点的复制状态一致。然后,主节点根据从节点提供的偏移量在复制积压缓冲区中查找相应的数据。若在缓冲区中找到匹配的数据,则向从节点发送+CONTINUE响应,表示准备好了要发送的数据。
  6. 主节点随后将需要同步给从节点的数据发送给从节点,完成主从节点之间的数据一致性。这样,即使发生了网络中断,部分复制机制也能够确保主从节点之间的数据同步,减少了因全量复制而带来的高成本和性能开销。

复制积压缓冲区

复制积压缓冲区是主节点上的一个固定长度的队列,用于暂存写入命令等待发送给连接的从节点(slave)。默认情况下,该缓冲区的大小为1MB。当主节点与从节点建立连接时,复制积压缓冲区会被创建。

在主节点接收到写入命令时,不仅会将命令发送给客户端,还会将其写入复制积压缓冲区。这样做的目的是保证即使在网络断开或从节点未能及时响应的情况下,主节点也能保持这些写入命令的备份。一旦连接恢复,主节点会通过复制协议将这些积压的命令发送给从节点,从而保证主从节点之间的数据一致性。

复制积压缓冲区是一个先进先出的定长队列,其本质上是一个环形队列,用于保存最近已复制的数据。这个缓冲区在主节点与从节点之间的数据复制过程中发挥着重要作用,特别是在部分复制和复制命令丢失的数据补救时。通过将写入命令暂存于复制积压缓冲区,即使在网络连接中断或者从节点未能及时响应的情况下,主节点也能够保持这些写入命令的备份。一旦连接恢复,主节点会逐步将复制积压缓冲区中的数据发送给从节点,从而确保主从节点之间的数据一致性。

复制积压缓冲区相关的统计信息可以通过主节点的 info replication 命令获取。其中,repl_backlog_active 表示复制缓冲区是否启用,repl_backlog_size 表示缓冲区的最大长度,repl_backlog_first_byte_offset 表示缓冲区的起始偏移量,而 repl_backlog_histlen 表示已保存数据的有效长度。通过这些统计指标,我们可以计算出复制积压缓冲区内的可用偏移量范围,即从 repl_backlog_first_byte_offset 开始,到 repl_backlog_first_byte_offset + repl_backlog_histlen 结束,这个范围内的值相当于环形队列中的数组下标。

下面我们通过执行 info replication 命令来查看复制积压缓冲区的相关统计信息:

127.0.0.1:6379> info replication
# Replication
role:master
...
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:7479
repl_backlog_histlen:1048576

在这个示例中,r
epl_backlog_active 为 1 表示复制缓冲区是激活状态,
repl_backlog_size 为 1048576 表示缓冲区的最大长度为 1MB,
repl_backlog_first_byte_offset 为 7479 表示缓冲区的起始偏移量,
repl_backlog_histlen 为 1048576 表示已保存数据的有效长度。

❗如果当前从节点需要的数据已经超出了主节点的复制积压缓冲区的范围,那么无法进行部分复制,只能进行全量复制。这是因为部分复制所需的数据已经不再缓冲区内,无法从缓冲区中获取。在这种情况下,主节点和从节点需要重新建立起一致的复制连接,主节点将会对从节点执行全量复制,以确保从节点能够获取到全部数据,并且与主节点保持一致。 

实时复制

实时复制是主从节点建立复制连接后的一种重要机制,它通过长连接的方式不断地将主节点接收到的修改操作传输给从节点,从而实现主从节点数据的实时同步,以保持数据的一致性和实时性。这种实时同步机制对于许多应用场景至关重要,特别是需要及时更新数据的情况下。

实时复制的流程如下:

  1. 数据同步阶段:在初始阶段,从节点与主节点建立连接并完成数据同步,确保从节点的数据与主节点一致。这个阶段结束后,从节点已经拥有了与主节点相同的数据副本,并处于与主节点实时同步的状态。

  2. 实时同步阶段:在实时同步阶段,主节点持续接收新的修改数据请求,这些请求可能来自客户端或其他数据写入操作。主节点接收到这些请求后,会立即将修改数据通过事先建立的TCP长连接发送给所有从节点。

  3. 从节点数据更新:从节点接收到主节点发送的修改请求后,根据这些请求在本地内存中进行相应的数据更新操作。这确保了从节点的数据与主节点保持同步。

在这个流程中,延时是一个重要的因素。一般情况下,实时同步的延时较短,即从主节点接收到修改请求到从节点完成数据更新的时间较短。然而,在存在多级从节点的树形结构中,延时可能会增加,原因如下:

  • 级联同步延迟:如果存在多级从节点,主节点的数据更新需要依次传播到所有级别的从节点。每一级别的从节点都需要接收、处理和应用这些修改请求,因此级联同步会导致延时的累积。

  • 网络延迟和拥塞:数据传输过程中的网络延迟和拥塞也会影响实时同步的延时。特别是在级联同步的情况下,网络传输时间会逐级累加,导致延时增加。

  • 从节点处理能力:从节点的处理能力可能成为延时的瓶颈。如果从节点的处理速度无法跟上主节点的修改请求速度,将导致数据同步的滞后。

在实时复制过程中,为了保持连接的健康状态和维护连接状态,通常会使用心跳包进行监测和维护。这里的心跳是指应用层自身实现的一种机制,用于周期性地发送特定的消息或信号以确认连接的存活性。与 TCP 协议自带的心跳不同,应用层的心跳更加灵活,可以根据实际需求进行定制和优化,以适应不同的网络环境和应用场景。

通过实时复制和心跳机制的配合,主从节点之间可以及时地进行数据同步和连接状态的监测,确保数据的实时性和一致性,提高系统的可靠性和稳定性。

当主节点和从节点建立复制连接后,实时复制机制起到了至关重要的作用,确保数据的实时同步和一致性:

  1. 心跳检测机制:主从节点之间通过模拟对方的客户端进行通信,定期发送心跳消息或信号来确认连接的健康状态。这可以防止由于网络中断或节点故障导致的连接问题,并及时发现并处理异常情况。

  2. 主节点的 ping 命令:主节点默认每隔一定时间(通常为10秒)向从节点发送 ping 命令,以检测从节点的存活性和连接状态。如果从节点未能及时响应 ping 命令,主节点可以根据具体情况采取相应的措施,例如重新连接或标记从节点为下线状态。

  3. 从节点的 replconf ack 命令:从节点会周期性地(通常为每隔1秒)向主节点发送 replconf ack {offset} 命令,用于向主节点报告自己当前的复制偏移量。通过这个命令,主节点可以了解从节点的复制进度,从而及时监控复制的状态和进程。

  4. 处理连接超时:如果主节点在设定的 repl-timeout 时间内未收到从节点的响应,即从节点的通信延迟超过了配置的阈值(默认为60秒),主节点将判定从节点为下线状态,并断开与其的复制客户端连接。一旦从节点恢复连接,心跳机制会重新启动,确保主从节点之间的连接状态和数据同步的持续性。

通过实时复制机制,主从节点可以始终保持连接,并且及时传输修改操作,从而保持数据的实时同步和一致性。

💡从节点和主节点之间断开连接有两种情况:

  • 当从节点主动与主节点断开连接(执行slaveof no one命令)时,从节点不再被动地接收来自主节点的复制数据,而是成为一个独立的节点。这种情况通常发生在需要将原本的从节点升级为独立的主节点,或者需要进行特定的操作和实验时。此时,程序员需要主动修改Redis的组成结构,将从节点配置为一个独立的主节点。这可能涉及到修改配置文件、重新启动Redis服务等操作。需要特别注意的是,在进行这种操作时,要确保数据的一致性和安全性,以避免数据丢失或不一致。
  • 另一种情况,当主节点发生故障时,从节点不会自动晋升为主节点。这种情况下,需要通过人工干预的方式来恢复主节点。通常情况下,管理员需要手动选择一个从节点作为新的主节点,并更新其他从节点的配置,将其设置为新主节点的从节点。这个过程可能涉及到修改配置文件、执行命令等操作。

总的来说,无论是从节点主动与主节点断开连接还是主节点发生故障,都需要管理员的主动干预来调整Redis集群的结构。因此,在设计和管理高可用性系统时,需要考虑到这些情况,并制定相应的应对策略和操作流程,以确保系统能够在发生故障时迅速恢复,并保持稳定运行。

划分工作目录

当我们停止运行主节点客户端之后,再次尝试启动Redis服务器时,发现无法成功启动?

问题出现的根本原因在于AOF文件的权限设置问题。AOF文件是Redis服务器在启动时必须加载的文件,它记录了Redis服务器接收到的每个写操作,因此对于服务器的正常运行至关重要。

而我们启动的时候,是使用service redis-server start 启动Redis服务器的,这通常是以特定的用户(例如redis用户)身份启动,而不是root用户,目的是降低潜在的安全风险。因为以root用户身份启动Redis服务器存在较大的安全风险,一旦Redis服务器被黑客攻破,后果可能会非常严重。

然而,由于从节点是以root用户身份手动启动的,而生成的AOF文件也继承了root用户的权限,导致其他非root用户无法以可读可写的方式访问AOF文件,从而造成了无法启动Redis服务器的问题。

此外,由于没有在创建从节点的配置文件时修改AOF文件的路径,导致所有Redis服务器都共用同一个AOF文件,这在实际应用中是不合适的。因为不同的Redis服务器可能承担着不同的角色和负责不同的数据集,共用同一个AOF文件会导致数据不一致性和安全性问题。

因此,为了解决这个问题,我们需要确保每个Redis服务器都有独立的AOF文件,并且AOF文件的权限设置正确,可以被所有需要访问它的用户所读写。另外,还应该考虑使用专用的非特权用户来启动Redis服务器,以降低系统受到攻击的风险。

解决方案:

针对区分不同Redis服务器的工作目录,以及解决从节点的工作目录问题:

  1. 停止Redis服务器: 首先,需要停止之前正在运行的Redis服务器,确保不会有数据丢失或冲突。

  2. 删除旧工作目录下的AOF文件(可选): 如果选择删除旧工作目录下的AOF文件,可以通过执行以下命令来实现:

    rm appendonly.aof

    这样可以确保在启动新的Redis服务器时不会受到旧AOF文件的影响。
    使用chown命令修改AOF文件的所属用户和用户组为Redis用户和Redis用户组,也是一种有效的方法,可以确保新的Redis服务器在启动时可以访问并管理AOF文件。
    操作如下:

    chown redis:redis appendonly.aof
    

    这样可以确保在启动新的Redis服务器时,其对应的AOF文件拥有正确的权限,从而避免了可能的访问权限问题。这种方法和删除AOF文件相比,可以更快速地完成操作,且不会丢失任何数据。

  3. 创建新工作目录并修改配置文件:

    • 首先,为从节点创建一个新的工作目录,可以通过执行以下命令实现:
      mkdir -p /path/to/new_work_directory
    • 然后,修改从节点的配置文件(通常是redis.conf),将dir选项设置为新的工作目录路径,可以在配置文件中找到并修改该选项:
      dir /path/to/new_work_directory

    这样可以确保从节点的数据文件和日志文件都存储在新的工作目录中。



  4. 启动Redis服务器: 修改完从节点的配置文件后,重新启动Redis服务器:

    redis-server /path/to/redis.conf

    确保从节点已经按照新的配置文件进行了启动,并且数据文件和日志文件都保存在新的工作目录下。
    ​​​​​​​

通过这个解决方案,我们可以将不同Redis服务器的工作目录区分开来,并确保从节点的工作目录与其他节点不会冲突或混淆。这有助于提高系统的可靠性和管理效率。

总结

主从复制解决的问题

主从复制是一种用于解决单点问题的重要技术,主要针对单个 Redis 节点的可用性和性能有限等问题。

  1. 提高可用性:单个 Redis 节点可能会面临因硬件故障、网络问题或软件错误等原因导致的宕机风险。通过主从复制,可以创建多个从节点,当主节点出现故障时,可以快速切换到其中一个从节点,保证服务的持续可用性。这种故障转移的能力大大提高了系统的稳定性和可靠性。

  2. 提升性能:单个 Redis 节点的性能有限,无法满足高并发和大规模数据处理的需求。通过主从复制,可以将读请求分发到多个从节点上进行处理,从而分担主节点的负载,提高整体系统的读取性能和并发处理能力。此外,通过水平扩展和负载均衡等技术,可以进一步提升系统的性能。

总的来说,主从复制技术通过创建多个节点并建立节点之间的复制关系,有效地解决了单点故障和性能瓶颈等问题,提高了 Redis 系统的稳定性、可用性和性能。

主从复制的特点

主从复制是 Redis 中一项重要的功能,具有以下特点:

  1. 创建主节点的多个副本:通过复制功能,主节点可以拥有多个从节点副本,这些从节点将复制主节点的数据,实现数据的备份和冗余,提高系统的可靠性和容错性。

  2. 读写分离:主节点负责处理写入操作,而从节点用于处理读取请求。通过读写分离,可以有效降低主节点的访问压力,提高系统的读取性能和并发处理能力。

  3. 多种拓扑结构:复制支持多种拓扑结构,例如单主单从、主从链、主从树等,可以根据不同的场景和需求选择合适的拓扑结构,灵活应对各种复制架构需求。

  4. 多种复制方式:复制过程包括全量复制、部分复制和实时复制。全量复制用于初次复制场景,部分复制用于处理因网络闪断等原因造成的数据丢失场景,而实时复制则通过长连接的方式持续传输修改操作,保持主从节点的数据实时同步。

  5. 心跳机制:主从节点之间通过心跳机制保证通信的正常和数据的一致性。主节点定期发送 ping 命令检测从节点的存活性,从节点定期向主节点报告复制偏移量,以确保复制连接的稳定性和数据的同步性。

主从复制的优缺点

主从复制在提高系统的可用性和可靠性方面有诸多优势,但也存在一些局限性和缺点。

优点:

  1. 负载分担和读写分离:主从复制可以将读请求分发到多个从节点上,减轻了主节点的负载压力,提高了系统的读取性能和并发处理能力。

  2. 数据冗余和备份:通过从节点的存在,可以实现数据的备份和冗余,提高了系统的可靠性和容错性,当主节点发生故障时,可以快速切换到从节点继续提供服务。

  3. 故障恢复:在主节点故障时,可以通过从节点进行故障恢复,提高了系统的可用性,降低了服务中断的风险。

  4. 扩展性:可以通过添加更多的从节点来扩展系统的读取能力,从而满足系统的扩展需求。

缺点:

  1. 复制延迟:当从节点数量增多时,复制数据的延迟会变得明显,可能导致从节点上的数据与主节点数据之间存在一定程度的时间差。

  2. 故障转移需要手动干预:在主节点发生故障时,从节点不会自动晋升为主节点,需要管理员手动介入,进行故障恢复和主从切换,增加了管理和维护的复杂性。

  3. 网络带宽压力:主从复制会占用一定的网络带宽资源,特别是在复制大量数据时,可能会给网络带宽造成一定压力,影响其他系统的正常运行。

  4. 一致性保障:在主从复制过程中,由于网络延迟或其他原因,可能会导致主从节点之间的数据不一致,需要额外的机制来保障数据的一致性和完整性。

举报

相关推荐

0 条评论