ちょっと話題の記事

Elasticsearch 1.0.0 released! なのでSnapshot/Restore on S3をやってみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Elasticsearch 1.0.0 released、おめでとうございます!

ということで1.0.0 featuresを見ていたところ

Snapshot/Restore API

Backup or restore select indices or the whole cluster to a shared filesystem, S3 or HDFS via a simple API.

これはやはり試さないといかんだろうと思い、やってみました!

準備

環境はAmazon Linux on EC2です。 早速1.0.0のrpmを取得しインストールします。そしてchkconfigに登録してサービス起動。

$ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.noarch.rpm
$ sudo rpm -ivh ./elasticsearch-1.0.0.noarch.rpm

$ sudo chkconfig --add elasticsearch
$ sudo chkconfig elasticsearch on
$ sudo service elasticsearch start
Starting elasticsearch:                                    [  OK  ]

ローカルファイルシステムを使ったSnapshot and Restore

データ登録

リストアの動作確認をするために、テストデータを追加しておきます。

$ curl -XPUT http://localhost:9200/test/test/1 -d '
> {
>   "title" : "doc1",
>   "text"  : "one"
> }'
{"_index":"test","_type":"test","_id":"1","_version":1,"created":true}

$ curl -XPUT http://localhost:9200/test/test/2 -d '
> {
>   "title" : "doc2",
>   "text"  : "two"
> }'
{"_index":"test","_type":"test","_id":"2","_version":1,"created":true}

データがちゃんと登録されていることを確認しておきましょう。

$ curl -XGET http://localhost:9200/test/test/_search -d '
> {
>     "query" : {
>         "match_all" : {}
>     }
> }'
{"took":90,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[
{"_index":"test","_type":"test","_id":"1","_score":1.0, "_source" : 
{
  "title" : "doc1",
  "text"  : "one"
}},
{"_index":"test","_type":"test","_id":"2","_score":1.0, "_source" : 
{
  "title" : "doc2",
  "text"  : "two"
}}]}}

スナップショットの設定

「my_backup」というファイルシステムリポジトリを作成し、スナップショットを取得します。settingsについては以下の通り。

location スナップショットの保存場所。必須。
compress スナップショットファイルの圧縮指定。デフォルトはtrue。
concurrent_streams スナップショットストリームの数。デフォルトは5。
chunk_size スナップショットを分割する場合のサイズ指定。デフォルトはnullのため分割無し。
max_restore_bytes_per_sec リストア時の最大転送速度を指定。デフォルトは20mb。
max_snapshot_bytes_per_sec スナップショット作成時の最大転送速度を指定。デフォルトは20mb。
$ curl -XPUT 'http://localhost:9200/_snapshot/my_backup' -d '{
>     "type": "fs",
>     "settings": {
>         "location": "/mnt/backup/my_backup",
>         "compress": true
>     }
> }'
{"acknowledged":true}

設定値を確認します。

$ curl -XGET 'http://localhost:9200/_snapshot/my_backup?pretty'
{
  "my_backup" : {
    "type" : "fs",
    "settings" : {
      "compress" : "true",
      "location" : "/mnt/backup/my_backup"
    }
  }
}

スナップショットの取得

それでは実際にスナップショットを取得してみましょう。

$ curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"
{"snapshot":{"snapshot":"snapshot_1","indices":["test"],"state":"SUCCESS","start_time":"2014-02-13T04:47:21.494Z","start_time_in_millis":1392266841494,"end_time":"2014-02-13T04:47:21.847Z","end_time_in_millis":1392266841847,"duration_in_millis":353,"failures":[],"shards":{"total":5,"failed":0,"successful":5}}}

確認してみると...ちゃんと出来てます!

$ ls -alF /mnt/backup/my_backup/
合計 24
drwxr-xr-x 3 elasticsearch elasticsearch 4096  2月 13 04:47 2014 ./
drwxrwxrwx 3 root          root          4096  2月 13 04:45 2014 ../
-rw-r--r-- 1 elasticsearch elasticsearch   31  2月 13 04:47 2014 index
drwxr-xr-x 3 elasticsearch elasticsearch 4096  2月 13 04:47 2014 indices/
-rw-r--r-- 1 elasticsearch elasticsearch  179  2月 13 04:47 2014 metadata-snapshot_1
-rw-r--r-- 1 elasticsearch elasticsearch  173  2月 13 04:47 2014 snapshot-snapshot_1

リストア

リストアの動作を確認すべく、登録されているデータのうちid=2を削除しておきます。

$ curl -XDELETE http://localhost:9200/test/test/2
{"found":true,"_index":"test","_type":"test","_id":"2","_version":2}

$ curl -XGET http://localhost:9200/test/test/_search -d '
>  {
>      "query" : {
>          "match_all" : {}
>      }
>  }'
{"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"test","_type":"test","_id":"1","_score":1.0, "_source" : 
{
  "title" : "doc1",
  "text"  : "one"
}}]}}

ではリストアしてみます。indexを一旦closeしてからスナップショットからリストア、その後indexをopenします。

$ curl -XPOST http://localhost:9200/test/_close
{"acknowledged":true}

$ curl -XPOST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore"
{"accepted":true}

$ curl -XPOST http://localhost:9200/test/_open
{"acknowledged":true}

確認

データを確認してみると...削除したid=2のデータが復活しています!

$ curl -XGET http://localhost:9200/test/test/_search -d '
>   {
>       "query" : {
>           "match_all" : {}
>       }
>   }'
{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[
{"_index":"test","_type":"test","_id":"1","_score":1.0, "_source" : 
{
  "title" : "doc1",
  "text"  : "one"
}},
{"_index":"test","_type":"test","_id":"2","_score":1.0, "_source" : 
{
  "title" : "doc2",
  "text"  : "two"
}}]}}

S3を使ったSnapshot and Restore

ここからが本題。SnapshotをS3のbucketに取得し、更にリストアしてみます。

準備

前提としてIAM Role for EC2でPowerUsersが割り当てられていることとします。なのでelasticsearch.ymlにaccess_keyやsecret_keyを書き込む必要はありません。

AWS Cloud Plugin for Elasticsearchをインストールしておきます。

$ sudo /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-cloud-aws/2.0.0.RC1

スナップショットの設定

「s3_backup」というリポジトリを作成します。

$ curl -XPUT 'http://localhost:9200/_snapshot/s3_backup' -d '{
>     "type": "s3",
>     "settings": {
>         "bucket": "elasticsearch",
>         "region": "ap-northeast"
>     }
>  }'
{"acknowledged":true}

スナップショットの取得

スナップショットを取得します。コマンド自体はファイルシステムリポジトリと同様です。

$ curl -XPUT "localhost:9200/_snapshot/s3_backup/snapshot_1?wait_for_completion=true"
{"snapshot":{"snapshot":"snapshot_1","indices":["test"],"state":"SUCCESS","start_time":"2014-02-13T05:25:03.665Z","start_time_in_millis":1392269103665,"end_time":"2014-02-13T05:25:05.079Z","end_time_in_millis":1392269105079,"duration_in_millis":1414,"failures":[],"shards":{"total":5,"failed":0,"successful":5}}}

S3のbucketの中身を確認してみると...ちゃんと出来てますね!

s3_backup

リストア

またid=2のデータを削除しておきます。

$ curl -XDELETE http://localhost:9200/test/test/2
{"found":true,"_index":"test","_type":"test","_id":"2","_version":2}

$ curl -XGET http://localhost:9200/test/test/_search -d '
>  {
>      "query" : {
>          "match_all" : {}
>      }
>  }'
{"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"test","_type":"test","_id":"1","_score":1.0, "_source" : 
{
  "title" : "doc1",
  "text"  : "one"
}}]}}

それではS3リポジトリを使ってリストアします。ファイルシステムリポジトリと何ら変わりません。

$ curl -XPOST http://localhost:9200/test/_close
{"acknowledged":true}

$ curl -XPOST "localhost:9200/_snapshot/s3_backup/snapshot_1/_restore"
{"accepted":true}

$ curl -XPOST http://localhost:9200/test/_open
{"acknowledged":true}

確認

ちゃんとid=2のデータが復活してますねー!

$ curl -XGET http://localhost:9200/test/test/_search -d '
>    {
>        "query" : {
>            "match_all" : {}
>        }
>    }'
{"took":78,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[
 {"_index":"test","_type":"test","_id":"1","_score":1.0, "_source" {
   "title" : "doc1",
   "text"  : "one": 
 }},
 {"_index":"test","_type":"test","_id":"2","_score":1.0, "_source" : 
 {
   "title" : "doc2",
   "text"  : "two"
 }}]}}

まとめ

1.0.0betaから既に実装されていた機能ですが、1.0.0リリースに併せて改めて触ってみました。簡単!便利!

他にもたくさんのfeatursが実装されていますので、色々試してみたいと思います!