@johtaniの日記 2nd

@johtani ‘s blog 2nd edition

Curator: 時系列インデックスの管理(日本語訳)

Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(ローマ字)で返信を頂きました。 せっかくなので、ブログ記事を翻訳してもいいかを尋ねたところ、快くOKを頂いたので、翻訳してみました。参考になればと。(誤訳など見つけたらコメントください。)

curator: 時系列インデックスの管理

原文:curator: tending your time-series indices

背景

数年前、Elasticsearch、Logstash、Kibana(ELK)を管理し、ここ30日よりも古いインデックスを自動的に削除する方法を必要としていました。 APIドキュメントを読み、#logstashや#elasticsearchのIRCチャネルのコミュニティの助けを借りて、簡単なスクリプトとcronを用意するのが簡単であることを知りました。

1
curl -XDELETE 'localhost:9200/logstash-2014.01.01?pretty'

もちろん、これも動作しますが、日付を生成するのがめんどくさいのでもっとエレガントな方法が欲しかったです。

最初に

pythonでスクリプトを書き始めました。特定の日数のインデックスを管理するだけのコマンドラインクリーナーを書いてコミュニティにシェアしました。他の人が、新しい機能を追加してくれました。私は、古いインデックスをoptimizeすることができる他のスクリプトも書きました。これは、シャードごとにnセグメント以上存在しないように各シャードのセグメントをマージすることです。これらのスクリプトで1つになるようにマージしたりエンハンスし、古いインデックスを管理する助けになるツールです。

curatorの紹介

Curatorで可能なインデックスオペレーション

  • 削除(日付もしくは、トータル容量による制限)
  • インデックスのクローズ(Close)
  • bloom filter cacheの無効化
  • Optimize(LuceneのforceMerge)

curatorのインストール

この記事を書いている時点で、Curator は0.5.1がリリースされ、0.90.10に対応しています。Curatorはまた、Elasticsearchの1.0(現在はRC1)へも対応しています。各リリースへの互換性の保証のためのテストも行っています。

現時点では、gitリポジトリで配布しています。近い将来、pipによるインストール可能なパッケージにする予定です。利用することを恐れないでください。もし、pythonとpipがあなたのマシンにインストールされていれば、次のようにインストールは簡単です。

1
2
git clone https://github.com/elasticsearch/curator.git
pip install -r requirements.txt

インストール後の確認は次のコマンドです。

1
2
$ ./curator.py -v
curator.py 0.5.1

利用方法とサンプル

サンプルを示す前に、オプションを見ておくとよいでしょう。このリストは長いですが(この記事の最後に含まれています)、どのようなことがコントロールできるかを説明しています。デフォルトがどうなっているかに注意してください。もし、デフォルト値で良い場合は、フラグを指定する必要はありません。

では、簡単なサンプルを見ながら、CuratorがELKスタックをどうやって管理するかを見て行きましょう。

削除(delete)

90日以上のインデックスを保存したくないとしましょう。コマンドは次のようになります。

1
$ curator.py --host my-elasticsearch -d 90

-dで日数を指定しているだけです。簡単でしょ?

容量による削除(delete by space)

これは、指定したギガバイト数を超えたインデックスを場合に(最も古いものから)削除を行う特殊なケースです。

1
$ curator.py --host my-elasticsearch -C space -g 10024

-Cでspaceによるcurationであること、-gでギガバイト数(10024、10TB)であることを指定しているのがわかります。-gは1.5や0.5という数値を指定できます。

その他のCuratorオプションはspaceによる削除と組み合わせて使用できないことに注意してください。

クローズ(close)

Open/Close Index APIにより、インデックスをクローズすることができます。

open/close index APIを利用すると、インデックスをクローズしたり、あとでオープンしたりすることができます。クローズされたインデックスはクラスタのオーバヘッドにほとんどならず(メタデータの管理を除く)、読み書き操作の妨げにもなりません。クローズされたインデックスは、リカバリプロセス時に、オープンされます。

インデックスをクローズすることは、存在はするが検索できないという意味です。何が便利なのでしょう?

90日のインデックスを保存する義務があるが、検索は過去30日のインデックスを対象にする以外は稀であるような場合を想像してください。このような状況で、価値のあるリソース(ヒープスペースなど)を節約するためにインデックスをクローズすることができます。これは、クラスタに検索やインデキシングのためのメモリを与えることができることを意味します。そして、もし、クローズしたインデックスのデータが必要になったら、APIを呼び出してインデックスをオープンすれば検索できます。

このような場合、今オープンしているインデックスが再び、クローズされないように、一時的にCuratorのスケジュール実行をオフにしておくのが懸命です。

1
$ curator.py --host my-elasticsearch -c 30 -d 90

先ほど説明した例の実行方法です。これは、30日よりも古いインデックスはクローズし、90日より古いインデックスを削除します。本当に簡単でしょ?

bloom filterの無効化

これは、0.90.9以降のバージョンで利用可能な機能です。(リンク先はIssue #4525)

心配しないでください。このスクリプトは操作を行う前に、elasticsearchが利用可能なバージョンであるかをチェックします。

bloom filterとは何でしょう?なぜ、無効化したくなるのでしょう?

bloom filterはインデキシング操作を高速化するためにリソースを割り当てられます。時系列データで、インデキシングしている間もこれは有用です。インデックスは2日後には、日付が変わると新しいデータはおそらくインデックスされません。そのインデックスにはもはや必要のないリソースをbloom filterはまだ持っています。Curatorはこれらのリソースを開放することができます!

1
$ curator.py --host my-elasticsearch -b 2 -c 30 -d 90

これで、bloom filterのリソースは少なくとも2日(1にもできます)よりも古いインデックスについては利用せず、30日より古いインデックスはクローズし、90より古いインデックスは削除します。

optimizeというよりもforcemerge

コマンドの説明をする前に、Elasticsearch APIのoptimizeを見ることは、生きているインデックスや”cold”インデックス(インデキシングがアクティブではないという意味)に実行する必要があるということを理解するために重要です。実際、optimizeはLuceneではforceMergeと名前が変えられ、インデックスを改善するためにoptimizeを呼び出す必要はなくなりました。Elasticsearchのセグメントをマージすることは利点がありますが、coldインデックス全てに対してoptimizeを開始する前に、コストを理解する必要があります。

forceMerge操作はインデックスにある各シャードのセグメントの数を少なくします。各セグメントはオーバヘッドがあるため、セグメントが多いということは、より多くのリソースを使うという意味です。良さそうですね?リソースが少ない?

それは、可能ですが、merge操作を実行するには多くのディスクやネットワークI/Oが必要で、ディスクやクラスタの通常の書き込み操作に悪影響を及ぼします。もし、これが必要なら私のアドバイスを良く考えてください。(数%ほど)検索を速くし、リソースの使用量も減らすことができます。また、管理しているセグメント数が小さくなるということは、クラスタのリカバリを速くすることにもなります。1つのインデックスをoptimizeするためにはおそらく1時間以上の時間がかかります。「使用する前に目立たない場所で試してください」というクリーニングボトル(訳注:洗剤とか漂白剤かな?)の注意書きと同様に、ディスクI/Oが低い時にテストし、もし操作とリソースがあなたのクラスタのユースケースにあっているかを見てください。デフォルトでは、シャードごとに2つのセグメントにマージしますが、--max_num_segmentsフラグで変更可能です。

ここまでのサンプルは次のようなコマンドになります。

1
$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90

これで、bloom filterは2日より古いインデックスでは向こうにし、2日より古いインデックスは”optimize”し、30日より古いインデックスはクローズし、90日より古いインデックスは削除されます。

操作の順序

スクリプトは操作が衝突するのを防ぐために次の順序で実行されます。なぜ、クローズされたインデックスはoptimizeしないのでしょう?なぜ、削除予定のインデックスはクローズされないのでしょう?

  1. Delete (by space or time)
  2. Close
  3. Disable bloom filters
  4. Optimize

使用の検討

最後の例で、3つの操作を1つのコマンドで実行していますが、それらが連続ですべて実行されるのを望んでいないかもしれません。

1
$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90

これは、次の操作と同様です。

1
2
3
4
$ curator.py --host my-elasticsearch -d 90
$ curator.py --host my-elasticsearch -c 30
$ curator.py --host my-elasticsearch -b 2
$ curator.py --host my-elasticsearch -o 2

これらのコマンドを異なる時間に実行したり、異なるその他のオプション(特に、optimize実行で--timeout 3600を追加したり)を指定して実行するのは簡単です。

また、デフォルトのlogstash-とは異なるプレフィックスのインデックスを持っているかもしれません。

1
2
$ curator.py --host my-elasticsearch --prefix logstash- -d 30
$ curator.py --host my-elasticsearch --prefix othername- -d 30

最後に

Curatorは時系列インデックスの保存ポリシーを管理するのに役立ちます。豊富な設定オプションがインデックスを管理することを簡単にします。クラスタに存在するノードの数に関係なく。https://github.com/elasticsearch/curatorへのフィードバックやコントリビューションをお待ちしています!

参考(全引数とオプション)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$ curator.py -h
usage: curator.py [-h] [-v] [--host HOST] [--port PORT] [-t TIMEOUT]
                  [-p PREFIX] [-s SEPARATOR] [-C CURATION_STYLE]
                  [-T TIME_UNIT] [-d DELETE_OLDER] [-c CLOSE_OLDER]
                  [-b BLOOM_OLDER] [-g DISK_SPACE]
                  [--max_num_segments MAX_NUM_SEGMENTS] [-o OPTIMIZE] [-n]
                  [-D] [-l LOG_FILE]

Curator for Elasticsearch indices. Can delete (by space or time), close,
disable bloom filters and optimize (forceMerge) your indices.

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program version number and exit
  --host HOST           Elasticsearch host. Default: localhost
  --port PORT           Elasticsearch port. Default: 9200
  -t TIMEOUT, --timeout TIMEOUT
                        Elasticsearch timeout. Default: 30
  -p PREFIX, --prefix PREFIX
                        Prefix for the indices. Indices that do not have this
                        prefix are skipped. Default: logstash-
  -s SEPARATOR, --separator SEPARATOR
                        Time unit separator. Default: .
  -C CURATION_STYLE, --curation-style CURATION_STYLE
                        Curate indices by [time, space] Default: time
  -T TIME_UNIT, --time-unit TIME_UNIT
                        Unit of time to reckon by: [days, hours] Default: days
  -d DELETE_OLDER, --delete DELETE_OLDER
                        Delete indices older than n TIME_UNITs.
  -c CLOSE_OLDER, --close CLOSE_OLDER
                        Close indices older than n TIME_UNITs.
  -b BLOOM_OLDER, --bloom BLOOM_OLDER
                        Disable bloom filter for indices older than n
                        TIME_UNITs.
  -g DISK_SPACE, --disk-space DISK_SPACE
                        Delete indices beyond n GIGABYTES.
  --max_num_segments MAX_NUM_SEGMENTS
                        Maximum number of segments, post-optimize. Default: 2
  -o OPTIMIZE, --optimize OPTIMIZE
                        Optimize (Lucene forceMerge) indices older than n
                        TIME_UNITs. Must increase timeout to stay connected
                        throughout optimize operation, recommend no less than
                        3600.
  -n, --dry-run         If true, does not perform any changes to the
                        Elasticsearch indices.
  -D, --debug           Debug mode
  -l LOG_FILE, --logfile LOG_FILE
                        log file

Comments