【问题标题】:Mongodb cluster with aws cloud formation and auto scaling具有 AWS 云形成和自动缩放的 Mongodb 集群
【发布时间】:2015-08-27 16:40:02
【问题描述】:

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

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

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

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

有什么想法吗?谢谢。

【问题讨论】:

    标签: mongodb amazon-web-services cluster-computing autoscaling amazon-cloudformation


    【解决方案1】:

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

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

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

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

    像您一样,我最初尝试了您在链接 (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) 对运行它的人有用的描述,(b) 特殊类型(例如,当运行创建一个预过滤的组合框,因此更难出错)和 (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

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

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

    但是,如果您创建新分片(因为空间不足),则需要进行配置。例如,如果您要添加一个新的 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 命令中简单地使用两个副本的私有 IP,但过去我对此非常不满(例如,几个月前,所有 AWS 实例都重新启动,并为所有这些实例生成了新的私有 IP。修复 MongoDB 集群花了我 2 天时间,因为我必须手动重新配置所有内容 - 而更改 Route53 中的 IP 需要几秒钟... ;-)

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

    无论如何,这是我对此事的漫不经心的想法。最重要的是,一旦您有了模板,您的生活就会变得更加轻松,而且值得付出努力!祝你好运! :-)

    【讨论】:

    • 感谢您提供非常详细的解释,我一定会在某个时候尝试一下。我最终暂时选择了托管解决方案,因为解决这个问题并不容易而且可能很耗时,但是您在这里有一些非常好的建议,我想重新讨论一下。我必须承认,aws 提供的配置非常复杂。
    • 托管解决方案(易于使用、部署更快)与自己托管(电源、控制、潜在的更便宜的总拥有成本等)有优缺点。我都做过,两者都适用于不同的场景。 CloudFormation 模板很棘手,学习曲线很长(以及一般的 AWS 开发运营),但非常值得!使用 CloudFormation 模板启动服务器、安装和配置软件的主要优势包括 (a) 可重复性 (b) 基础架构即代码,即支持代码审查 (c) 可靠性等。
    • 我在尝试使用 AWS MongoDB 快速入门提供的模板时遇到了同样的问题……只是花了很长时间,而且几乎没有反馈就失败了。我喜欢你的方法,@bobmarksie 它提供了更多的控制。有没有我们可以访问提到的模板的地方? (MongoDbConfigServer.templateMongoDbShardedReplicaServer.templateMongoDbArbiterServer.template
    • 嗨@monsieurBelbo - 我已经将模板上传到这里 - github.com/adoreboard/aws-cloudformation-templates。注意:没有用于创建 (1) VPC、(2) 安全组、(3) Route53 私有区域和 (4) 用于监控的 IAM 角色的模板。如果这些尚不存在,您可以手动或通过更多 Clo​​udFormation 模板创建它们。否则,您可以简单地调整模板以适合您的用例。当我有空闲时间时,我可能会写一篇关于以这种方式创建 MongoDB 集群的深入博客文章!如果您有任何改进建议,我将很高兴听到!祝你好运。
    • @bobmarksie,这太棒了!我已经研究了一整天的解决方案。我决定放弃,因为我认为if I use AWS auto-scaling I never scale a MongoDB server or a cluster. Thereby auto-scaling is not an effective way to scale technical infrastructure -which has a database server。现在你的解决方案就在我面前!另一方面,我尝试为我的应用程序构建一个安全的 AWS 基础设施(尽可能便宜)。我认为您的解决方案不适合没有足够投资的初创公司。而且还没有数据。你怎么看?
    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 2017-01-18
    • 2020-07-31
    • 2021-06-03
    • 2020-10-21
    • 2020-03-28
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多