ようへいの日々精進XP

よかろうもん

elasticsearch 1.0.0 RC2 の Snapshot と Restore 機能を触ってみる(もう少し突っ込んで)

はじめに

  • 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 repositorylocation パラメータで既存のファイルシステムの指定が可能
  • "type": "url"shared file system repository で作成されたスナップショットにアクセスする(詳細なオプションはこちら

尚、"type": "url" については使い方はよく解らない...。

リポジトリプラグイン

リポジトリプラグインとしては以下のようなプラグインが用意されている。

その他にもこちらの記事だと GlusterFSGoogle Compute EngineMicrosoft 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 上のリポジトリから該当のファイルが無くなっている。

f:id:inokara:20140208225122p:plain


環境の構築

環境

検証の環境は以下の通り。

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 でデータ投入中のノードを確認してみる。

f:id:inokara:20140208172359p:plain

おお、kibana だ。概要や使い方等はこちらで詳しく紹介されている。


スナップショットとレストアの実験

データをインデックスに投入中でもスナップショットを取れるのかな?

上記にも記載したように制約(※スナップショットを取得した以降のインデックスは反映されない)があるものの可能。以下、一応、再現動画。

二つに分割された画面の上がデータを投入中(インデックス作成中)。下段でスナップショットを取得。

別のノードにレストア出来るのかな?

f:id:inokara:20140209015423p:plain

上記のような構成で別のノードで取得したスナップショットを元にインデックスを構築することが出来るか試してみたところ以下のような流れで出来そう。

  • ノードの設定(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 で確認してみる。

f:id:inokara:20140209012944p:plain

15M10 万ドキュメントで約 5 秒。これって速いのかな?


最後に

  • 先日の勉強会でもスナップショット、レストア機能に期待値が高いことを感じたのでリリース版が待たれる
  • 細かいオプションについて追いきれていない部分は引き続き調べられたらなー