LoginSignup
18
17

More than 5 years have passed since last update.

初心者が送る!ElasticSearch運用日記

Last updated at Posted at 2015-12-11

初心者が送る!ElasticSearch格闘日記

ElasticSearch導入2回目の初心者ですが
日々、ElasticSearchと戦いながら楽しく運用をしています。

導入してわかったメリット

・可視化することで異変に気づく(気づいてしまうことも。。)
・時系列にすることで思わぬ気づきがある
・ログ調査のスピード早くなる

日々の格闘

新規システム構築時にあわせ、
可視化目的で運用(監視)ツールの一環としての構築。
導入の際、投入するログ量が多いと分かっていたのですが、
負荷と戦う毎日を繰り返しています!!

稼働環境

・ElasticSearch 1.4.4
・kibana 4
・AWS t2.large×8台 EBS:250G
・ES_HEAP_SIZE:4096m
・3000~6000docs/秒
・データサイズ:600GB程度
・index数:500個位

定期的なindexのお掃除

Cronで定期的にindexの削除を実施しており
以下のようなスクリプトを実行

TGTDATE=$1
URL="http://xxxx:9200"
curl -s ${URL}/_cat/indices 2>/dev/null | awk -v TGTDATE=$TGTDATE '$3 ~ TGTDATE { print $3 }' | \
while read INDEX
do
  curl -s -XDELETE -w'\n' ${URL}/${INDEX} | jq .acknowledged
done

考慮点として、直近のデータ以外は必要ではないため、
indexの保持期間は2日保存と自分ルールを決めてます。

インデックス命名規則

Fluentdでfluent-plugin-elasticsearchからデータ投入。

2つのパターンで分けており

  1. Webサーバなどのデータ量が大きいもの
  2. OSのログなど負荷が低いもの

でインデックス命名規則を分けています。

1時間単位のネーミング

td-agent.conf
    <template>
      include_tag_key true
      tag_key @log_name
      host xxxxxx
      port 9200
      logstash_format true
      logstash_prefix ${tag_parts[0]}
      logstash_dateformat  %Y.%m.%d-%H

      buffer_chunk_limit 16m
      buffer_queue_limit 256

      buffer_type file
      buffer_path /var/log/td-agent/buffer1/elastic_${tag}
      flush_at_shutdown true

      flush_interval 1s
      try_flush_interval 2s
      queued_chunk_flush_interval 1s

      num_threads 4
      retry_limit 2
      retry_wait 2
    </template>

日単位のindex

td-agent.conf
  <template>
    include_tag_key true
    tag_key @log_name
    host xxxxx
    port 9200
    logstash_format true
    logstash_prefix ${tag_parts[1]}
    logstash_dateformat  %Y.%m.%d

    buffer_chunk_limit 8m
    buffer_queue_limit 128
    buffer_type file
    buffer_path /var/log/td-agent/buffer2/elastic_${tag}
    flush_at_shutdown true

    flush_interval 1s
    try_flush_interval 2s
    queued_chunk_flush_interval 1s

    num_threads 4
    retry_limit 2
    retry_wait 2
  </template>

ただ、1時間単位でindexを作ること数が多くなり運用しずらいです。

送り先であるFluentdのチューニング

Fluentdを使ってElasticSearchのですが、
NGINXなどのログは大量に送られてくるので
データ送信を設定値で細かくしています

大きい値8と小さい値0.01くらいまで
パフォーマンスを取って試しましたが、この環境では

td-agent.conf
      flush_interval 1s
      try_flush_interval 2s
      queued_chunk_flush_interval 1s

が良かった結果でした

負荷軽減のためのIndexTemplate

fieldのtypeで考慮している点

なるべく負荷を下げようとした結果、
・集計しないとき

Index.Template
    "index": "no",
    "doc_values": true,
    "type": "string"

・本当にkibanaとかで集計するとき

Index.Template
    "index": "not_analyzed",
    "doc_values": true,
    "type": "string"

を設定しています。

基本的には、"index": "no"を設定しておき
どうしてもKibanにグラフ化したいときには
"index": "noを設定しないような運用をしています。

あわせて、refresh_intervalに30秒を指定して付加を軽減しています。

elasticsearch.yml
    "index.refresh_interval": "30s",
    "index.number_of_replicas": "1

データの長期保存のための再集計

2日でデータを削除するとしても、長期保存したいデータもあり
その場合は、保存したいデータを集計して抜き出し、再度ElasticSearchに入れ込んで
工夫しています。

再投入の際には、複数値で割り算など求めて加工したり
他にも、zabbixとかAeroSpikeのデータなどAPIで取って
ElasticSearchに含めて集約しています。

設定値

node名にホスト名を入れたいので

elasticsearch.yml
    node.name: ${HOSTNAME}

を指定して、

/etc/init.d/elasticsearch
    export HOSTNAME=ES-SERVER

とホスト名で認識されるようにしています。

リバランシンシングで均等にするため
cluster.routing.allocation.cluster_concurrent_rebalance

リカバリー時に負荷を少なくするため
cluster.routing.allocation.node_concurrent_recoveries: 3
indices.recovery.max_bytes_per_sec: 50mb
indices.recovery.concurrent_streams: 5
をいれています。

EC2のインスタンス入れ替え

導入当初はc4.large×8台を使っていたが
コストの兼ね合いもあり、t2.largeへ移行しました。

移行方法はこちらを参考にしました
https://www.elastic.co/guide/en/elasticsearch/guide/current/_rolling_restarts.html

Kibanaのデータバックアップ

Kibana再設定は手間がかかるのでデータバックは重要です!
elasticsearch-cloud-awsを使っているので、S3に時々保存しています。
https://github.com/elastic/elasticsearch-cloud-aws#s3-repository
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html

障害対応時

残念ながら、負荷に負けてしまうことが時々あります。
そんなときは、復旧ができなくなるため、断腸の思いでindex削除しています。

curl -XDELETE 0:9200/*2015*

でindex削除しています。
ですので、長期保存用のindexなど必要なデータはindex名を変えておきます。

あとは、
unassigned_shardsが無いかCronで定期チェックしていたり、
unassigned_shardsがあった場合は

  curl -s -m 5 -XPOST '0:9200/_cluster/reroute' -d '{
    "commands" : [ {
          "allocate" : {
              "index" : "'$index名'",
              "shard" : '$shard',
              "node" : "'$割当先'",
              "allow_primary" : true
          }
        }
     ]
  }' | jq -r .acknowledged

で配置しているようにしています。

最後に

AZ間を跨いで稼動させているので通信量が気になって、ノード間の通信量を調べたてみたかったり
スプリットブレインがおきたときの対処を冷静にしたり
EC2のインスタンスストアを使えばよかったと思ったり
これからも日々楽しく運用してみます。

18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17