モニタリングのためにLibratoを導入しようとしてどのように失敗したか

こんにちは、インフラストラクチャー部の菅原(@sgwr_dts)です。

インフラストラクチャー部は基本的にクックパッドのインフラに関わる業務を行っていますが、関連会社やグループ会社のインフラまわりについても作業を行ったりお手伝いしたりします。今回、グループ会社である「みんなのウェディング」のAWS化に伴ってそのお手伝いをさせていただいたので、そのときのモニタリングシステムの構築についての失敗談をお話ししたいと思います。

みんなのウェディングのAWS移行

みんなのウェディングは2015年4月にクックパッドグループに加わった結婚式場の口コミサイトです。いままでみんなのウェディングはVPSのホスティングサービスで動いていたのですが、グループ会社化に伴って大規模なリニューアルを進めており、その一環としてAWSへの移行を行いました。

AWSへの移行作業では様々な要素を検討する必要があります。パフォーマンス、セキュリティ、コスト、可用性、データマイグレーション……etc。それらのひとつにモニタリングシステムの構築があります。サービスはダウンしていないか? 一部のサーバに過剰な負荷がかかっていないか? リソースに十分な余裕はあるか? 等々、サービスの健康状態のモニタリングはとても重要です。

今回、AWS上のモニタリングシステムを構築するに当たって、私はLibratoというクラウドサービスを利用してモニタリングシステムを構築しようとしました。

Libratoはメトリクスの可視化・モニタリングを行ってくれるモニタリングクラウドサービスです。システムから送信したメトリクスをグラフにして、設定した閾値に従ってアラートを上げることができます。競合するサービスとしてはDatadogNew Relicなどがあげられます。

このLibratoを使って運用の手間を少なくしてスマートなモニタリングシステムを構築しようとしたのですが……結論から言うと失敗しました。

クラウドサービスでのモニタリングシステム構築

既存のモニタリングシステムはいろいろありますが、MuninやNagiosのようにメトリクスの可視化と監視を別々に行うものもあれば、Zabbixのようにそれらを1つのツールで行うものもあります。また、EC2の上に自前でモニタリングシステムを構築せず、クラウドサービスを利用する方法もあります。 今回は以下の様な観点から選定対象を絞り込みました。

  • インフラエンジニアが少ないのでなるべく運用に手間をかけたくない
  • メトリクスの可視化と監視は同時に行いたい
  • GUIでの操作がわかりやすい、手間がかからない
  • APIでプログラマブルに操作が可能
  • グラフがきれいで見やすい
  • 費用はなるべく抑えたい

最終的に、モニタリングクラウドサービスであるDatadogとLibratoを比較検討しました。

  • 機能面ではDatadogの方がかなり優れていました。Libratoはグラフ化・ダッシュボード・アラート、と基本的な機能のみ。グラフの種類もDatadogほど豊富ではありません。とはいえ、モニタリングシステムとしては(1つの点をのぞいて)必要十分な機能がそろっていたと思います
  • 価格面ではLibratoほうが安くしやすい課金体系でした。Datadogはホスト単位の課金、Libratoはメトリクス単位の課金です。大量のメトリクスを収集する場合、DataDogの方がコストパフォーマンスが良さそうなのですが、モニタリングに必要なメトリクスがかなり絞られていたため、サーバあたり$1〜$2/月とかなりコストを抑えることができそうでした。また将来的にサービス単位のメトリクスを収集・可視化することも考えており、その点でもLibratoの課金体系は都合の良いものでした
  • APIは、どちらもきちんとしたものが用意されています。プログラムを使った省力化はどちらでも行えそうでしたが、Libratoは低機能故にデータ構造がシンプルで後述のコード化を簡単に行えそうでした

主に価格の低さと以下の理由から今回はLibratoを採用してみることにしました。

fluentdを使ったメトリクスの収集

前述の機能比較で「(1つの点をのぞいて)必要十分」と但し書きを付けたのは、Libratoにはメトリクス収集用のエージェントが存在しないためです。普通に考えればその時点ですぐに検討の対象から外れるのですが、メトリクス収集エージェントについてはアイデアがありました。それはfluentd+fluent-plugin-dstatを使ってメトリクスを収集するというものです。

fluent-plugin-dstatはコマンドラインのリソース統計ツールdstatを使ってメトリクスを収集し、それをfluentdに流すプラグインです。これをメトリクス収集エージェントとして使おうと思ったのは次のような理由からです。

  • dstatで監視対象のメトリクスの大部分をまかなえる。また足りないメトリクスもプラグインで追加できる
  • fluentd(td-agent)は基本的にすべてのサーバにインストールされており、流したデータをいろいろなツールで柔軟に活用できそう
  • モニタリングシステムとコマンドラインの統計ツールを一元的に管理できる

3つ目の理由については、モニタリングシステムとは別にdstat・vmstatのようなツールで「その場」のメトリクスを調べることがそれなりにあり、特定のミドルウェア用にXXXstatをインストールしたり自作したりすることがあったので、それらを一元的に管理してdstatのプラグインに集約することで、監視の追加やstatツール作成の手間を軽減することをねらったものです。

Libratoのコード化

Libratoのようなクラウドサービスを使う場合、運用の手間は確かに減らせるのですが、反面、Web GUIからの作業—マウスポチポチ業が増えていきます。確かにちょっとした作業であればGUIは簡単でよいのですが、たくさんの変更を行う必要がある場合にはとても手間がかかります。また、人力の作業なのでオペレーションミスも起こしやすくなります。一般的にクラウドサービスはAPIを用意することでプログラマブルにオペレーションを行えるようにしています。しかし、普通のミドルウェアの「設定ファイルを変更して設定ファイルを再読込させる」といった作業に比べると若干面倒です。

これに対して私は「サービスの設定をDSLで定義して、設定ファイルの変更の様にオペレーションを行えるようにする」という方法をよくとります。以前の書いた記事でも、そのためのツールを紹介させていただきました。

LibratoのきれいなAPIとシンプルなデータ構造では同様のアプローチがとりやすく、そのためのツールであるlbrtを作成しました。このツールではグラフ・アラート・ダッシュボードをすべてRuby DSLで定義することができます。

たとえば、ダッシュボードを定義するRubyコードは以下のようになります。

space "My Space1" do
  chart "chart1" do
    type "stacked"
    stream do
      metric "login-delay"
      type "gauge"
      source "*"
      group_function "average"
      summary_function "average"
    end
  end

  chart "chart2" do
    type "line"
    stream do
      metric "login-delay2"
      type "gauge"
      source "*"
      group_function "breakout"
      summary_function "average"
    end
  end
end

GUIで作成したダッシュボードなどをExportしてコピーアンドペーストで増やしていくこともできますし、DSLはRubyコードなので、AWSのAPIからサーバの情報を収集しそれに併せて自動的にグラフ・アラート・ダッシュボードを増やすことができます。

といった感じで、fluentdを使ったメトリクス収集を行うようにし、lbrtがある程度できた時点ではうまくいきそうだと考えていました。 このときは。

メトリクスが足りない!

dstatは様々なメトリクスを収集できますが、同梱されているプラグインですべてのメトリクスをすべて収集できるわけではありません。ApacheやSolrなどのいくつかのミドルウェアについてはプラグインを探すか作るかする必要があります。しかし、dstatのプラグインはHubサイトのようなものが存在せず、またコミュニティ製のプラグインを探してもほとんど見つかりません。そのため、大半のプラグインは自作する必要があります。しかし、Pythonに明るい人間がそれほどおらず、AWS移行のためのその他の作業もあって、サービスインまでにプラグインを全て自作するのは難しい状況でした。

いろいろ考えた末、この問題の解決策としてzabbix-agentを使ってメトリクスを収集することにしました。実はモニタリングをすべてクラウドサービスに委譲した例が今までなく、保険としてZabbixを使ったモニタリングシステムも一応は準備しておいたのです。dstatのプラグインは少ないですが、zabbix-agentのプラグインは山のようにあります。fluent-plugin-zabbix-agentというzabbix-agentのデータをfluentdに流すためのプラグインも作成し、とりあえず必要なメトリクス収集はできるようになりました。

しかし、このあたりから本末転倒感が漂ってきました。

グラフ・アラートが足りない!

当然のことながら、メトリクスが収集できれば終わりというわけではなく、それをグラフにしてダッシュボードに配置して適切なアラートを設定する必要があります。lbrtにはテンプレートの機能が備わっているので、OSやMySQL・Apacheなどミドルウェアごとにテンプレートを作成してやれば、半自動的にグラフ・ダッシュボード・アラートが設定されます。しかし、自作のツールであるlbrtに既存のテンプレートがあるわけがなく、すべてのテンプレートを1から書くことになります。書くべきテンプレートはOS、MySQL、Apache、Nginx、Solr、RDS、ElastiCache、ELB、Rails……

ここにいたって締め切りにはとても間に合わないと悟り、Libratoを使ったモニタリングシステムの構築はあきらめました……

結局……

最終的には、予備として準備しておいたZabbixをきちんと整えてサービスのモニタリングを行っています。Zabbixは広く使われているモニタリングツールなので、必要なテンプレートはすべて既存のものを利用することができました。AWSとの連携については、スクリプトを書いてcronや自動登録で連携できるようにしました。ダッシュボード(スクリーン)に関しては、ホスト毎のメトリクスを俯瞰的に見るダッシュボードを手動、またはAPIで作り込むことは大変だったため、Muninのようにホストごとのグラフ一覧を自動的に見られるようにするWebアプリケーションを自作しました

当初のもくろみは完全に失敗してしまいましたが、一応、十分に安定したモニタリングシステムを構築することはできました。

今回の件については、OS・ミドルウェア毎のメトリクス収集に必要な作業が完璧に抜け落ちており、作業量の見積もりが完全に間違ってしまったことが、失敗の大きな要因と考えています。それを踏まえた上で、Datadogや他のサービスについて利用事例をもっと詳しく調べられていれば、Libratoに無駄な工数をさくこともなかったかもしれません。Zabbixが保険として機能してくれたのは不幸中の幸いでした。

フォローしておくと、Librato自体はスケーラビリティがありコストに優れた良いクラウドサービスです。今回はLibratoがあまりカバーできていない範囲を無理矢理がんばろうとしたことが問題だったと思います。

同様のモニタリングシステムを検討・構築しているかたがいましたら、この記事が参考になれば幸いです。

インフラストラクチャー部では、意欲的なシステムの構築に挑戦したい仲間を積極募集中です!