読者です 読者をやめる 読者になる 読者になる

Carpe Diem

備忘録。https://github.com/jun06t

エイリアスを用いたマッピング変更

Elasticsearch

概要

仕様変更でフィールドの追加やマッピングの変更など発生しますが、Elasticsearch に関わらずほとんどの検索エンジンは検索・インデックス仕様の変更をする際、インデクスを再作成する必要があります。
エイリアスを利用すると、その変更をダウンタイム0でできるようになります。

環境

  • Ubuntu 14.04
  • ElasticSearch 1.4.2

基本的な流れ

  1. 古いインデクスにエイリアスを付けて、エイリアスを検索インデクスとして使用する
  2. 新しいインデクスを作成
  3. 古いインデクスのデータを新しいインデクスにコピー
  4. エイリアスを新しいインデクスに付け替える
  5. 古いインデクスを削除する

古い方のインデクスを用意

マッピング

公式サイトのダミーデータを使うやり方でやります。

$ curl -XPUT http://localhost:9200/shakespeare -d '
{
 "mappings" : {
  "_default_" : {
   "properties" : {
    "speaker" : {"type": "string", "index" : "not_analyzed" },
    "play_name" : {"type": "string", "index" : "not_analyzed" },
    "line_id" : { "type" : "integer" },
    "speech_number" : { "type" : "integer" }
   }
  }
 }
}
'

ダミーデータの投入

ダミーデータをダウンロードします。

$ wget http://www.elasticsearch.org/guide/en/kibana/current/snippets/shakespeare.json

非常に大きいのでtrimします。

$ cat shakespeare.json | head -n 1000 > test.json

投入します。

$ curl -XPUT localhost:9200/_bulk --data-binary @test.json > /dev/null

エイリアスを作成

古い方にエイリアスを付けます。

$ curl -XPUT localhost:9200/shakespeare/_alias/shakespeare_alias
{"acknowledged":true}

確認

$ curl -XGET localhost:9200/*/_alias?pretty
{
  "shakespeare" : {
    "aliases" : {
      "shakespeare_alias" : { }
    }
  }
}

HEADプラグインで見るとこんな感じになります。

f:id:quoll00:20150204012004p:plain

以降サービスとしてはこのエイリアスに対して検索を行います。

動作確認(古いインデクス)

エイリアスshakespeare_aliasに対して検索を行います。
古いインデクスshakespearenot_analyzedマッピングしたので完全一致のクエリtermが必要です。

$ curl http://localhost:9200/shakespeare_alias/_search?pretty -d '
{
    "query": {
        "term": {
            "line.play_name": "Henry IV"
        }
    }
}
'

結果は以下のように引っかかります。

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 496,
    "max_score" : 0.998002,
    "hits" : [ {
      "_index" : "shakespeare",
      "_type" : "line",
      "_id" : "2",
      "_score" : 0.998002,
      "_source":{"line_id":3,"play_name":"Henry IV","speech_number":"","line_number":"","speaker":"","text_entry":"Enter KING HENRY, LORD JOHN OF LANCASTER, the EARL of WESTMORELAND, SIR WALTER BLUNT, and others"}
    }, 

新しいインデクスを用意

今度はspeaker, play_nameのindexをanalyzedにしてみます。

curl -XPUT http://localhost:9200/shakespeare_v2 -d '
{
 "mappings" : {
  "_default_" : {
   "properties" : {
    "speaker" : {"type": "string", "index" : "analyzed" },
    "play_name" : {"type": "string", "index" : "analyzed" },
    "line_id" : { "type" : "integer" },
    "speech_number" : { "type" : "integer" }
   }
  }
 }
}
'

インデクスが増えました。

f:id:quoll00:20150204012028p:plain

データのコピー

ライブラリを利用します。

$ npm install -g elasticsearch-reindex

ドキュメントの通りに実行します。

$ elasticsearch-reindex -f 'localhost:9200/shakespeare' -t 'localhost:9200/shakespeare_v2'


     reindexing [======------------------------] 100/500(20%) 0.0 0.0s

     reindexing [============------------------] 200/500(40%) 0.1 0.1s

     reindexing [==================------------] 300/500(60%) 0.2 0.1s

     reindexing [========================------] 400/500(80%) 0.2 0.1s

     reindexing [==============================] 500/500(100%) 1.8 0.0s

     Total 500 documents have been processed!
    Worker finished his work!

データが投入されました。

f:id:quoll00:20150204012043p:plain

エイリアスの付け替え

次にエイリアスの付替えを行います。

$ curl -XPOST 'http://localhost:9200/_aliases' -d '
{
  "actions" : [
    {"remove": {"index": "shakespeare", "alias": "shakespeare_alias" }},
    {"add" :   {"index": "shakespeare_v2", "alias": "shakespeare_alias" }}
  ]
}
'

エイリアスが変わりました。

f:id:quoll00:20150204012058p:plain

動作確認(新しいインデクス)

新しいインデクスshakespeare_v2analyzedマッピングしたので解析された要素で検索が可能です。

$ curl http://localhost:9200/shakespeare_alias/_search?pretty -d '
{
    "query": {
        "query_string": {
            "query": "Henry",
            "default_field": "line.play_name"
        }
    }
}
'

query_stringで検索して以下の結果がでます。

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 496,
    "max_score" : 0.6237512,
    "hits" : [ {
      "_index" : "shakespeare_v2",
      "_type" : "line",
      "_id" : "2",
      "_score" : 0.6237512,
      "_source":{"line_id":3,"play_name":"Henry IV","speech_number":"","line_number":"","speaker":"","text_entry":"Enter KING HENRY, LORD JOHN OF LANCASTER, the EARL of WESTMORELAND, SIR WALTER BLUNT, and others"}
    },

以上です。お疲れ様でした。

ソース