Robinhoodのサーバ運用チームは、インフラストラクチャのメトリック収集、監視、アラートに関する一連の記事を公開した。OpenTSDB、Grafana、Kafka、Riemannがスタックのコアを形成し、プロキシ層として機能するKafkaがデータをRiemannにプッシュして、ストリーム処理された結果がストレージのOpenTSDBに格納される構成だ。
Robinhoodのテクノロジスタックは大部分がPython、一部Golangで記述されている。メトリックはデバッグや、あるいは稼働サーバの監視に重要な意味を持っている。メトリックの収集は主として、さまざまなソフトウェアスタックに対応した標準コレクタ(tcollectorsと呼ばれる)を数多く備えたメトリック収集データベースのOpenTSDBを使用して行われる。OpenTSDBはさらに、収集したメトリックをTelnetまたはHTTPエンドポイントを使用してOpenTSDBにプッシュするプラグイン・カスタムコレクタもサポートする。Robinhoodの場合、メトリック情報が最初に送信されるのはKafkaプロキシである。
それぞれのサーバ上では、標準およびカスタムtcollectorがデータをKafkaに送信する。アプリケーションはstatsdライブラリを使用してインストールされ、それぞれのサーバボックスで動作するローカルのstatsdプロセスにアプリケーションメトリックを送信する。statsdサーバの実装には、Cで記述されたstatsiteを使用している。カスタムアダプタがstatsdのメトリックをローカルのtcollector用メトリックに変換し、Kafka経由でOpenTSDBに送信する。tcollectorプロセスがstdoutに出力したメトリックを、Pythonスクリプトを使ってKafkaにプッシュする仕組みだ。
OpenTSDBはメトリック収集システムのバックボーンを形成しているため、高い可用性を必要とする。InfoQはRobinhoodのオペレーションエンジニアであるAravind Gottipati氏に連絡を取り、詳細を確認した。
Robinhoodでは複数の独立したOpenTSDBインスタンスを実行しています。それぞれのインスタンスが別々に、Kafkaからの同じメトリックストリームをコンシュームします。これによって、これらOpenTSDBインスタンスのいずれかが要求に対応するロードバランシング(すべてが同じなので)が可能になります。同時にこれは、簡易的なHAでもあります。完全なHBaseクラスタは運用せず、これらのインスタンスがそれぞれ、単一ノードのHBaseサーバ(+マスタ)をローカル実行しています。
Kafkaは、複数のコンシューマが別々の方法でデータを処理可能にするための仲介として使用されている。その中のひとつがメトリックを変換し、OpenTSDBにプッシュするのだ。必要であれば、複数のOpenTSDBサーバに処理を分散して、データの増加に対処することもできる。Kafkaをプロキシとして使用することにより、メンテナンス目的でコンシューマを一時停止および再開することも可能になる。KafkaとOpenTSDBをつなぐのは、標準出力に出力するコンソールベースのコンシューマである。この出力がOpenTSDB telnetリスナに、netcatを使ってプッシュされる仕組みだ。
メトリックの表示には、Graphite、InfluxDB、OpenTSDBバックエンドをサポートする視覚化ツールのGrafanaを使用する。同じダッシュボードにCloudWatchのメトリックをプラグインすることも可能だ。
Riemannは、Robinhoodの監視および警告ワークフローの重要な部分を形成する。Robinhoodでも使用しているSensuなど、従来のアラートシステムは、メトリックの基準時間によるビューに依存している。このビューは、クエリ作成の難易度や実行に伴う高レイテンシといったさまざまな理由によって、ヒストリカルなビューと一致しない場合がある。メトリックシステムによってはヒストリカルビューをサポートしない場合もあるので、データが見つからない場合には補間しなければならない。これらのいくつかはOpenTSDBで対応できるにも関わらず、なぜRiemannが必要なのか? “OpenTSDBはHBaseに依存しており、一般的にはHBaseから鍵空間の全範囲を引き出すことに優れています。メトリックの一点を正確なタイムスタンプで引き出すことは得意ではありません。アラートにこれを使用するということは、つまり、プルアウトした結果から選択したタイムスタンプと正確に一致するものを検索しなくてはならない、という意味になります。クエリは通常はとても便利なのですが、単一のデータポイントを正確に取り出すためには、キー範囲全体をすべて検索しなくてはならないのです”、とGottipati氏は言う。
ストリーム処理では、ルールとフィルタを定義し、それらを通じてデータをストリーミングする。フィルタあるいはルールが一致すれば、アラートが発行される。Riemannでは、さまざまなソースから集約したメトリックを、ストリームとして処理言語の入力にすることができる。メトリック収集システム全体は、データをプッシュするKafkaコンシューマを使ってRiemannに結び付けられている。メトリックの命名規則はOpenTSDBの影響を受けており、各メトリックは、それぞれのイベントに関連付けられたタイプ、ホスト、ロールを、キー・バリュー・ペアのタグとして所持する。ここでもRiemannにデータをプッシュするためにnetcatが使用されている。tcollectorによって各イベントにタグ付けされたロール(Webマスタ、dbなど)は、ここでRoemannのタグに変換される。この変換と、Riemannのプリミティブ用に社内開発されたラッパDSLにより、Riemannに組み込まれているフィルタ機能を容易に利用することができる。このシステムがDevOpsコラボレーションの鍵となっている。それでは、RobinhoodでDevOps文化を導入する上で、重要なマイルストンは何だったのだろう?Gottipati氏が答えてくれた。
(statsdメトリックを表示する)アプリケーションメトリック用のダッシュボードの他に、収集したシステムメトリックを強調表示するためのダッシュボードのサンプルをいくつか開発しました。さまざまなトラブルシュートの要求に対応するために、これらのダッシュボードの供用を開始して、ベテラン達に使い始めてもらいました。しばらく使用した後、そのユーザがよりアプリケーション固有のダッシュボードを編集する支援をして、プロセスを進めました。バックエンド/アプリケーションチームはさまざまなダッシュボードの開発とメンテナンスを行なっています。その中には運用担当者が知らないものもあるので、新たに参加した技術者には、ダッシュボードの探し方と使い方をレクチャしています。
Riemann内のイベントの表示には、デフォルトのRiemannダッシュボードに代えてElasticsearch(ELS)インスタンスが使用されている。Kafkaからのイベントのおよそ50%がELSにプッシュされており、ピーク時には約20,000イベント/秒に達する。
この記事を評価
- 編集者評
- 編集長アクション