使用CloudFormation创建AWS DocumentDB集群时副本实例同可用区部署异常问题排查
解决DocumentDB CloudFormation实例AZ分配竞态条件问题
我完全懂你的困惑——按照DocumentDB官方文档的描述,实例本该自动跨可用区(AZ)均衡分布,但实际操作中却出现了两个副本挤在同一个AZ的情况,你猜测的竞态条件完全正确!
CloudFormation默认会并行创建同类型资源,当三个AWS::DocDB::DBInstance同时启动时,它们会几乎同时向DocumentDB集群查询当前已分配的AZ状态。此时集群可能还没来得及更新第一个实例的AZ分配信息,导致后两个实例都认为某个AZ是空的,最终扎堆部署。
解决方案:添加DependsOn强制串行创建
你提出的通过DependsOn让实例按顺序创建的思路是解决这个问题的关键。我们需要让每个实例等待前一个实例完全创建并完成AZ分配后再启动,这样DocumentDB就能按照文档描述的逻辑,依次将实例分配到剩余的AZ中。
修改后的三个DBInstance资源定义如下:
MongoDBInstance1: Type: AWS::DocDB::DBInstance Properties: DBInstanceClass: "db.r6g.large" DBClusterIdentifier: !Ref MongoDBCluster DBInstanceIdentifier: !Sub "mongodb-instance1-${MongoDBInstanceIdentifier}" PreferredMaintenanceWindow: "sun:00:00-sun:05:00" Tags: - Key: Name Value: !Sub "MongoDB Instance1 ${MongoDBInstanceIdentifier}" MongoDBInstance2: Type: AWS::DocDB::DBInstance DependsOn: MongoDBInstance1 # 等待实例1创建完成再启动 Properties: DBInstanceClass: "db.r6g.large" DBClusterIdentifier: !Ref MongoDBCluster DBInstanceIdentifier: !Sub "mongodb-instance2-${MongoDBInstanceIdentifier}" PreferredMaintenanceWindow: "sun:00:00-sun:05:00" Tags: - Key: Name Value: !Sub "MongoDB Instance2 ${MongoDBInstanceIdentifier}" MongoDBInstance3: Type: AWS::DocDB::DBInstance DependsOn: MongoDBInstance2 # 等待实例2创建完成再启动 Properties: DBInstanceClass: "db.r6g.large" DBClusterIdentifier: !Ref MongoDBCluster DBInstanceIdentifier: !Sub "mongodb-instance3-${MongoDBInstanceIdentifier}" PreferredMaintenanceWindow: "sun:00:00-sun:05:00" Tags: - Key: Name Value: !Sub "MongoDB Instance3 ${MongoDBInstanceIdentifier}"
原理说明
通过DependsOn强制实例串行创建后,每个新实例启动时,集群已经完成了前一个实例的AZ分配并更新了状态。此时DocumentDB就能准确判断出哪个AZ还未被占用,按照“主实例→第一个副本→第二个副本依次分配到不同AZ”的逻辑完成部署。我之前在类似场景中遇到过完全相同的问题,添加依赖后完美解决了AZ扎堆的情况。
另外补充一点:如果你不需要固定指定AZ列表,也可以尝试移除集群中的AvailabilityZones参数,让AWS自动分配AZ,但如果需要严格绑定到us-east-1a/b/c,串行创建是最可靠的方案。
内容的提问来源于stack exchange,提问作者Pierre
相关产品推荐
相关产品推荐

