从分布式一致性保证的角度看,Group Replication一直是一个最终一致性系统。这意味着,在入流量减少或停止后,所有组成员都将拥有相同的数据内容。系统的一致性事件可以分为控制操作和数据流操作。
对于Group Replication,控制操作可以从一致性角度评估,包括:
-
成员加入或离开,详见第 20.5.4 节,“分布式恢复”和写保护。
-
网络故障,详见围栏模式。
-
在单主组中,主故障转移,也可以是由
group_replication_set_as_primary()
触发的操作。
在单主组中,在主故障转移时,新的主服务器可以立即对应用程序流量开放,不管复制延迟有多大,或者直到新的主服务器应用了所有延迟后才开放访问。
使用第一种方法,组可以在主故障后尽快确保组成员稳定,然后立即开放数据访问,同时新的主服务器应用延迟。这样可以确保写一致性,但是在新的主服务器应用延迟期间,读取可能会暂时获取过时的数据。例如,如果客户端 C1 在旧主服务器上写入 A=2 WHERE A=1
,然后连接到新的主服务器,可能会读取 A=1
,直到新的主服务器应用了延迟并赶上旧主服务器的状态。
使用第二种方法,系统会在主故障后确保组成员稳定,然后等待新的主服务器应用所有延迟,然后才开放数据访问。这样可以确保在上述情况下,客户端 C1 连接到新的主服务器时读取 A=2
。但是,代价是故障转移时间将与延迟大小成正比,在正确配置的组中,延迟应该很小。
在 MySQL 8.0.14 之前,无法配置故障转移策略,默认情况下,系统会尽量提高可用性,如第一种方法所述。在 MySQL 8.0.14 及更高版本中,您可以使用 group_replication_consistency
变量配置事务一致性保证的级别。详见一致性对主选举的影响。
数据流对组一致性保证非常重要,因为读取和写入操作分布在组的所有成员上,特别是在单主模式下。数据流操作适用于 Group Replication 的两种模式:单主和多主模式,但为了简化解释,我们将其限制在单主模式下。通常情况下,写入操作路由到主服务器,而读取操作分布在第二服务器上。由于组应该作为单个实体,因此可以合理地期望主服务器上的写入操作立即在第二服务器上可用。虽然 Group Replication 使用了基于 Paxos 算法的组通信系统(GCS)协议,但是一些部分是异步的,这意味着第二服务器上的数据是异步应用的。这意味着客户端 C2 可以在主服务器上写入 B=2 WHERE B=1
,然后立即连接到第二服务器并读取 B=1
。这是因为第二服务器仍在应用延迟,并且尚未应用来自主服务器的交易。
您可以根据组的一致性保证在何时同步事务来配置。为了帮助您理解这个概念,本节将组内的事务同步点简化为读操作或写操作时。 如果数据在读取时同步,则当前客户会话将等待直到给定的点,该点是所有先前的更新事务已经应用的时间,然后才能开始执行。使用这种方法,只有这个会话受到影响,所有其他并发数据操作不受影响。
如果数据在写入时同步,写入会话将等待所有次要服务器写入数据。组复制使用总订单写入,因此这意味着等待所有次要服务器队列中的写入应用程序。当使用这种同步点时,写入会话将等待所有次要服务器队列应用程序。
任何替代方案都确保在客户C2的情况下总是读取 B=2
,即使立即连接到次要服务器。每种替代方案都有其优缺点,这些优缺点直接关系到您的系统工作负载。以下示例描述了不同类型的工作负载,并建议哪个同步点是适合的。
想象以下情况:
-
您想负载平衡读取,而不部署额外的限制,以避免读取过时的数据,组写入远远少于组读取。
-
您有一个组,主要是只读数据,您想让读写事务在提交后应用于所有地方,以便后续读取包含最新写入的最新数据。这确保您不需要为每个RO事务付出同步成本,而只需为RW事务付出。
在这些情况下,您应该选择在写入时同步。
想象以下情况:
-
您想负载平衡读取,而不部署额外的限制,以避免读取过时的数据,组写入远远多于组读取。
-
您想让工作负载中的特定事务总是读取组中的最新数据,例如,每当敏感数据更新(例如文件凭证或类似数据)时,您想强制读取最新值。
在这些情况下,您应该选择在读取时同步。