【elasticsearch】Profile APIでクエリ解析

Profile API

elasticsearch2.2が先月リリースされ(リリースノート)Profile APIという機能が追加されました。
この機能はRDBMSの実行計画のようにクエリ実行の流れがわかる情報をAPIで提供してくれます。
スローなクエリの解析に効果がありそうだと個人的にも期待している機能です。

どうやって使う?

Profile APIの使い方はすごく簡単で、クエリ実行時にprofileをtrueにセットしてあげると

{
   "profile": true,
   "query": {
      "match": {
         "pref": "茨城"
      }
   }
}

こちらのようにクエリの実行情報を実行結果とともに返してくれます。

 {
   "id": "[GjqU-RMDQbiR3zU58ITvgA][population][2]",
   "searches": [
      {
         "query": [
            {
               "query_type": "BooleanQuery",
               "lucene": "pref:茨 pref:城",
               "time": "0.5796450000ms",
               "breakdown": {
                  "score": 6486,
                  "create_weight": 155444,
                  "next_doc": 7623,
                  "match": 0,
                  "build_scorer": 143408,
                  "advance": 0
               },
               "children": [
                  {
                     "query_type": "TermQuery",
                     "lucene": "pref:茨",
                     "time": "0.2137220000ms",
                     "breakdown": {
                        "score": 3054,
                        "create_weight": 92406,
                        "next_doc": 2069,
                        "match": 0,
                        "build_scorer": 116193,
                        "advance": 0
                     }
                  },
                  {
                     "query_type": "TermQuery",
                     "lucene": "pref:城",
                     "time": "0.05296200000ms",
                     "breakdown": {
                        "score": 621,
                        "create_weight": 39380,
                        "next_doc": 798,
                        "match": 0,
                        "build_scorer": 12163,
                        "advance": 0
                     }
                  }
               ]
            }
         ],
         "rewrite_time": 6780,
         "collector": [
            {
               "name": "SimpleTopScoreDocCollector",
               "reason": "search_top_hits",
               "time": "0.01149200000ms"
            }
         ]
      }
}

どんな情報が取れる?

Profile APIで取得できる情報の種類はこちらです

query Lucene内でどのようにクエリが実行されているか
collector LuceneのCollector(検索結果の収集やスコアリング、ソートなどを行うクラス)がどのように実行されているか
rewrite Luceneによって実行クエリがどのようにリライトされたか

そして提供される情報はどんどん増えていく予定です(suggestやhighlightなど)

出力される情報はLucene内での出来事についてなので、Luceneについて詳しくないと
細かいところまで理解することは難しそうです(自分も苦戦しています)

ただ、たとえLuceneがわからなくてもクエリのどこが遅くなってる原因なのか何となく分かる情報になっています。たとえばqueryセクションをみてますと

"query": [
   {
      "query_type": "BooleanQuery",
      "lucene": "pref:茨 pref:城",
      "time": "0.5796450000ms",
      "breakdown": {
         "score": 6486,
         "create_weight": 155444,
         "next_doc": 7623,
         "match": 0,
         "build_scorer": 143408,
         "advance": 0
      },
      "children": [
      {
         "query_type": "TermQuery",
         "lucene": "pref:茨",
         "time": "0.2137220000ms",
         "breakdown": {
            "score": 3054,
            "create_weight": 92406,
            "next_doc": 2069,
            "match": 0,
            "build_scorer": 116193,
            "advance": 0
         }
      },
      {
         "query_type": "TermQuery",
         "lucene": "pref:城",
         "time": "0.05296200000ms",
         "breakdown": {
            "score": 621,
            "create_weight": 39380,
            "next_doc": 798,
            "match": 0,
            "build_scorer": 12163,
            "advance": 0
         }
      }
    ]
  }
]

こちらはアナライズされている県名のフィールドに「茨城」で検索した場合のProfileですが
LuceneのBooleanQuery全体で0.579ms、その子どもとなるTermQueryでそれぞれ0.213ms、
0.052msかかっていることがわかります。

ちなみに各項目は

query_type Lucene内で実行されるクラス名
lucene Luceneクエリ
time 実行時間(ms)
breakdown 時間がどのように使われたかの詳細

とのことです。

おわりに

スローなクエリにはProfile API!とだけ覚えて帰っていただければと思います。

10分でサーバリソース監視ができるTopbeat

はじめまして。
備忘録も兼ねてブログを始めてみました。
今後はこの頃仕事でよく使っているelastic社のプロダクトやelasticsearchのTipsを中心にいろいろと書いていけたらと思っています。
よろしくおねがいしますm(__)m

Topbeat

今回はelastic社が提供するBeatsシリーズの一つ、Topbeatを紹介させてください。TopbeatはTopコマンドで収集できるようなサーバリソース情報をelasticsearchに自動で格納してくれるツールです。kibanaと連携することでZabbixやmuninの簡易版として使用することができそうです。
導入はすこぶる簡単で、インストールから設定、kibanaでの監視まで約10分くらいでできてしまいます。
10分です。

Beatsシリーズとは

エージェントとしてサーバに常駐し、なんらかの情報をelasticsearchに送るツール群をElastic社ではBeatsと呼んでいます。
BeatsシリーズはTopbeat以外だと以下の2つが公式で提供されています。

  • Filebeat
  • Packetbeat

いずれはこちらの方も記事にできればと思っています。特にPacketBeatは取得できる情報がエグいので、ぜひご紹介したいです。
これらのBeatシリーズはBeats Platformという共通の仕組みで作成されており、その仕組みを利用して新しいBeatを作成することもできます。

インストール

自分はCentOSを使ったため、RPMでインストールしました。

curl -L -O https://download.elastic.co/beats/topbeat/topbeat-1.0.1-x86_64.rpm 
sudo rpm -vi topbeat-1.0.1-x86_64.rpm

ご覧のとおり非常に簡単にインストールができます。その他、MacWindowsにもインストールができますが、どれも簡単にできるようになっています。(こちら
この他に、データを格納するためのelasticsearchとデータをよしなに表示するためのKibanaが必要になります。
後述のbeats-dashboardを利用する事も考えると、elasticsearch2.xとKibana4の組み合わせが推奨です。
elasticsearchやKibanaのインストールについては巷に情報がたくさんありますが、Beatsのページにもきれいにまとまっています。
Topbeatはelasticsearchのmapping定義用テンプレートも提供しており、以下のようにすればelasticsearchにテンプレートをセットできます。

curl -XPUT 'http://localhost:9200/_template/topbeat' -d@/etc/topbeat/topbeat.template.json

テンプレートをセットすることで各フィールドのマッピングがよりKibana向きになるのでなるべくセットしたほうが良さそうです。
ちなみにelasticsearchを利用せず、ファイルに結果を出力することもできるようですが、sarなどと変わらなくなってしまいそうので試していません^^;

設定

設定ファイルは/etc/topbeat/topbeat.ymlの一つだけです。elasticsearchをtopbeatと同じサーバにインストールした場合は設定の変更は必要ありません。
elasticsearchを別サーバにインストールする場合、topbeat.yml内の

elasticsearch:
  hosts: ["localhost:9200"]

の部分をlocalhostからelasticsearchサーバのIPアドレスに変更します。
他にも監視対象とするプロセスの指定などがtopbeat.ymlで設定できます。

取得できる情報

Topbeatはelasticsearchに以下の3つのtypeに分けてデータを投入します。

type 対象
system システム全体
process プロセスごと
filesystem ファイルシステム

各タイプごとのフィールドはこんな感じになっています。

system

load.load1 直近1分のロードアベレージ
load.load5 直近5分のロードアベレージ
load.load15 直近15分のロードアベレージ
cpu.user ユーザーCPU時間
cpu.user_p ユーザーCPU時間の使用率
cpu.nice 優先度の低いプロセスのCPU時間
cpu.system システムCPU時間
cpu.system_p システムCPU時間の使用率
cpu.idle アイドル時間
cpu.iowait IO待機時間
cpu.irq 割り込み実行時間
cpu.softirq ソフトウェア割り込み実行時間
cpu.steal CPUリソースを割り当ててもらえなかった時間
mem.total 全メモリ容量
mem.used 使用中メモリ容量
mem.free 利用可能なメモリ容量
mem.used_p メモリ使用率
mem.actual_used 実メモリ使用容量(Linuxのみ)
mem.actual_free 実際の利用可能メモリ容量(Linuxのみ)
mem.actual_used_p 実メモリ使用率(Linuxのみ)
swap.total スワップメモリ容量
swap.used 使用中スワップメモリ容量
swap.free 利用可能なスワップメモリ容量
swap.used_p スワップメモリ使用率
swap.actual_used スワップメモリ使用容量(Linuxのみ)
swap.actual_free 実際の利用可能スワップメモリ容量(Linuxのみ)
swap.actual_used_p スワップメモリ使用率(Linuxのみ)

process

proc.name プロセス名
proc.state プロセスの状態。"running"とか"zombie"とか
proc.pid プロセスID
proc.ppid 親プロセスID
proc.cpu.user プロセスが消費したユーザーCPU時間
proc.cpu.user_p プロセスのユーザーCPU時間の使用率
proc.cpu.system プロセスが消費したシステムCPU時間
proc.cpu.total プロセスが消費した総CPU時間
proc.cpu.start_time プロセスが開始された時間
proc.mem.size プロセスが持つ仮想メモリの総量
proc.mem.rss プロセスが占有するメモリ容量
proc.mem.rss_p プロセスのメモリ使用率
proc.mem.share プロセスが使用する共有メモリの容量

filesystem

fs.avail 使用可能ディスク容量
fs.device_name デバイス名
fs.mount_point マウントポイント
fs.files 総ファイルノード数
fs.free_files 使用可能なファイルノード数
fs.total ディスク容量
fs.used ディスク使用容量
fs.used_p ディスク使用率

topやsar、dstatで取得できる項目の多くが取得できますね。

beats-dashboard

BeatsシリーズではTopbeatやPacketbeatのためにKibana4向けにダッシュボードのテンプレートを提供しています。
こちらのテンプレートをKibanaにインストールするだけで、Topbeatが収集したデータをいい感じに俯瞰できるダッシュボードが手に入ってしまいます。
まさにいたれりつくせり・・・
インストールの仕方は簡単で、elasticsearchが入っているサーバ上でこちらのコマンドを実行するだけです。

curl -L -O http://download.elastic.co/beats/dashboards/beats-dashboards-1.0.1.tar.gz
tar xzvf beats-dashboards-1.0.1.tar.gz
cd beats-dashboards-1.0.1/
./load.sh

elasticsearchが別サーバにある場合、load.shの後ろにelasticsearchのURLを付け加えます。

./load.sh "http://localhost:9200"

インストールされたTopbeat用のダッシュボードはこんな感じになります。
f:id:oasis440:20160203082557p:plain
システム全体・プロセスごとのリソース使用状況がひと目で分かるようになっています。
これだけでサーバ監視が事足りてしまうサービスもたくさんあるのではないかと思います。
見たいフィールドをグラフ化したい場合もKibanaなのでカスタマイズも簡単です!

おわりに

簡単にサーバリソース監視環境を作れるツールとして、Topbeatを紹介させていただきました。
 ・インストールが簡単
 ・設定が簡単
 ・グラフ化が簡単
 ・ビジュアルは結構イケてる
あたりが伝わっていれば嬉しい限りです。
最後にお詫びになりますが、書いた手順でを自分で一通りやってみたところ13分38秒かかってしまいました・・・
ですがデキる人は10分もかからないと思うのでタイトル等は10分のまま行かせていただきます。
内容に間違いがありましたらコメントでいただけると幸いですm(__)m