はじめに
elasticsearch 1.0.0
から利用出来るようになっていたので過去に渡って簡単に触ってみた- ざーっと触った感じたと
API
にアクセスするだけで簡単にスナップショットが取れる手軽さは非常に魅力的な印象 - ただ、データ量が大きくなっても大丈夫?とかデータはどんなデータでも大丈夫?とか他にオプションはどんなのあるんだろうと思って、も少し突っ込んで触ってみる
S3
の課金にちょっと気をつけつつ弄ってみよう!
参考
スナップショットとレストア機能
スナップショットとレストアの機能についてこちらを参考に概要を抜粋。
リポジトリ
スナップショットを作成する前に以下のようにしてリポジトリを作成する必要がある。
$ curl -XPUT 'http://localhost:9200/_snapshot/my_backup' -d '{ "type": "fs", "settings": { "location": "/mount/backups/my_backup", "compress": true } }'
リポジトリの確認も curl -XGET 'http://localhost:9200/_snapshot'
で確認が出来る。
{"my_s3_repository":{"type":"s3","settings":{"region":"ap-northeast-1","bucket":"elasticsearch-snapshot"}}}
上記は Amazon S3
にリポジトリを作成した場合の例。以下のようにリポジトリを指定した場合には...
curl -XGET 'http://localhost:9200/_snapshot/my_s3_repository?pretty'
以下のようにリポジトリの詳細が確認出来る。
{ "my_s3_repository" : { "type" : "s3", "settings" : { "region" : "ap-northeast-1", "bucket" : "elasticsearch-snapshot" } } }
リポジトリの種類
type:fs
を指定するとshared file system repository
となる(詳細なオプションはこちら)shared file system repository
でlocation
パラメータで既存のファイルシステムの指定が可能"type": "url"
はshared file system repository
で作成されたスナップショットにアクセスする(詳細なオプションはこちら)
尚、"type": "url"
については使い方はよく解らない...。
リポジトリのプラグイン
リポジトリのプラグインとしては以下のようなプラグインが用意されている。
その他にもこちらの記事だと GlusterFS
と Google Compute Engine
や Microsoft Azure にも対応するみたい。
スナップショット
スナップショットは以下のようにして取得する。
$ curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true
wait_for_completion
オプションはスナップショット終了を「待つ」、「待たない」の制御が出来る。以下のように出力される。
{"snapshot":{"snapshot":"snapshot_20140208_1","indices":[".marvel-2014.02.08",".marvel-2014.02.06","test01",".marvel-2014.02.05","restaurant"],"state":"SUCCESS","start_time":"2014-02-08T12:35:45.927Z","start_time_in_millis":1391862945927,"end_time":"2014-02-08T12:40:12.596Z","end_time_in_millis":1391863212596,"duration_in_millis":266669,"failures":[],"shards":{"total":13,"failed":0,"successful":13}}}
試した感じだとデフォルトは wait_for_completion=false
のようだ。また、以下のように取得することも出来る。
$ curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1" -d '{ "indices": "index_1,index_2", "ignore_unavailable": "true", "include_global_state": false }'
indices
オプションでスナップショットを取得するインデックスを個別に指定出来る(指定が無い場合には丸っと全てのスナップショットが取れる)。また、"ignore_unavailable": "true",
で無効なインデックスのスナップショットは取得しない(らしい...)。また、"include_global_state": false
でスナップショットに global state
を含めないようにしている。(global state
ってなんだろう??)
尚、スナップショットの動作についてはドキュメントの以下の部分が重要な部分かと思われるのでそのまま抜粋。
The index snapshot process is incremental. In the process of making the index snapshot Elasticsearch analyses the list of the index files that are already stored in the repository and copies only files that were created or changed since the last snapshot. That allows multiple snapshots to be preserved in the repository in a compact form. Snapshotting process is executed in non-blocking fashion. All indexing and searching operation can continue to be executed against the index that is being snapshotted. However, a snapshot represents the point-in-time view of the index at the moment when snapshot was created, so no records that were added to the index after snapshot process had started will be present in the snapshot.
ざっくりと以下のように意訳(powered by Google 翻訳!!)
- 増分スナップショット
- リポジトリの差分をチェックして増分だけを新たにスナップショットを取得する
- 上記のことから複数のスナップショットの容量を抑えることが出来る
- スナップショットの取得に際してインデックスをブロックしないので検索等の操作に影響しない
- 但し、スナップショットが
取得されたpoint-in-time
以降で追加されたインデックスはスナップショットには含まれない
ふむふむ、なるほど。
レストア
以下のようにしてレストアを行う。
$ curl -XPOST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore"
スナップショットの取得時と同じようなオプションが利用出来るようだ。"rename_pattern": "index_(.)+"
と "rename_replacement": "restored_index_$1"
を組み合わせてレストアするインデックス名を変更してレストアが出来るようだ。
リポジトリの操作
以下はリポジトリに登録されているスナップショット一覧を取得する。出力は こちらのように出力される。
curl -XGET localhost:9200/_snapshot/my_s3_repository/_all?pretty
また、 スナップショットの削除も以下のようにして行うことが出来る。
curl -XDELETE localhost:9200/_snapshot/my_s3_repository/snapshot_20140204
以下のように S3
上のリポジトリから該当のファイルが無くなっている。
環境の構築
環境
検証の環境は以下の通り。
- elasticsearch ノードは Amazon EC2 の t1.micro インスタンスで Ubuntu 13.10
- スナップショットの取得先は Amazon S3
elasticsearch のノード構築
elasticsearch のノードはこちらの Chef の cookbook を使った
elasticsearch のノードの設定
特に大きな設定は行っておらず、Amazon S3 へのスナップショットを取得する為に ACCESS_KEY 等をelasticsearch.yml
の末尾に設定する。
cloud: aws: access_key: AKxxxxxxxxxxxxxxxxxx secret_key: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
個人的にはこのような設定については elasticsearch.yml
の末尾に記載するよりは別ファイルを include
出来たりすると嬉しいかなあ。
データを投入
サンプルデータ
サンプルデータにはこちらのデータを利用させて頂いた。CSV
形式で提供されているのでとりあえず CSV
形式をどうやって elasticsearch
に放り込むか悩んだ結果...以下のようなスクリプトを CSV
ファイルの分だけ用意して放り込んだ...
#!/usr/bin/env ruby require "csv" require "net/http" require "uri" require 'digest/md5' datas = CSV.open("/path/to/rating_votes.csv", "r") header = datas.take(1)[0] datas.each do |data| rdm = ((0..9).to_a + ("a".."z").to_a + ("A".."Z").to_a).sample(3).join id = Digest::MD5.new.update("#{rdm}") puts "curl -X POST localhost:9200/restaurant/rating_votes/#{id} -d \ \'{\"#{header[0]}\":\"#{data[0]}\",\"#{header[1]}\" :\"#{data[1]}\",\ \"#{header[2]}\" :\"#{data[2]}\",\ \"#{header[3]}\" :\"#{data[3]}\"}\'" end
Ruby
力を高めなければ...。今回はインデックスは restraunt
というインデックスに CSV
ファイル毎に type
を設定した。
データ投入中...
Marvel でデータ投入中のノードを確認してみる。
おお、kibana
だ。概要や使い方等はこちらで詳しく紹介されている。
スナップショットとレストアの実験
データをインデックスに投入中でもスナップショットを取れるのかな?
上記にも記載したように制約(※スナップショットを取得した以降のインデックスは反映されない)があるものの可能。以下、一応、再現動画。
二つに分割された画面の上がデータを投入中(インデックス作成中)。下段でスナップショットを取得。
別のノードにレストア出来るのかな?
上記のような構成で別のノードで取得したスナップショットを元にインデックスを構築することが出来るか試してみたところ以下のような流れで出来そう。
- ノードの設定(
S3
へのアクセスまで確認) - リポジトリの設定
- レストア
実際に試すと以下のような感じになる。
まずはスナップショットを作成した際と同じ名前でリポジトリを作成する。
curl -XPUT 'http://localhost:9200/_snapshot/my_s3_repository' -d '{ "type": "s3", "settings": { "bucket": "elasticsearch-snapshot", "region": "ap-northeast-1" } }'
レストアしたい時点のスナップショットを確認する。
curl -XGET localhost:9200/_snapshot/my_s3_repository/_all?pretty
確認したらレストアする。以下のコマンドで restaurant
インデックスのレストアを開始。
time curl -XPOST localhost:9200/_snapshot/my_s3_repository/20140208_03/_restore -d '{ "indices": "restaurant" }'
以下のように出力されてレストアが終了する。
{"accepted":true} real 0m0.478s user 0m0.005s sys 0m0.012s
念のために elasticsearch-head
で確認してみる。
15M
で 10
万ドキュメントで約 5
秒。これって速いのかな?
最後に
- 先日の勉強会でもスナップショット、レストア機能に期待値が高いことを感じたのでリリース版が待たれる
- 細かいオプションについて追いきれていない部分は引き続き調べられたらなー