我一直在调查在AWS中创建自己的mongodb群集。 Aws mongodb template提供了一些很好的起点。但是,它不包括自动缩放或节点出现故障时。例如,如果我有1个主节点和2个辅助节点。并且主要关闭并且自动缩放开始。如何将新启动的mongodb实例添加到副本集?
如果查看模板,它会使用init.sh脚本来检查正在启动的节点是否是主节点,并等待所有其他节点存在,并在主节点上创建一个具有其IP地址的副本集。当初始配置副本集时,所有节点都已存在。
不仅如此,我的节点应用程序还使用了mongoose。部分数据库连接允许您指定多个节点。我如何跟踪当前正在运行的内容(我想我可以使用DynamoDB但不确定)。
如果实例出现故障,通常的流程是什么?如果发生这种情况,人们通常会手动重新配置群集吗?
有什么想法?感谢。
答案 0 :(得分:38)
这是一个非常好的问题,我最近经历了这个非常痛苦的旅程。我在这里写了一个相当广泛的答案,希望通过CloudFormation运行MongoDB集群的一些想法对其他人有用。
我假设您正在创建一个MongoDB生产群集,如下所示: -
即。 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服务器创建单独的模板,例如
MongoDbConfigServer.template
(创建配置服务器的模板 - 运行3次) MongoDbShardedReplicaServer.template
(创建副本的模板 - 每个分片运行2次) 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
(如果布尔值为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模板重新创建它,磁盘将自动同步。如果实例发生故障,这是我的正常流程,通常不需要重新配置。我过去浪费了太多时间来试图修理服务器 - 有时幸运/有时没有。我的备份策略现在每天通过mongodump
,crontab
运行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分片中的实例后运行它。
无论如何,这是我在这个问题上相当漫无边际的想法。最重要的是,一旦你有模板到位,你的生活就会变得更容易,而且非常值得付出努力!祝你好运! : - )