架构之道:如何确保数据同步和一致性

709 阅读10分钟

主从模式,亦称为主动/被动或领导者模式,是一种广泛应用的数据同步策略。在这个策略中,系统使用一个主节点来协调数据变更。系统中的其他节点作为从节点,负责从主节点同步数据。这种模式确保了数据的一致性和同步性。

1、主从架构模式概述

想象一个用于存储商店库存信息的数据库系统。这个系统的主节点设在总部,而从节点则分布在各个分店。

顾客在商店购买商品时,销售记录首先在总部的数据库中更新。随后,主节点会将这些更改同步到所有从节点。这确保了所有分店的数据库从节点都拥有最新的库存信息。

分店的收银员在查询商品库存时,可以直接访问本地的从节点。这种方式比查询远端的主节点更快,因为从节点距离他们更近。

这种架构的目的是提高网站的可靠性和性能。当网站流量激增,如果只有一个主数据库节点来处理所有读写请求,数据库可能会因为过载而响应缓慢。为了扩展应用程序以应对增长的用户需求,就需要一个用于写操作的数据源和另一个用于读操作的数据源,这就是主从架构的优势所在。

假设运行一个大型应用程序时服务器崩溃,原因是数据库服务器的读写请求过多。在这种情况下,推荐使用主从数据库架构。这种架构通过在从节点上分散读取负载,可以有效地扩展应用程序,适应不断增长的用户需求。

图 5-16

2、同步 VS 异步更新

在分布式系统中,数据在节点间同步的两种主要方式是同步更新和异步更新(如图5-17所示)。

同步更新:这种方式下,主节点会等待所有从节点确认接收到数据的更新后,才向客户端宣告操作成功。这确保了从节点始终保持与主节点相同的最新数据。但这可能会降低系统性能,因为主节点在收到所有从节点对上一个写入操作的确认之前,无法执行下一个写入操作。

举例来说,银行系统可能采用同步更新来管理客户账户数据,以确保所有数据从节点始终保持一致,哪怕在节点故障时也能如此。

异步更新:在这种方式下,主节点在从节点确认接收数据更新之前,就可以向客户端报告操作成功。这意味着从节点可能不会即时拥有最新的数据,且如果主节点在数据更新完全传送到所有从节点之前出现故障,则存在数据丢失的风险。然而,异步更新不会影响系统性能,因为主节点可以立即进行下一个写入操作。

例如,社交媒体网站可能采用异步更新来处理用户数据,这样在不影响性能的前提下支持大量用户,但这也可能意味着在所有数据从节点更新前存在一定的延迟。

图5-17

3、如何选择更新方式

对于那些数据一致性极为关键的系统,同步更新是最理想的选择。但是,如果系统的优先考虑是性能,那么异步更新会是一个更好的选择。

在实际应用中,很多系统采用了同步更新和异步更新相结合的方式。例如,数据库可能通过同步更新将数据更新到一些关键的从节点上,同时利用异步更新将数据更新到更多的从节点中。这种方法有时也被称作半同步更新(如图5-18所示)。

图5-18

在半同步数据更新模式中,从节点1的数据更新是同步进行的:主节点会在从节点1确认接收到数据操作之后,才向用户报告操作成功,并确保在其他客户端可以访问这些数据之前完成这些操作。而对于从节点2的数据更新,则是采用异步方式:主节点会向从节点2发送更新信息,但不会等待从节点2的确认回应。

4、如何增加从节点

在构建主从架构系统并添加新的从节点时,我们首要任务是确保这个新从节点与主节点的数据保持一致。这个过程可以通过以下步骤实现:首先,在某个特定时刻对主节点的数据做一个一致性快照;然后,将这个快照复制到新的从节点上;最后,让这个新的从节点连接到主节点,并同步自快照创建之后在主节点上发生的所有数据变更。

假设你正在管理一个包含一个主节点和两个从节点的数据库系统,现在需要添加第三个从节点。完成这一过程,你需要按照以下步骤操作:

  • 对主节点数据库进行快照。
  • 把这个快照复制到新的从节点上。
  • 启动这个新的从节点。
  • 新从节点会自动与主节点建立连接,并同步快照之后发生的所有数据变更。
  • 一旦新从节点同步了主节点的最新数据,它就会开始实时同步主节点数据。

采用一致性快照的优势:

  • 无需停机: 使用一致性快照添加新从节点可以在不关闭数据库的情况下进行。
  • 数据一致性保障: 这种方法能确保新从节点获得与主节点一致的数据副本。

然而,使用一致性快照也有其不足之处:

  • 增加存储需求: 创建快照会占用额外的存储空间。
  • 延长新从节点设置时间: 根据数据库的大小,创建快照可能需要较长时间。

5、日志同步

日志同步是主从架构中至关重要的一环,它确保了数据库中多个节点之间的数据同步。在这样的架构下,主节点承担着记录数据库所有更改的任务,而从节点则负责从主节点获取并同步这些更改。

在基于主节点的数据同步过程中,主要采用了四种类型的同步日志(如图5-19所示):

图5-19

5.1、基于SQL语句的同步

基于SQL语句的同步是数据库同步方法中最基础但也最有限制的一种方式。在这种方式下,主节点会记录下它执行的每条SQL语句,并把这些语句传送到从节点。随后,从节点需要按照与主节点完全相同的顺序来执行这些SQL语句。

不过,基于语句的同步方法可能面临一些挑战。主要的问题在于,确保从节点能够精确地按照主节点执行语句的相同顺序进行操作有时很难做到。此外,如果涉及的SQL语句存在副作用,那么可能会导致主从节点间的数据出现不一致情况。

5.2、预写日志传输(WAL传输)

预写日志传输(WAL传输)是一种与数据库存储引擎高度耦合的可靠数据同步方法。在这个过程中,主节点会将数据库的每次更改都记录在预写日志(WAL)中。预写日志本质上是一连串记录,详尽描述了对数据库所做的更改。然后,主节点将这些日志发送到从节点,从节点据此将这些更改应用到自己的数据库中。

对于追求高可用性和高可靠性的数据库系统来说,WAL传输是一个理想的选择。但是,需要注意的是,在采用WAL传输的系统中,数据库软件的升级可能较为复杂,因为要求主节点和从节点必须运行相同版本的软件。这可能导致在软件更新过程中遇到一定的挑战。

5.3、基于行的逻辑日志同步

基于行的逻辑日志同步在灵活性方面优于预写日志传输(WAL传输)。在这种同步机制中,主节点负责以行为单位记录数据库的每次更改。每一条日志记录都详尽地包含了被更改行的相关信息,明确指出了哪一行发生了变化,以及该行的所有列的新值。然后,主节点会把这些日志记录发送到从节点,从节点根据这些记录在自己的数据库中执行相应的更改。

这种基于行的逻辑日志同步方式特别适合于那些需要高度灵活性和可扩展性的数据库系统。同时,它也非常适用于需要频繁进行软件升级的数据库环境,因为这种同步模式允许主节点和从节点运行不同版本的数据库软件,从而提供了更大的兼容性和灵活性。

5.4、触发器式同步

触发器式同步是一种既复杂又高度灵活的数据同步方法。在这个方法中,主节点使用数据库触发器来捕捉数据变更,并将这些变更记录在一个专门的表中。接着,通过一个外部进程读取这个表中的数据变更记录,并将它们同步到其他系统中。

如果数据库环境需要定制化处理,或者我们希望将数据库与其他系统进行集成,那么触发器式同步是一个非常适合的选择。然而,需要注意的是,与其他同步方法相比,触发器式同步在实现和维护方面可能更为复杂。这种方法需要更多的定制工作和细致的管理,以确保同步的准确性和高效性。

总结

选择最适合您需求的同步日志类型取决于具体的项目需求,如果项目需要一个简单而可靠的同步方案,那么预写日志传输(WAL传输)是一个很好的选择。这种方法以其稳定性和可靠性而闻名。另一方面,如果需要寻求更高的灵活性,基于行的逻辑日志同步将是更理想的选择。这种方法提供了更多的灵活调整空间。此外,如果项目的需求包括定制化的同步流程或需要与其他系统集成,触发器式同步可能是最符合您需求的选项。触发器式同步允许更精细的控制和更广泛的定制可能性。