ウェブサイト及びサーバー監視の プレミアム製品

Server Densityについて

サーバーの監視によるMongoDBの使いこなし術

今回は、Feargal Finnegan氏のゲスト記事を紹介させて頂きたいと思います。Feargal氏は、実用的なソフトウェア·アーキテクトと完全なスタックの開発者として15年間、スタートアップのビジネスに携わってきました。彼は当社にコンタクトして、インフラの問題を診断してきた自身の経験について話してくれたので、素晴らしいブログとして紹介させて頂きます。是非ともお楽しみください!

一般的に人々はMongoDBの悪口を書くのが好きです。自分も何度かトラブルシューティングをする機会があったので、同様に悪口を書こうと思ったことはありましたが、それは公平ではないと思います。- なぜならば、個人的にはMongoDBの全体的な評価は良いからです。

MongoDBで多く発生する可能性がある問題を解決する方法のガイドブックはたくさんありますが、その方面の話はここではや止めておきましょう。その代わりに、当社がはデータベースのいくつかのトリッキーな問題を特定し、修正するためにどのように監視ツールをしてきたかついて説明させて頂きます。ご自身のインフラストラクチャの問題を診断する上での実用的なアドバイスになるはずです。

local-storage

最近、Contrail Innovationsの顧客は、使用頻度とユーザーの数が急激に増えたために、MongoDBクラスタは新たな負荷に対処することが難しくなっていました。彼らは、 3つのノードのレプリカセットのように単一のシャードを実行していました。プライマリノードは、すべての読み取りと書き込み、二次ノードは、単にフェイルオーバーのために存在して、第三ノードは、 S3へのスナップショットバックアップのためで、プライマリーノードになることはできませんでした。

MongoDBのソケットの例外

まず、最初の問題は MongoDBのプライマリが2つのノード間で切り替わるようになったということでした。一つのノードは、プライマリとして設定されていましたが、複製セット内の他のノードとの接続性を失っていました。その後、接続性が復元され、別のプライマリが選択されるまで、ノードははステップダウンして、しばらくの間に選択され、オフラインになる引き金と原因となりました

SocketException以外はMongoDBログに明らかな問題は何もありませんでした。私は最近、ELKスタックを実施し、LogstashやKibana経由でログを表示するので、何が起こっているか把握することが簡単になりました。当社そのアプリの状態を把握でき、処理ノードがプライマリのMongoDBへの接続を失ったことも確認できました

MongoDBのレプリケーションログを確認することにより、多くの情報を把握でき、MongoDBのシェルからこのような操作を行うことができます。

production1:PRIMARY> show log rs.

このコードで若干なエントリがこのように始まる:
‘couldn't connect to server’

このログで、私はrsHealthPollがセット内の他のノードがダウンしたことを示していることを把握できました。時には1つのノードがダウンしていましたが、 2つのノードとコンタクトがとれなくなったら、MongoDBのが明らかにネットワークパーティションの結果として、スプリットブレイン状態に入らないようにプライマリからステップダウンしたと報告されます。実際に何が起こっているか把握するためにServer DensityMongoDBの監視により集められたグラフや統計を分析しました。それにより、注目せねばならない多くの点がはっきりしてきました。

まずは、プライマリーノードにCPUに負担が多くかかるということです。EC2上では、ほぼ確実に同じハードウェア上で実行されている別のインスタンスが、自身のインスタンスからリソースを消費してしまうという「ややこしい隣人」的な問題に苦しむことを意味します 。単に自身のインスタンスを停止し、新しいハードウェアにそれを強制する必要があります。-そうすることで隣のインスタンスの問題を解消することができるでしょう。そうすることで、CPUのパフォーマンスは改善しますが、まだ接続の問題が残っています。Linuxカーネルを確認することで、私たちはulimit設定はMongoDBバージョンの現在のドキュメントに対応する値に設定されていないことに気づきました。(MongoDBのアップグレードする度にこれらをチェックする必要があります。)推奨される設定を変更し、ローリングクラスタの再起動を行うことにより、これらの接続の問題を解決しました。

アムステルダムでの共同スペースでHackers & Foundersで働くBottlenose出身の友人の薦めにより、TCPキープアライブを変更しました。詳細の設定についてはについてはこちらを.

ご覧下さい。

ハイなIOWaitとロウなCPU

Server Densityのダッシュボード - プライマリのMongoDB

これらの変更が終わった後で、当社の顧客は成長を続け、MongoDBインスタンスのデータ量も増え続けました。Server Densityは、当社にプライマリのMongoDBでは高いIOWaitsが起こっているということを警告てきており、MongoDBの統計のさらに深く分析する必要がありました。このために、私はさらに細かな点に踏む込むために、具体的に優れMMS監視サービスを使用しました。

mms dasboard

まず最初に確認をしたのはページフォルトでした。 MongoDBは、ディスクから読み取りが必要な時にこれらの現象が発生していました。ユーザーとデータが突然の伸びたことで、それらの現象が多く発生し始めていました。 opcountersに対して確認をすることで、MongoDBがディスクIOで忙しいことを示す小さな比率が分かります。(これは既にIOWaitsから知っていたことですが)それから私は、ワーキングセットをチェックしました。 -たくさんのページのための十分なスペースがあったので、それはRAMの不足しているわけではありません。

db.runCommand({serverStatus: 1, workingSet: 1})

ページフォルトの数が多いを除いては、グラフには何も突出したことはありません。しかしながら、実行中のdb.currentOp ( )はいくつかのクエリが実行中であったことを示しました。それなので、MongoDBのプロファイリングを開始する時です。

production1:PRIMARY> db.setProfilingLevel(1, 700)

700ms以上かかっているログクエリだけをプロファイリング設定すると、私はすぐにクエリの完了までに3分の時間がかかっていることに気づきました。 MongoDBの中のインデックスのScalaのコードを確認し、私は、クエリのフィールドのいずれかが索引付けされていなかったMongoDBのひとつのフィールドが完全なスキャンを実行し、ディスクからすべてのデータを読んでいたことを発見しました。私はプロファイリングを維持し、他にも3つも 3同じ事を見つけたました – これはすごいです!なくなったインデックスを追加した後で、ページフォルト& IOWaitsはなくなりました –これで 問題は解決したことになります。
mms

server-monitoring-graph

見てください。インデックスがありません!

端的に話をします。MongoDBで非常に高いIO、低CPU、高いページフォールトが発生している場合には最善の方法は、データベースのプロファイルを作成し、すべてインデックスが欠落しているかを確認することです。コードベースが拡大すれば、クエリでインデックスを見逃すのは非常に簡単だし、クエリの結果が、ユーザーが次に直面していないのであれば、すでに問題を引き起こしていない限り、追跡するのは本当に難しいことです。

ご自身のユースケースに合った場合には、MongoDBを恐れてする必要はまったくなく、非常に信頼性が高いです。しかし、スケールアウトするには、Server DensityMMSのような監視ツールを利用して、舞台裏ですべての問題に対処する必要があります。