Mongodb 具有 aws 云形成和自动缩放的集群

Mongodb cluster with aws cloud formation and auto scaling

我一直在研究在 AWS 中创建自己的 mongodb 集群。 Aws mongodb template 提供了一些很好的起点。但是,它不包括自动缩放或节点出现故障时。例如,如果我有 1 个主节点和 2 个辅助节点。主服务器宕机,自动缩放开始。我如何将新启动的 mongodb 实例添加到副本集?

如果您查看模板,它会使用 init.sh 脚本来检查正在启动的节点是否是主节点,并等待所有其他节点都存在并创建一个副本集,其中包含它们的 IP 地址首要的。初始配置副本集时,所有节点都已经存在。

不仅如此,我的节点应用程序还使用猫鼬。部分数据库连接允许您指定多个节点。我将如何跟踪当前的动态和 运行(我想我可以使用 DynamoDB 但不确定)。

如果实例宕机,通常的流程是什么?如果发生这种情况,人们通常会手动重新配置集群吗?

有什么想法吗?谢谢

这是一个很好的问题,我最近也经历了这段非常痛苦的旅程。我在这里写了一个相当广泛的答案,希望通过 CloudFormation 运行宁 MongoDB 集群的一些想法对其他人有用。

我假设您正在创建一个 MongoDB 生产集群,如下所示:-

  • 3 个配置服务器(micros/smalls 个实例可以在这里工作)
  • 至少 1 个分片包括例如2(主要和次要)分片实例(最小或大型),为数据/日志/日志磁盘配置了大磁盘。
  • 投票仲裁机(微信可能还行)。

https://docs.mongodb.org/manual/core/sharded-cluster-architectures-production/

像你一样,我最初尝试了你在 link (https://s3.amazonaws.com/quickstart-reference/mongodb/latest/templates/MongoDB-VPC.template) 中发布的 AWS MongoDB CloudFormation 模板,但老实说,它太复杂了,即它是9,300 行长并设置多个服务器(即副本分片、配置、仲裁器等)。 运行 CloudFormation 模板花费了很长时间,并且一直失败(例如,在 15 分钟后),这意味着服务器再次终止,我不得不重试,这真的很令人沮丧/耗时。

我最终寻求的解决方案(我对此非常满意)是为集群中的每种类型的 MongoDB 服务器创建单独的模板,例如

  1. MongoDbConfigServer.template (创建配置服务器的模板 - 运行 这 3 次)
  2. MongoDbShardedReplicaServer.template (创建副本的模板 - 运行 每个分片 2 次)
  3. MongoDbArbiterServer.template (创建仲裁器的模板 - 运行 每个分片一次)

注意:模板位于 https://github.com/adoreboard/aws-cloudformation-templates

然后的想法是单独启动集群中的每个服务器,即 3 个配置服务器、2 个分片副本服务器(用于 1 个分片)和一个仲裁器。然后,您可以将自定义参数添加到每个模板中,例如副本服务器的参数可以包括:-

  • InstanceType 例如t2.micro
  • ReplicaSetName 例如s1r (分片 1 个副本)
  • ReplicaSetNumber 例如2 (与 ReplicaSetName 一起使用以创建名称,例如名称变为 s1r2
  • VpcId 例如vpc-e4ad2b25 (显然不是真正的 VPC!)
  • SubnetId 例如subnet-2d39a157 (显然不是真正的子网!)
  • GroupId (现有 MongoDB 组 ID 的名称)
  • Route53 (将记录添加到内部 DNS 的布尔值 - 最佳实践)
  • Route53HostedZone (如果布尔值为真则使用 Route53 的内部 DNS ID)

CloudFormation 真正酷的地方在于,这些自定义参数可以 (a) 对人们 运行ning 它有用的描述,(b) 特殊类型(例如,当 运行ning 创建一个预过滤的组合框,因此更难犯错误)和(c)默认值。这是一个例子:-

    "Route53HostedZone": {
        "Description": "Route 53 hosted zone for updating internal DNS (Only applicable if the parameter [ UpdateRoute53 ] = \"true\"",
        "Type": "AWS::Route53::HostedZone::Id",
        "Default": "YA3VWJWIX3FDC"
    },

这使得 运行使用 CloudFormation 模板变得轻而易举,因为很多时候我们可以依赖默认值,并且只根据我们正在创建的服务器实例(或替换)。

除了参数,前面提到的 3 个模板中的每一个都有一个创建实例的 "Resources" 部分。我们也可以通过 "AWS::CloudFormation::Init" 部分做一些很酷的事情。例如

"Resources": {

    "MongoDbConfigServer": {
        "Type": "AWS::EC2::Instance",
        "Metadata": {
            "AWS::CloudFormation::Init": {
                "configSets" : {
                    "Install" : [ "Metric-Uploading-Config", "Install-MongoDB", "Update-Route53" ]
                },

前面示例中的 "configSets" 表明创建 MongoDB 服务器不仅仅是创建 AWS 实例并在其上安装 MongoDB 的问题,而且我们还可以 ( a) 安装 CloudWatch 磁盘/内存指标 (b) 更新 Route53 DNS 等。您的想法是尽可能自动化 DNS/监控等。

IMO,创建一个模板,因此为每个服务器创建一个堆栈具有非常好的优势,即能够通过 CloudFormation Web 控制台非常快速地更换服务器。此外,因为我们有一个 server-per-template,所以很容易一点一点地构建 MongoDB 集群。

我关于创建模板的最后一点建议是从其他 GitHub MongoDB CloudFormation 模板中复制适合您的内容,例如我使用以下方法创建副本服务器以使用 RAID10(而不是更昂贵的 AWS 配置的 IOPS 磁盘)。

https://github.com/CaptainCodeman/mongo-aws-vpc/blob/master/src/templates/mongo-master.template

在你提到的问题中 auto-scaling - 我的偏好是手动添加分片/替换损坏的实例(auto-scaling 对 Web 容器有意义,例如 Tomcat / Apache 但MongoDB 集群应该随着时间的推移缓慢增长)。然而,监控非常重要,尤其是分片服务器上的磁盘大小,以便在磁盘已满时提醒您(因此您可以添加新分片来删除数据)。使用 AWS CloudWatch 指标/警报或使用 MongoDB MMS 服务可以相当轻松地实现监控。

如果一个节点出现故障,例如分片中的一个副本,那么您可以简单地终止服务器,使用您的 CloudFormation 模板重新创建它te 和磁盘将自动同步。如果实例出现故障并且通常不需要 re-configuration,这是我的正常流程。过去我浪费了太多时间试图修复服务器 - 有时是幸运的,有时不是。我现在的备份策略是运行一个mongodump数据库的重要集合,每天通过一个crontabzip起来上传到AWS S3。这意味着如果发生核选项(完全数据库损坏),我们可以在一小时或 2 小时内重新创建整个数据库和 mongorestore

但是,如果您创建一个新的分片(因为您 运行宁出 space)配置是必要的。例如,如果您要添加一个新的 Shard 3,您将创建 2 个副本节点(例如,名称为 => mongo-s3r1 的主节点/名称为 => mongo-s3r2 的辅助节点) 和 1 个仲裁器(例如名称为 mongo-s3r-arb)然后你将通过 MongoDB shell 连接到 mongos (MongoDB 路由器)和 运行 这个命令:-

sh.addShard("s3r/mongo-s3r1.internal.mycompany.com:27017,mongo-s3r2.internal.mycompany.com:27017")

注意: - 此命令假定您通过 Route53 使用私有 DNS(最佳实践)。您可以简单地在 addShard 命令中使用 2 个副本的私有 IP,但过去我对此非常恼火(例如,几个月前所有 AWS 实例都重新启动并为所有实例生成了新的私有 IP他们。修复 MongoDB 集群花了我 2 天时间,因为我必须手动重新配置所有内容 - 而更改 Route53 中的 IP 需要几秒钟......;-)

您可能会争辩说我们还应该将 addShard 命令添加到另一个 CloudFormation 模板,但 IMO 这增加了不必要的复杂性,因为它必须知道具有 MongoDB 路由器的服务器(mongos) 并将其连接到 运行 addShard 命令。因此,在创建新 MongoDB 分片中的实例后,我只是 运行 这个。

总之,这就是我对此事的比较杂乱无章的想法。最主要的是,一旦你有了模板,你的生活就会变得容易得多,而且绝对值得付出努力!祝你好运! :-)