はじめまして。インフラ&コアテク本部の鳥垣と申します。普段はAmeba Smart Phone PlatformやAmebaの基幹系サービス全般のインフラを見る仕事をしております。
昨今fluentd + Elasticsearch + kibanaを使ったリアルタイムモニタリングが流行っていますが、これを使ってCassandraのステータスをモニタリングするシステムを作ってみましたので、そのお話をさせていただければと思います。
以前にWebSocketで監視もリアルタイムにという記事でもあるとおりリアルタイムモニタの仕組みはありましたが、kibanaの検証も兼ねてリアルタイムのグラフ描画にチャレンジしてみました。
KibanaとNginx
Cassandraのステータス取得はJolokiaを使います。今回は以下の値をグラフにしてみました。
※値は5秒ごとに取得しています。
また、上記のJolokiaからの取得以外にもnodetool cfstatsからcolumn familyのステータスを取得してグラフ化したりもしています。
cfstatsからは以下の値を取得しています。
ただし、column familyが100を超えるほどあるため、ポーリング間隔は10秒ごとにしています。
ReadStage Pendingのグラフを作成する場合は「QUERY」にて以下のように項目を入力します。
※hostnameに「-」が入っている場合、topNを使った複数サーバのグラフを重ねて描画する箇所でうまく描画できなかったため、「-」を「_」に変換しました。
※Cassandraを再起動した場合、fluentdの再起動も必要になります(Jolokiaからの取得ができなくなってしまうため)。
構築のきっかけ
こちらのサイトにてdstatのモニタリングをkibanaでやっている記事を拝見し、Cassandraのステータスも同じようにリアルタイムグラフの描画ができないかと考えました。以前にWebSocketで監視もリアルタイムにという記事でもあるとおりリアルタイムモニタの仕組みはありましたが、kibanaの検証も兼ねてリアルタイムのグラフ描画にチャレンジしてみました。
システム構成
- ElasticSearchは3台でクラスタ構築しています。
- indexの保持期間は3日間にしています。
- ElasticSearchサーバのIP変更などが発生した場合などを考慮してfluentdの取得データは一旦kibanaサーバに集約するようにしています。
セットアップ
ElasticSearch- 公式サイトから最新版のRPMをダウンロードしてインストール。
- Heapをメモリの半分までを割り当てる。
- 3台でクラスタ組むように設定(負荷分散と冗長性を考慮してクラスタを構成)。
- ElasticSearchのステータス監視用にプラグインのHQとheadをインストール。
- elasticsearch.ymlの設定は以下のとおり(変更箇所のみ抜粋)
cluster.name: cluster name node.name: "node name" node.master: true node.data: true index.number_of_shards: 5 index.number_of_replicas: 2 discovery.zen.minimum_master_nodes: 2 discovery.zen.ping.timeout: 3s discovery.zen.ping.multicast.enabled: false discovery.zen.ping.unicast.hosts: ["node ip", "node ip","node ip"]
KibanaとNginx
- yumにてNginxをインストール。Nginxはデフォルト設定。
- 公式サイトから最新版のkibanaをダウンロードして解凍し、ドキュメントルートに配置。
- kibanaサーバに集約用のfluentdをインストール。受信用設定とElasticSearchにデータを送信する設定を入れる。
- 各Cassandraノードサーバにfluentdをインストール。gemにてfluent-plugin-map, fluent-plugin-elasticsearchをインストール。Cassandraのステータスを取得する設定を入れる(詳細は後述)。
Cassandraステータスの取得
Cassandraのステータス取得はJolokiaを使います。今回は以下の値をグラフにしてみました。
bean | attribute | 項目名 |
---|---|---|
org.apache.cassandra.db:type=CompactionManager | PendingTasks | COMPACTION PENDING |
org.apache.cassandra.internal:type=FlushWriter | PendingTasks | FLUSHWRITER PENDING |
org.apache.cassandra.internal:type=HintedHandoff | PendingTasks | HINTEDHANDOFF PENDING |
org.apache.cassandra.request:type=ReadStage | PendingTasks | READSTAGE PENDING |
org.apache.cassandra.request:type=MutationStage | PendingTasks | MUTATIONSTAGE PENDING |
org.apache.cassandra.db:type=StorageProxy | RecentReadLatencyMicros | STORAGEPROXY READ LATENCY |
org.apache.cassandra.db:type=StorageProxy | RecentWriteLatencyMicros | STORAGEPROXY WRITE LATENCY |
上記をfluentdにて取得するために、fluent-plugin-jolokiaを使用しています。
fluentdの設定は以下になります。(例としてReadStage Pendingのみ記載します)
<source> type jolokia tag jolokia.cassandra.RS jolokia_url http://node_ip:8778/jolokia/ jmx_bean org.apache.cassandra.request:type=ReadStage run_interval 5s </source> <match jolokia.cassandra.RS> type copy <store> type map tag "map.cassandra.jolokia.ReadStage" time time record {"value" => record["value"]["PendingTasks"], "stat" => "ReadStage-Pending", "host" => "hostname"} </store> </match>
※値は5秒ごとに取得しています。
また、上記のJolokiaからの取得以外にもnodetool cfstatsからcolumn familyのステータスを取得してグラフ化したりもしています。
cfstatsからは以下の値を取得しています。
- Pending Tasks
- Read Latency
- Write Latency
ただし、column familyが100を超えるほどあるため、ポーリング間隔は10秒ごとにしています。
Kibanaグラフ作成
ブラウザにてkibanaにアクセスしグラフを作成します。ReadStage Pendingのグラフを作成する場合は「QUERY」にて以下のように項目を入力します。
- stat:"ReadStage-Pending"を入力
- topNを選択(全ノードを1グラフに重ねて表示させるため)
- Fieldは「host」を入力
上記グラフはCassandraノード100台分のReadStage Pendingをグラフ化したものです。
※hostnameに「-」が入っている場合、topNを使った複数サーバのグラフを重ねて描画する箇所でうまく描画できなかったため、「-」を「_」に変換しました。
※Cassandraを再起動した場合、fluentdの再起動も必要になります(Jolokiaからの取得ができなくなってしまうため)。
まとめ
kibanaを触ってみた所感を簡単にまとめてみました。好いなと思った所
- グラフをホストで重ねて表示ができる。 異常があるホストがすぐにわかる。
- 秒単位でのグラフ表示が可能 fluentdで値がとれればなんでも秒単位描画できる。
- 最初のグラフを作るときが大変。。。 1回作成すればJSONでエクスポートできるので、似たようなグラフを作りたいときはそれを編集してインポートすることはできます。
- グラフ作成に慣れが必要かなと。
- 簡単に差分表示ができない(GrowthForecastのように差分表示機能が実装されていない)。 総計値しか取得できないようなものをグラフ化する場合は、前回の値との差分を計算してから描画など工夫が必要になります。
- ElasticSearchのCPU負荷がすごいことになるw グラフ数や閲覧人数にもよりますが、ひどい時はCPU負荷だけでサーバのロードアベレージが80くらいはいきますw
なのでElasticSearchサーバはCPUコア数が多いサーバを使ったほうが無難です。
今回のシステムではElasticSearchサーバのCPUは24コアで構築しています。
画面のリフレッシュ間隔は5分程度が無難かと思います。
また、このシステムの実績を生かして今では他サービスにてApache,TomcatやMySQLなどのステータスもKibanaでリアルタイムでモニタできるようにしておりまして、特にイベントなどで負荷が局所的に高まるときなどは大変重宝しております。
今後として
ElasticSearchの負荷がやたら高くなるので、この負荷をなんとか抑える方法がないか模索していこうと思っています。また、Cassandraサーバでまだモニタリングできそうなところ(JVMのスレッド数やディスクIOなど)もグラフを増やしていければと考えております。
もしこれからリアルタイムモニタリングを導入したいとお考えの方の参考になればと思います。
また、もっとこうすれば良くなるよなどご意見あればぜひ教えていただけると幸いです。