サイバーエージェントを支える技術者たち

第25回MongoDB最前線! 効果的なシャーディングとバックアップ

「MongoDB」は、スキーマレスであることやスケールアウトが容易なこと、さらにレプリケーションのしくみが用意されているといった特徴から急速に人気を集めている、オープンソースのドキュメント指向データベースです。第21回で、MongoDBの基本的なしくみや開発時における注意点などをサイバーエージェントの技術者に解説していただきました。今回は後編ということで、運用時におけるポイントについて伺っていきます。

Ameba PicoやピグライフでMongoDBを実運用

サイバーエージェントにおいて、MongoDBはすでにいくつかのプロジェクトで活用されていますが、その1つにアメリカ向けのアメーバピグであるAmeba Picoが挙げられます。松下雅和氏は2011年1月に入社し、このAmeba Picoの運用にアサインされたことでMongoDBを使うことになったと話します。

松下雅和氏
松下雅和氏

「前職ではMongoDBを使ったことはなかったので、サイバーエージェントに入社してから勉強し始めました。最初は前任者の使い方を見つつ使い方を覚える、という感じですね。ちなみに私が運用を担当することになったAmeba Picoでは、実はKey/Valueストア的な使い方がメインで、Valueにはバイナリに変換されたデータを保持しています」⁠松下氏)

アメーバピグの新たなソーシャルゲームとして注目を集めるピグライフでもMongoDBは使われています。その運用を担当する並河祐貴氏は、事前に十分な検証を行い、これなら大丈夫だと判断したうえで導入に踏み切ったと言います。

並河祐貴氏
並河祐貴氏

「運用面から事前に検証したのは、安定して運用ができるのか、トラブルが発生した際にリカバリが問題なく行えるかといった点です。たとえばMongoDBには、障害発生時に自動的にハードウェアを切り替えるレプリカセットと呼ばれるしくみが用意されています。そこで実際にサーバの電源をいきなり引き抜き、きちんとフェイルオーバーするかどうかなどを確認しました。こうした機能や仕様をひとつずつ実際に確認して、最終的に実際に使っても大丈夫だという判断に至りました」⁠並河氏)

実際に運用に入っても、今までのところ問題なく動作しているとのこと。本番環境において、ハードウェア障害によりサーバがダウンしたというケースもあったそうですが、そのときも自動的にバックアップ機に切り替わり、サービスも問題なく継続できたということで、可用性に関しての心配は少ないようです。

シャーディング利用時はデータのバランシングが鍵

実際にデータストアを運用する際、可用性とともに気になるのはパフォーマンスでしょう。このパフォーマンスの観点で重要になるのは、やはり搭載しているメインメモリの容量だと並河氏は指摘します。

「メインメモリ上にデータがある間はそれなりのパフォーマンスが得られますが、そこから溢れてディスクに落ちていくと、どうしてもパフォーマンスは低下してしまいます」⁠並河氏)

さらにポイントになるのは、シャーディング構成におけるそれぞれのハードウェア構成です。シャーディングとはMongoDBに搭載されている負荷分散のためのしくみであり、サーバの増設によるスケールアウトを可能にします。ただ、このシャーディングを利用する際は、それぞれのサーバの性能をできるだけそろえるべきだと松下氏は指摘します。

「Ameba PicoはAmazon EC2を使って運用しているのですが、一時期ハイスペックなインスタンスとスペックの低いインスタンスが混在する状況になったのです。そのとき、MongoDBの動作が安定しないという状況に陥り、最終的に各インスタンスのスペックを合わせるという作業を行いました。実はMongoDBのシャーディングにおけるバランシングはけっして賢いものではなく、サーバのスペックに関係なくデータを分散します。そこでサーバのスペックが違うと、このシャードだけが遅いといった状況が発生してしまうわけです」⁠松下氏)

サーバのスペックやデータのアクセス頻度などを鑑み、適切に各シャードにデータを分散してくれるのが理想ですが、現状のMongoDBにはそこまでの機能はありません。そのため、どのように分散されてもパフォーマンスを維持するために、サーバのスペックをそろえておくべきということです。

ただ、いくらサーバのスペックをそろえても、アクセス頻度の高いデータが特定のサーバに偏ってしまうという状況は起こりえます。こうした場合には、データの偏りに合わせて高性能なサーバを配置するのもポイントの1つだと話すのは並河氏です。

「ピグライフでは現在46シャードあり、サーバの種類は基本的にそろえています。ただ、どうしても偏りが出ている部分があって、バランシングがうまくできていない、一部のシャードにクエリが集中するという状況は起こってしまいます。そうしたシャードに対してはメモリやストレージをフルに活用できるハイスペックなサーバを配置するといったことも検討してもよいかもしれません」⁠並河氏)

アクセス頻度の高い複数のデータが特定のシャードに集中してしまうと、パフォーマンス上のボトルネックが発生します。そこで手運用でデータの配置をコントロールすることもあるとのこと。

「MongoDBの運用において、シャーディングを構成している各シャードをモニタリングし、今どれくらいクエリが来ているのか、あるいはロックがどれくらいかかっているのかというのは、けっこうチェックしています。それでデータの状況を見て、あるシャードに偏りが発生しているということがわかれば、メンテナンスの時間を利用して手動でデータ(チャンク)を移動する、といった対応も行っています」⁠並河氏)

各シャードへのデータの分散については、開発時点から考えておくべきだと話すのは松下氏です。

「MongoDBでは、どのシャードにデータが配置されるかはシャードキーによって決まります。たとえばユーザ情報のようなデータはできるだけ各シャードに均等に分散させるべきなので、なるべくランダムな数値をシャードキーとして設定しておきます。逆に、履歴情報で日付をシャードキーにしてしまうと、同じサーバに連続して書き込みが行われるといったことになるので、それ以外の値をキーとして使うといったことを考えておくべきだと思います」⁠松下氏)

シャードを追加するタイミングには注意すべき

シャーディングを利用していれば、新たなサーバを利用してシャードを追加し、パフォーマンスを引き上げるといったことができます。そこで気になるのは、どの程度簡単にシャードを追加できるのかというところではないでしょうか。この点について並河氏は、⁠MongoDBはシャードの追加がオンラインですごく手軽にできます。サーバさえあればパフォーマンスを向上できるのはすごく便利ですね」と評価します。ただ、シャードを追加するタイミングは注意すべきだと話すのは桑野章弘氏です。

桑野章弘氏
桑野章弘氏

「一時的にロックがかかるなど、シャードの追加にはそれなりのリソースを消費します。そのため、状況によっては若干レスポンスが低下してしまうといったことも起こりえるので注意が必要ですね。どうしてもすぐにシャードを追加したいといった場合、あるいは1シャードや2シャード程度であればオンラインで追加してしまいますが、30~40シャードを一気に追加するといった場合はメンテナンスに合わせて対応するほうが望ましいですね」⁠桑野氏)

ちなみにMongoDBのモニタリングには、サーバの監視などに使われているMuninにMongoDB用のプラグインを追加して利用しているとのこと。これにより、たとえばロックの頻度などといった数値をグラフ化してチェックすることが可能になります。

可用性やスケールアウトの点で構築/運用の手間を省けるMongoDB

MySQLなどを運用する際、用途などに応じてパラメータの内容を検討しておくといった作業は極めて重要でしょう。では、MongoDBではどうなのでしょうか。

「まったく必要ないわけではありませんが、MySQLのようにバッファのキャッシュ量を調整するといった細かな設定を考えることはありません。最初に設定するのはジャーナリングのオン/オフと、シャードのチャンクサイズ、サーバ間でレプリケーションを行うために使われるOplog(オペレーションログ)の大きさくらいです。ただ、Oplogの大きさについてはデフォルト値で特に困ったことはないので、特に修正していません」⁠桑野氏)

では、MySQLと比べて運用の手間はどの程度違うのでしょうか。その点について伺ったところ、冗長性の確保やスケールアウトの手間が省けるという答えが返ってきました。

「MySQLの場合、可用性を担保するために冗長構成を考えておく必要がありますが、MongoDBであればレプリカセットのしくみを使えば済んでしまうので、そういう意味ではMongoDBのほうが楽ですね。また、シャーディングのしくみが最初から用意されているのも大きなポイントだと思います」⁠桑野氏)

ただ、その一方でこなれていない部分もあると言います。具体的に指摘されたのはMongoDBにアクセスするためのドライバの安定性です。

「ドライバのバージョンを上げたところ、データを正常に取得できなくなるなどのトラブルに遭遇しました。ドライバの完成度はけっこうネックになるイメージです」⁠桑野氏)

トラブル発生時の手戻りへの対処がバックアップ検討のポイント

そのほか運用上で苦労する点として挙げられたのは、トラブル発生時に正常な状態まで戻すといったことを行うためのしくみがないことです。

「MySQLのバイナリログのようなものがないので、特定のポジションに戻れないのが厳しいという場面はあります。単純にバックアップであればmongodumpコマンドなどを使えばデータファイルをすべて取得できるのですが、障害が発生したので1時間前の状態に戻す、といったことはできないわけです」⁠桑野氏)

mongodumpコマンドを利用すればオンラインでバックアップを取得できるなど、通常のフルバックアップであれば苦労することはないと言います。ただ、バックアップポリシーについては、試行錯誤が続いているようです。

「最初は1日1回の間隔でバックアップを行っていたのですが、そうするとトラブルが発生した際に最大で1日前の状態にまで戻ってしまうことになります。それはやはり厳しいということで、トラブル発生の直前の状態には戻せなくても、たとえば2~3時間前には戻せるといった形にしようと考えています」⁠桑野氏)

画像

MongoDBを運用するうえで知っておきたいポイント

そのほか、苦労した点として松下氏が話すのはドキュメントの問題です。

「バージョンによって機能が違うため、たとえばドキュメントを参照してトラブルに対応しようとしても、前提となるMongoDBのバージョンが違っていて役に立たなかったといったことがありました。また、気が付いたらドキュメントの内容が変わっていたということもあるので、たまに見直しています」⁠松下氏)

オペレーションミスが思わぬトラブルに発展することもあるようです。松下氏が経験したのは、サーバによってディレクトリ構成が異なり、リカバリしようとしたところ、データがロストした状態で復旧されてしまったというもの。バックアップを取得していたため大きな問題にはならなかったようですが、なかなか気付きにくい点だけに注意が必要ではないでしょうか。

またシャーディングの機能においても、サーバの設定を間違えるとリカバリが効かないなど、⁠オペレーションミスしたときのダメージが大きい」と話すのは桑野氏。こうした運用上のミスをカバーするようなしくみの追加は、MongoDBの今後のバージョンアップにおいて期待されるところではないでしょうか。

このように注意すべき点がある一方、やはりシャーディングやレプリカセットのしくみが最初から提供されているのは、MongoDBの大きな強みでしょう。またアプリケーションの開発においても、スキーマレスで利用できる柔軟性の高さは魅力的です。今後、新たなデータストアとしてMongoDBが広まっていく可能性はやはり高そうです。

サイバーエージェント公式エンジニアブログ
URL:http://ameblo.jp/principia-ca
エンジニアの生の声を週替わりでお届け中!

おすすめ記事

記事・ニュース一覧