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

时间:2015-06-11 19:44:49

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

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

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

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

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

有什么想法?感谢。

1 个答案:

答案 0 :(得分:38)

这是一个非常好的问题,我最近经历了这个非常痛苦的旅程。我在这里写了一个相当广泛的答案,希望通过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 (创建仲裁者的模板 - 为每个分片运行一次)
  4. 注意: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 (如果布尔值为true,则使用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模板重新创建它,磁盘将自动同步。如果实例发生故障,这是我的正常流程,通常不需要重新配置。我过去浪费了太多时间来试图修理服务器 - 有时幸运/有时没有。我的备份策略现在每天通过mongodumpcrontab运行zip数据库的重要集合,并上传到AWS S3。这意味着如果核选项发生(完全数据库损坏),我们可以在一小时或两小时内重新创建整个数据库和mongorestore

    但是,如果您创建新的分片(因为您的空间不足),则必须进行配置。例如,如果要添加新的 Shard 3 ,则会创建2个副本节点(例如,主要名称=> mongo-s3r1 / secondary,名称=> 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分片中的实例后运行它。

    无论如何,这是我在这个问题上相当漫无边际的想法。最重要的是,一旦你有模板到位,你的生活就会变得更容易,而且非常值得付出努力!祝你好运! : - )