ElasticSearchを良い感じに使うコツとか

自分用メモ


# install ~ setup

fabricでオーケストレーションした

```:fabfile.py
def install_elastic_search():
    sudo("wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.2.1.deb")
    sudo("dpkg -i elasticsearch-1.2.1.deb")
    sudo("service elasticsearch start")
    run("echo export PATH=\$PATH:/usr/share/elasticsearch/bin/ >> ~/.bashrc")

def es_init():
    //changing permission
    //see document
```

# td-agentとの連携

いろんなサーバーからのログをelasticsearchの入っているログサーバーで受ける
td-agent(fluentd)のforestプラグインで条件分岐したりタグから情報を抜き取って利用すると良い

```:td-agent.conf

<source>
  type forward
  port 24224
</source>

<match **>
 type forest
 subtype elasticsearch
 <template>
   host localhost
   port 9200
   index_name ${tag_parts[2]}
   type_name ${tag_parts[1]}

   buffer_type memory
   flush_interval 3s
   retry_limit 17
   retry_wait 1.0
   num_threads 1
   flush_at_shutdown true
 </template>
</match>

```

これちょっと`flush_interval 3s`は良くない。
たぶんプロダクションならパフォーマンスに影響出るくらい頻度が高い。

ちなみにtd-agentでintervalをアカン感じのタイミングに設定するとElasticSearchにPUTしたはずのデータがなかなか反映されなくて困ったりするので反映遅いなあと思ったらそのへんいじると良いかも。

# テスト

## 存在テスト

```:fabfile_test.py

def all():
  availability_test("td-agent")
  availability_test("elasticsearch")

def availability_test(name):
  env.warn_only = True

  if name == "td-agent":
    version_checker = name + " --version"
  elif name == "elasticsearch":
    version_checker = "export PATH=$PATH:/usr/share/elasticsearch/bin/ && " + name + " -v"

  if "command not found" in run(version_checker):
    print(name + " hasn't been installed")
  else:
    print(name + " has been installed")
  env.warn_only = False

```

今思えばfabricのテストツールのenvassert使った方が良いし、僕も今はリファクタしてそれ使ってるはず。

envassertはsetupも楽だしserverspecほどゴテゴテしてなくて良い。いや、rspec的記法で書けるのはとても良いしJSで言ったらmochaとかも良い感じだと思うんだけど、serverspecは準備に必要なものが多すぎてなんかインフラテストのための環境をテストしたくなってくるし触ったけど敬遠気味。なのでrubyistだけどchefじゃなくてfiblic。

## ログ系結合テスト

ガチ汚い
python当たりで書き直す

```:bash

#! /bin/bash
###############################################
# function
###############################################

initializing () {
  if ! expr $before : '[0-9]*' 1> /dev/null 2> /dev/null ; then
    before=0
  fi

  if [ -z $num ]; then
    num=0
  fi

  if [ $num -le $before ]; then
    num=$(($before+1))
  fi
}

buffering () {
  waiting=$*
  for i in `seq 1 $waiting`
  do
    left=$(($waiting - $i))
    echo $left sec
    sleep 1
  done
}

log_into_td_es () {
  fab -u <your_name> -i <your_pem> -H <your_domain> all
  buffering 1
}

diff_check () {
  diff=$(($after - $before))
  if [ $diff -eq 1 ]; then
    echo diff: $diff
  else
    echo not changed
    exit 1
  fi
}

# delete_all () {
#   curl -XDELETE 'http://$*:9200/*' 1> /dev/null 2> /dev/null 
# }




###############################################
# main
###############################################
before=`curl -XGET http://$*:9200/fluentd/_count 2> /dev/null | cut -d "," -f 1 | cut -d ":" -f 2`
echo before_count: $before
initializing
curl -XPUT http://$*:9200/fluentd/info/$num -d '{ "test" : "hoge" }' 1> /dev/null 2> /dev/null
after=`curl -XGET http://$*:9200/fluentd/_count 2> /dev/null | cut -d "," -f 1 | cut -d ":" -f 2`
echo after_count: $after
diff_check

```


# ログを使う

`elasticsearch-py`とか使ったが良い。僕はrubyistだけどインフラではpythonとかのが使うことは多いかも。チームに合わせる。こだわりはない。

`curl -X GET 'http://hoge.com:9200/_index/_type/_search?pretty=true&size=1000&sort=desc'`

とかで確認するのもよい。

# ESの様子を見る

## 目grep

`curl -X GET 'http://hoge.com:9200/_stats?pretty`

とかで何千行もの統計情報が出る。大体僕はドキュメント量(とストレージ)とか見たりする。今のところシャーディングもレプリケーションもしてないので後でする。

## 死活監視

- elasticsearch-head
- elasticsearch-paramedic
- SPM for ElasticSearch

ESの統計情報を定時的に取得して可視化してくれる奴ら。

そんな感じ。