この記事はニフティグループ Advent Calendar 2019の8日目の記事です。
7日目は@saikeiさんの一人暮らしの寂しさを推しとIoTとLINE Botで解決した話でした!
以前、担当しているサービスで一部の目立たない機能にMongoDBが使われている部分があり、しかもそこが高負荷になって閲覧に影響が出る事態が発生しました。
普段mongoを使っていない自分は冷や汗ダラダラ、これさえ知っておけばよかったのに!!ということをまとめたものが役に立てばいいなと公開していきます。
mongoってなんなんだ
公式ドキュメントを読んだ方がよい!
https://docs.mongodb.com/
mongoのレプリケーション構成
mongoはレプリケーションの機能が備わっており、1台が死んでも、他のサーバーがバックアップとして機能することができます。
ただし、読み書きの分散はなされず、純粋にデータのバックアップとしてのみ機能します。読み書きの分散をするには、別にシャーディングの設定が必要になります。
私のサービスでも前任の方がきっちりレプリケーションの設定をしてくれていました!
これも、正確には公式ドキュメントを読んだ方がよい!!!https://docs.mongodb.com/
ですが、全編英語なので、日本語でざっくり要約します。
ざっくり
- Primary(読み書きがくるサーバー)とSecondary(バックアップ)がいる
- レプリケーションを行うには、最低3台が必要
- 1台が死んでも、あとの2台でPrimaryを投票して決めなければいけないため
- 最後に同期が完了しているものが、Primaryに昇格する
- レプリケーションは非同期
- PrimaryのOplog(どんな操作がなされたかのオペレーションログ)の内容を反映する
- 非同期とはいえ、時間差は1秒〜最大数秒程度
- 自動フェイルオーバー
- PrimaryやSecondaryはお互いの生き死にを監視し、Primaryが死ぬと自動でフェイルオーバーする
Primaryが死ぬとどうなってしまうのか
- Secondaryのうち、投票されたものがPrimaryに昇格し、ロールバックが発生する
Primaryが高負荷になってしまい、切り離したいとき
mongoのコマンドラインから以下を叩く ※Primaryからしかできません
原因がアクセス数の増加などでの負荷ではなく、Primaryのサーバー自体に不具合が発生しており、一時的にSecondaryがPrimaryを務めることで解決できる問題の場合、このコマンドだけで解決できる場合があります。
Primaryに入れないレベルの障害が発生し、SecondaryをPrimaryに昇格させたい時
基本的に、Primaryからでないと、PrimaryをSecondaryに降格できないのですが、Primaryが何らかの理由で操作できない状態になってしまった場合、
Secondaryから強制的にPrimaryを降格させることが可能です。
こちらの記事の手順でうまくいきました。https://www.greptips.com/posts/1257/
レプリカセットのいずれかで、障害が発生したため切り離したいとき
cfg=rs.config()
// 切り離したいメンバーを除いて確認する
cfg.members = [cfg.members[1],cfg.members[2]]
// Priamryから操作している場合の設定反映
rs.reconfig(cfg)
// Secondaryから操作している場合の設定反映
rs.reconfig(cfg,{force:true})
困ったときのコマンド集
レプリケーションの設定を確認する
レプリケーションの状態を見る
最後にレプリケーションがされたのがいつかを確認する
mongoやそれが乗っているサーバー自体の不具合だと、以上のコマンドや対処法で一つ一つ丁寧に確認していけばなんとか問題が解決できるような気がします。
私が直面した問題の場合、アクセス負荷が急激に増大し、indexを貼っていなかったことでレプリカセットが順々にPrimaryになる→死ぬということを繰り返し、mongo自体にアクセスができないという最悪の状態になってしまいました😇
その際は、mongoへのアクセス元を遮断し、スペックアップ・indexの構築などを行なってから、mongoをサービスに復帰させるということを行いました。
どのDBを使っても言えることですがちゃんとindexは貼りましょうね!!!!
明日は、@kanishionori さんからレトロスペクティブの話か、AmazonForecastのお話が聞けそうです!楽しみですね!