全球多活使用限制

为保障实例的稳定和数据一致性,在使用全球多活功能时,有一些使用约束需要您注意。

使用限制

  • 子实例需满足以下条件:

    • 部署模式为经典

    • 存储介质为内存型

    • 架构为标准架构或集群架构。

    说明

    请确保各子实例规格一致,如需进行变配,建议对所有子实例均进行相同变配。若各子实例的规格不一致,可能会出现性能或容量问题。

  • 一个分布式实例中最多可包含三个子实例,且各子实例不能位于同一可用区。第一个子实例支持从已创建的实例进行转换,第二、第三个子实例需新购。

  • 一个分布式实例中的子实例必须都在中国内地或都在其他地域,若您需要在中国内地地域与其他地域之间进行数据同步,请使用DTS数据同步功能,更多信息请参见申请跨境数据同步权限

  • 成为分布式实例的子实例后,存在如下限制:

同步命令限制

  • FLUSHDBFLUSHALL命令不会被同步。

    • 如需清空数据:需对所有子实例执行FLUSHALL命令,否则会造成数据不一致。

    • 如需重新同步:例如以A实例为源,重新对B实例进行同步,您需要在分布式实例中移除B实例、对B实例执行FLUSHALL命令,再重新将B实例接入分布式实例中,接入后即可自动重新同步。

  • Pub和Sub命令不会被同步,如需实现跨域通知的消息复制,建议通过Stream数据结构来实现。

  • 同步RESTORE命令时,如果目标子实例具备相同的Key,则不会被执行。

同步粒度限制

目前同步的粒度为实例级,即子实例的所有数据都会被同步,暂不支持同步子实例中的部分数据。

说明

如需同步部分数据,需要通过业务逻辑来实现。

数据一致性限制

  • 单写场景下(例如用作灾备场景),数据的一致性级别为最终数据一致。

  • 多写场景下(例如用作多活场景),业务上应避免多个子实例在同一时刻或相近的时间修改同一个Key,否则可能造成数据不一致(即无法保障Key的最终一致性)或者数据堆积(在Streaming场景下严格递增产生的冲突),如下表所示。

    说明

    全球多活暂不支持CRDT(Conflict-Free Replicated Data Type)约束,您需要从业务层面自行保障。

    不一致情况

    图示

    说明

    value互换

    value互换

    1. 子实例A在1.1时刻收到SET命令(key->value_A),并于1.2时刻将数据写入数据库。

    2. 子实例B在2.1时刻收到SET命令(key->value_B),并于2.2时刻将数据写入数据库。

    3. 在3.1时刻子实例A向子实例B同步数据(key->value_A),同时子实例B向子实例A同步数据(key->value_B)。

    4. 同步完成,两个子实例中key对应的value发生了互换。

    乱序或丢失

    乱序或丢失

    1. 子实例A在1.1时刻收到命令(rpush key->value_A),并于1.2时刻将数据写入至数据库。

    2. 子实例B在2.1时刻收到命令(rpush key->value_B),并于2.2时刻将数据写入至数据库。

    3. 在3.1时刻子实例A向子实例B同步数据(rpush key->value_A),同时子实例B向子实例A同步数据(rpush key->value_B)。

    4. 当操作类型依赖value原始值时,在交换的情况下可能会出现乱序甚至丢失的情况。

      说明

      可能造成类似问题的还有、lpushlpopappendsort(store)、delhdelincrxadd系列等操作。

    类型不一致

    类型不一致

    1. 子实例A在1.1时刻收到命令(key->T(hash)),并于1.2时刻将数据写入至数据库。

    2. 子实例B在2.1时刻收到命令(key->T(string)),并于2.2时刻将数据写入至数据库。

    3. 在3时刻子实例间执行数据同步将形成冲突。

    写入条件不满足

    写入条件不满足

    1. 子实例A在1.1时刻收到命令(setnx key->value_A),并于1.2时刻将数据写入至数据库。

    2. 子实例B在2.1时刻收到命令(setnx key->value_B),并于2.2时刻将数据写入至数据库。

    3. 在3时刻子实例间执行数据同步将形成冲突。

      说明

      可能造成类似问题的还有set(nx | xx)hsetnx操作。