カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

Elasticsearchに触れてみたい人がやることをまとめてみた

Elasticsearch(以下ES)を触ってみたい人が周りにもちょくちょくいるので、書いてみる。半分は備忘録。

1. まずはインストール

公式サイトのインストールページ にRPMとかがあるので、インストールする。 このページにあるように、レポジトリの登録をして、インストールしてもよい。

2. 起動、動作確認をする

「/etc/elasticsearch/elasticsearch.yml」は特にいじらなくてもESは動くようになっている。

(2014/06/30: 追記) ただし、cluster.nameを設定してないと、同一クラスタ名のものが同一ネットワークにいるとクラスタを組んでしまうので、cluster.nameだけは設定しておこう。

セットアップガイドにもご丁寧に書かれているが、CentOSであれば、以下で起動できる。

$ sudo service elasticsearch start

起動したら、ログを見てエラーがないか確認する。また、9200番ポートをリッスンしていることを確認する。 それぞれ確認できたら、以下を叩こう。

$ curl http://localhost:9200

ステータスコード200で返ってくればOK。

3. プラグインを入れる

RESTFullなAPIというのは自動化する上ではすごく扱いやすいのだけれど、データがどう入っているかや、ノードのステータスがどうなっているかをぱっと確認するには少し扱いにくいように感じる。そういうときにプラグインを使う。 ということで、以下で、headmarvelプラグインを入れておこう。

$ /usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head/latest
$ /usr/share/elasticsearch/bin/plugin --install elasticsearch/marvel/latest

headに関しては、 elasticsearchのGUI「elasticsearch-head」がとても便利 - yuhei.kagayaElasticsearchのhead plugin - ほわいとぼーどなどを読むとイメージをつかみやすいと思う。marvelに関しては Elasticsearch Marvelの紹介と第一印象 - @johtaniの日記 2ndに詳しい。

headはどのインデックスにどういうデータが入っているかをぱっと見る上ですごく便利だし、marvelはリアルタイムにクラスタの状態を見る上で便利なので欠かせない。ちなみに、marvelはテスト環境での利用は無料で利用できるが、本番環境での利用は有料となるので、気をつけよう。

もちろんこれら以外にも色々プラグインはあるので、公式サイト含め多くのサイトでプラグインは紹介されているので、他にも探してみるとよい。

4. kibana, nginxのセットアップをする

ESを使うなら、やはりkibanaは欠かせないだろう。

kibanaはESにあるデータを簡単に可視化してくれる。公式サイト にいくつものグラフのサンプルが出ているが、きれいなグラフを簡単に作ることができるので、是非是非試したい。

ElasticSearch+Kibanaでログデータの検索と視覚化を実現するテクニックと運用ノウハウなどを見るとすごく詳しく書かれているので目を通しておくのをおすすめする。

kibanaはあくまでフロントのコードでしかないので、ApacheやnginxなどのWebサーバをいれて、ドキュメントルートをkibanaをインストールしたパスにする。

入れ終わったら、今度は9200番ポートではなく、Webサーバのポートにアクセスする。ダッシュボードが表示されたらOK。

とりあえずは「table」を選択して、表形式でデータを表示してみよう。 また、新しくグラフを生成したり、何かを修正した場合は、ダッシュボードを保存する癖をつけよう。最初のうちはその癖がなく、グラフをいくつも作ったのにリロードしたら全て消えてしまうということが何度かあった。そうならないためにも、保存を忘れないようにしよう。

5. データを流し込む

ESにはindex apiというのがあり、それを使うことでデータを流しこむことができる。

公式サイト にもサンプルが載っているが、以下の様なコマンドを叩くだけでいい。

$ curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

ESは、データを流し込むと全文検索の対象にするとか、データの型とかを勝手に決めてくれる。 なので、最初は何も考えずに流し込めばいい。

そして、適当にループさせて100件ぐらい突っ込んだら、kibanaのグラフを色々試してみるとよいだろう。

Elasticsearch Kibana でデータの可視化 — Hello! Elasticsearch. — Medium などのサイトでグラフの作り方を紹介されてるので、そういうのを見てまずは真似てみる。 その後、とりあえずすべてのグラフを作ってみるのが個人的にはオススメである。

6. fluentdを使って流し込む

index apiでもいいのだけれど、ログをまとめて流し込もうと考えると、fluentdがすごく便利である。

公式サイトにあるように以下のコマンドなどを使ってインストールするのがよいだろう。

$ curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh

$ sudo yum install libcurl-devel
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-forest

その後、td-agent.confを以下のように設定する。たとえば、nginxのアクセスログをESに流してみよう。

<source>
  type tail
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)")?/
  time_format %d/%b/%Y:%H:%M:%S %z
  path /var/log/nginx/default.access.log
  pos_file /var/log/fluentd/accesslog.pos
  tag es.nginx_access_log
</source>

<match es.**>
  type forest
  subtype elasticsearch
  remove_prefix es

  <template>
    host localhost
    port 9200

    logstash_format true
    logstash_prefix ${tag}
    logstash_dateformat %Y%m%d
    type_name details

    # buffering
    buffer_type memory
    buffer_chunk_limit 10m
    buffer_queue_limit 10
    flush_interval 1s
    retry_limit 16
    retry_wait
  </template>
</match>

ここでは、logtashフォーマットで、インデックス名はタグ名を使うようにしている。fluent-plugin-forestを使ってこのようにしておくと、複数のsourceがあってもconfをいじらなくて済むだろう。 あとは起動しログが流れるのを待って、headプラグインとかを使って、データが入ったか見てみよう。

7. テンプレートマッピングを使う

上述したようにESは型をいい感じにやってくれるので、慣れるまでは特に設定しなくてもいいのだろうけど、運用を考えると自分で設定できるようにしといたほうがいいだろう。

そのようなときはテンプレートマッピングを使う。

公式サイトにあるようにAPIを使ってもいいのだけれど、ここではファイルを置いてインデックス作成時に認識させる方法を紹介する。

/etc/elasticsearch/templates/nginx_access_log.json を作成し、以下のように記述しよう。

{
  "nginx_access_log": {
    "template": "nginx_access_log-*",
    "mappings": {
      "details": {
        "properties": {
          "remote": {
            "type": "string",
            "index":"not_analyzed"
          },
          "host": {
            "type": "string",
            "index":"not_analyzed"
          },
          "user": {
            "type": "string",
            "index":"not_analyzed"
          },
          "method": {
            "type": "string",
            "index":"not_analyzed"
          },
          "path": {
            "type": "string",
            "index":"not_analyzed"
          },
          "code": {
            "type": "string",
            "index":"not_analyzed"
          },
          "size": {
            "type": "string",
            "index":"not_analyzed"
          },
          "referer": {
            "type": "string",
            "index":"not_analyzed"
          },
          "agent": {
            "type": "string",
            "index":"not_analyzed"
          },
          "forwarder": {
            "type": "string",
            "index":"not_analyzed"
          }
        }
      }
    }
  }
}

ここでは「nginx_access_log-*」にマッチするインデックスが生成されたときに、型や全文検索の対象にしないことを設定している。 既存のインデックスを削除したのちアクセスログを流して、インデックスが作成されることを確認しよう。そしたら、headプラグインで対象テーブルのマッピングが正しく設定されたか確認しよう。headプラグイントップページから、Overview → 対象インデックスのInfo → Index Metadataでマッピング情報が見られるので、それで確認しよう。

8. クラスタを組む

まず複数ノードの構成をやってみよう。マルチキャストで組む方法とユニキャストで組む方法があるけれど、ネットワーク内に他のサービスがある場合もあるので、ユニキャストで対象ノードを指定しておく方法を覚えておいたほうがいいだろう。

ということで、/etc/elasticsearch/elasticsearch.ymlの以下の箇所を設定する。

discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts:
  - 192.168.11.101
  - 192.168.11.102
  - 192.168.11.103

また、慣れるまではシャードも一つでいいだろうし、レプリカセットもいらないだろう。ただ、運用を考えるとそれらも設定できるようにしといたほうがいい。 ということで、シャードとレプリカセットの設定もする。現状以下の設定でやってるけど、パフォーマンス次第では変わるかもしれない。

index.number_of_shards: 5
index.number_of_replicas: 1

これでインデックス作成時にシャードの設定やレプリカセットの設定をやってくれる。

9. それから

ここまでひと通りやれば使い方や全体の雰囲気を軽く掴むことができるように思う。ただ、上記の述べた方法で操作に慣れたら以下の様な方法をさらにやってみるともう少しESを楽しめると思う。今は以下のことを試行錯誤している。

  • norikraを入れて、fluentdから流れたデータを集計し、それをESに入れる。ESに入れるデータ量を削減できるので非常に便利。
  • fluent-plugin-anomalydetectを入れて、異常値の閾値を探る。生成された値をESに入れてグラフ化。

10. 終わりに

1週間ほど色々データ入れ動かしてみたけれど、fluentd, kibanaとの相性がすごくよく、色々データを突っ込んでは、こういうのあったらいいな思うグラフをどんどん生成している。

最近perlやawkでログを処理する方法を教えたりする機会もあるのだけれど、チームにいる人数全員にはなかなか教えるのが大変だし、誰でも同じデータにすぐアクセスできるという意味で、こういった環境は今後どんどん増えていきそうな印象がある。

ということで、まだ使ってない人はすごく気軽に試せるので、是非是非試して欲しい。