web-dev-qa-db-ja.com

AWSクラウド形成と自動スケーリングを備えたMongodbクラスター

AWSで独自のmongodbクラスターを作成することを調査しています。 Aws mongodb template いくつかの良い出発点を提供します。ただし、自動スケーリングやノードがダウンした場合は対象外です。たとえば、1つのプライマリノードと2つのセカンダリノードがあるとします。そして、プライマリがダウンし、自動スケーリングが開始されます。新しく起動されたmongodbインスタンスをレプリカセットに追加するにはどうすればよいですか?

テンプレートを見ると、init.shスクリプトを使用して、起動されているノードがプライマリノードであるかどうかを確認し、他のすべてのノードが存在するのを待って、プライマリにそれらのIPアドレスを使用してレプリカセットを作成します。レプリカセットが初期設定されている場合、すべてのノードがすでに存在します。

それだけでなく、私のノードアプリはマングースを使用しています。データベース接続の一部では、複数のノードを指定できます。現在稼働しているものを追跡するにはどうすればよいですか(DynamoDBを使用できると思いますが、よくわかりません)。

インスタンスがダウンした場合の通常のフローは何ですか?これが発生した場合、一般的に人々は手動でクラスターを再構成しますか?

何かご意見は?ありがとう。

17
Sun

これは非常に良い質問であり、私は最近、この非常につらい旅を自分で経験しました。 CloudFormationを介してMongoDBクラスターを実行するというこれらの考えのいくつかが他の人に役立つことを期待して、ここでかなり広範な回答を書いています。

次のようにMongoDB本番クラスターを作成していると仮定します。-

  • 3つの構成サーバー(micros/smallsインスタンスはここで機能します)
  • 少なくとも1つのシャードで構成されます。データ/ログ/ジャーナルディスク用に構成されたラージディスクを備えた2つの(プライマリおよびセカンダリ)シャードインスタンス(最小またはラージ)。
  • 投票用のアービターマシン(マイクロはおそらくOK)。

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

あなたと同じように、私は最初に、リンクに投稿したAWS MongoDB CloudFormationテンプレートを試しました( https://s3.amazonaws.com/quickstart-reference/mongodb/latest/templates/MongoDB-VPC.template )しかし、正直なところ、それははるかに複雑すぎました。つまり、9,300行の長さで、複数のサーバー(つまり、レプリカシャード、構成、アービターなど)をセットアップします。 CloudFormationテンプレートの実行には時間がかかり、失敗し続けました(たとえば、15分後)。これは、サーバーがすべて再終了したことを意味し、再試行する必要があり、非常に苛立たしく、時間がかかりました。

私が最終的に求めた解決策(私は非常に満足しています)は、クラスター内のMongoDBサーバーのタイプごとに個別のテンプレートを作成することでした。

  1. MongoDbConfigServer.template(構成サーバーを作成するためのテンプレート-これを3回実行します)
  2. MongoDbShardedReplicaServer.template(レプリカを作成するためのテンプレート-シャードごとに2回実行)
  3. MongoDbArbiterServer.template(アービターを作成するためのテンプレート-シャードごとに1回実行)

注:テンプレートは 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、テンプレートの作成、したがって各サーバーのスタックには、CloudFormationWebコンソールを介してサーバーを非常に迅速に置き換えることができるという非常に優れた利点があります。また、server-per-templateがあるため、MongoDBクラスターを少しずつ構築するのは簡単です。

テンプレートの作成に関する最後のアドバイスは、他のGitHub MongoDBCloudFormationテンプレートから適切なものをコピーすることです。以下を使用して、RAID10を使用するレプリカサーバーを作成しました(非常に高価なAWSプロビジョニングされたIOPSディスクの代わりに)。

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

あなたの質問では、自動スケーリングについて言及しました-私の好みは、シャードを追加するか、壊れたインスタンスを手動で置き換えることです(自動スケーリングは、Tomcat/ApacheなどのWebコンテナーでは意味がありますが、MongoDBクラスターは時間の経過とともに実際にゆっくりと成長するはずです)。ただし、監視は非常に重要です。特に、ディスクがいっぱいになったときに警告するシャードサーバーのディスクサイズが重要です(したがって、新しいシャードを追加してデータを削除できます)。 AWS CloudWatchメトリクス/アラームを使用するか、MongoDB MMSサービスを使用すると、モニタリングをかなり簡単に行うことができます。

シャード内のレプリカの1つなど、ノードがダウンした場合は、サーバーを強制終了し、CloudFormationテンプレートを使用してサーバーを再作成すると、ディスクが自動的に同期されます。インスタンスがダウンし、通常は再構成が必要ない場合、これは私の通常のフローです。私は過去にサーバーを修正しようとしてあまりにも多くの時間を無駄にしてきました-時には幸運なこともあればそうでないこともあります。私のバックアップ戦略は、データベースの重要なコレクションのmongodumpを1日1回、crontabZipを介して実行し、AWSS3にアップロードします。これは、核オプションが発生した場合(データベースが完全に破損した場合)、データベース全体とmongorestoreを1時間または2時間で再作成できることを意味します。

ただし、新しいシャードを作成する場合(スペースが不足しているため)、構成が必要です。たとえば、新しいShard 3を追加する場合は、2つのレプリカノードを作成します(たとえば、プライマリの名前は=> mongo-s3r1 /セカンダリのname => mongo-s3r2)と1つのアービター(たとえば、名前mongo-s3r-arb)の場合、MongoDBシェルを介して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シャードのインスタンスが作成された後でこれを実行するだけです。

とにかく、それはその問題についての私のかなりとりとめのない考えです。主なことは、テンプレートを配置すると、人生がはるかに簡単になり、努力する価値があります!頑張ってください! :-)

40
bobmarksie