はじめに
以下記事にて作成したレプリカセットが機能していることをPrimaryを落とすことで検証します。
環境情報
- MongoDB v4.4
- kubectl v1.18
事前準備
PrimaryのDBサーバにてデータベース/コレクションを作成して1つドキュメントを追加します。
repltest:PRIMARY> use test switched to db test
repltest:PRIMARY> db.user.insert({name:'taro', age:15}); WriteResult({ "nInserted" : 1 })
以下で追加されたメッセージが確認できます。
repltest:PRIMARY> db.user.find() { "_id" : ObjectId("5f9696f263a4ed6a7dea2952"), "name" : "taro", "age" : 15 }
この状態でSecondaryのDBサーバで操作を行うと以下のエラーとなります。
repltest:SECONDARY> show dbs uncaught exception: Error: listDatabases failed:{ "topologyVersion" : { "processId" : ObjectId("5f968edbf5c68e96b18f675f"), "counter" : NumberLong(4) }, "operationTime" : Timestamp(1603704581, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk", "$clusterTime" : { "clusterTime" : Timestamp(1603704581, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } :...
Primaryサーバの停止を再現する
以下コマンドでPodを停止します。
kubectl delete pod mongod-0 pod "mongod-0" deleted
すると自動的に復旧するも、その間のアクセスを捌くためにDBサーバが切り替わります。
実際に先ほどSecondaryとなっていたPodにアクセスすると
$ kubectl exec -it mongod-1 mongo MongoDB shell version v4.4.1 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb ... repltest:PRIMARY>
Primaryに切り替わっており先ほど通らなかったコマンドも通ります。
repltest:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.000GB test 0.000GB
Primary&Secondaryを同時に停止
いわゆる二重障害を起こしてもARBITERはPrimaryになることはありません。
$ kubectl exec -it mongod-2 mongo .... repltest:ARBITER>
これはArbiterの役割としてデータを持たずに投票だけを行う役割のため、Primaryの選出のみを行います。
終わりに
MongoDBではレプリカセットの設定を行うことで、自動的にPrimaryからSecoundaryにデータが同期されます。
そして、万が一Primaryが落ちた場合もArbiterによって新たなPrimaryを選出することで自動フェイルオーバーを行うことができるわけです。
以上、ご参考になれば幸いです。