Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【MongoDB】DockerComposeでクラスター構成のMongoDBを作る

こんばんは葛の葉です。今回から土曜更新に変更します。

さて、今回はDockerComposeでクラスター構成のMongoDBを構築します。

imageのバージョン

mongo:4.2.1-bionic

DockerComposeの記述

クラスター構成のDBを構築するのだったら、ネットワークやら何やら色々設定してくれるDockerComposeとの相性が良いでしょう。

version: '3'
services:
  a:
    image: mongo:4.2.1-bionic
    command: ["--replSet", "hogehoge"]

  b:
    image: mongo:4.2.1-bionic
    command: ["--replSet", "hogehoge"]

  c:
    image: mongo:4.2.1-bionic
    command: ["--replSet", "hogehoge"]

  node:
    image: node:8.16.1-alpine
    tty: true
    working_dir: /var/work
    volumes:
      - "./work:/var/work"

このような感じでcommand:["--replSet", "hogehoge"]と与えます。

docker-composeでのcommandはコンテナ生成時に実行されるコマンドです。そのため今回のような--replSet hogehogeというコマンドの指定の方法は正しくないように思えます。ですが、mongodbのイメージにおいてはmongodというコマンドをエントリーポイントにしているので、今回のこのような記述が可能となっています。

dockerにおけるエントリーポイントについては過去記事も参考にしてください。

kuzunoha-ne.hateblo.jp

--replSet hogehogeとはhogehogeという名前領域をもつレプリカセット名になります。このコマンドをそれぞれのMongoDBにこしらえることでhogehogeという領域の中で3つのMongodbが存在していることになりました。

docker-compose up -dとすれば4つのサービスが立ち上がります。

$ docker-compose up -d
Creating network "*****_default" with the default driver
Creating ***_b_1    ... done
Creating ***_node_1 ... done
Creating ***_c_1    ... done
Creating ***_a_1    ... done

そうして立ち上がったmongodbのサービス一つのMongoDBクライアントを呼び出し,rs.initiate()というコマンドを実施します。このrs.initiate()こそがレプリカセットを構築するコマンドになります。

$ docker-compose exec a mongo
~~~~なにやらMongoDBめいた文章がたくさん~~~~~

> rs.initiate();
{
    "info2" : "no configuration specified. Using a default configuration for the set",
    "me" : "fd9679ed9f56:27017",
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1571919088, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1571919088, 1)
}
hogehoge:SECONDARY> 

帰ってきたコンソールの文字がhogehoge:SECONDARY>となっているかと思います。(あるいはPRIMARY)

帰ってきたら今度は他のMongoDBをレプリカセットに追加します。rs.add({ host:"b:27017" })rs.add({ host:"c:27017" })としましょう。

hogehoge:PRIMARY> rs.add({host: "b:27017" })
{
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1571919442, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1571919442, 1)
}
hogehoge:PRIMARY> rs.add({host: "c:27017" })
{
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1571919445, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1571919445, 1)
}
hogehoge:PRIMARY> 

rs.conf()と打てば今の設定がきちんとクラスター構成になっているか確認できます。members以下が先程追加したDBたちであれば成功しています。

hogehoge:PRIMARY> rs.conf()
{
    "_id" : "hogehoge",
    "version" : 3,
    "protocolVersion" : NumberLong(1),
    "writeConcernMajorityJournalDefault" : true,
    "members" : [
        {
            "_id" : 0,
            "host" : "fd9679ed9f56:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
                
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
        {
            "_id" : 1,
            "host" : "b:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
                
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
        {
            "_id" : 2,
            "host" : "c:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
                
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : -1,
        "catchUpTakeoverDelayMillis" : 30000,
        "getLastErrorModes" : {
            
        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("5db194f08de825642be0bed5")
    }
}

今回の接続に関して

同じDockerCompose内にあるnodeサービスから接続する場合、URIは以下のようになります。

mongodb://a:27017,b:27017,c:27017/?replicaSet=hogehoge

Nodejsから接続をするにはMongoDBのドライバなどをインストールしましょう。

mongodb.github.io

www.npmjs.com