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

Elasticsearch のインデックスを再作成してみた

Elasticsearch

ローカルで Elasticsearch のインデックスを再作成する手順を試してみた.

たまに読んでる The Definitive Guide に詳しく書かれているけど,一言で言うと「エイリアスを活用して,再作成したインデックスに向き先を変える」って感じ.

  • CHAPTER 10. Index Management
    • Reindexing Your Data
    • Index Aliases and Zero Downtime

Elasticsearch: The Definitive Guide

Elasticsearch: The Definitive Guide

あと Elasticsearch の公式ブログだったり,ドキュメント版の The Definitive Guide にも似たようなことが書かれている.

ハンズオン資料をベースに

ハンズオンで使ったインデックスがローカルに残っていたのでその環境で試した.

手順

エイリアスを作成する

gourmet インデックスのエイリアスとして gourmet_alias を作成する.

➜  ~  curl http://localhost:9200/gourmet/_alias\?pretty
{
  "gourmet" : {
    "aliases" : { }
  }
}

➜  ~  curl -X PUT http://localhost:9200/gourmet/_alias/gourmet_alias
{"acknowledged":true}%

➜  ~  curl http://localhost:9200/gourmet/_alias\?pretty
{
  "gourmet" : {
    "aliases" : {
      "gourmet_alias" : { }
    }
  }
}

切り替え後のインデックスを作成する

切り替え後のインデックスとして gourmet-v2 を作成する.実運用ならここでマッピングを変えるけど,今回は簡易的に同じマッピングで進める.

➜  elasticsearch-hands-on git:(master) ✗ curl -X POST http://localhost:9200/gourmet-v2 -d @mappings/restaurants.json
{"acknowledged":true}%

Ruby Client でデータを流し込む

Ruby Client で手軽にできそうだったので試してみた.簡単!

Mac で試してるからパフォーマンスは良くないかもしれないけど,約21万ドキュメントで約4分掛かった.

[1] pry(main)> require 'tire'
true
[2] pry(main)> old_index = Tire::Index.new('gourmet')
#<Tire::Index:0x007fdb221917c0 @name="gourmet">
[3] pry(main)> old_index.reindex('gourmet-v2')
nil

ドキュメント数を確認する

全件流し込めていることが確認できる.

➜  ~  curl http://localhost:9200/_cat/count/gourmet
1443603801 18:03:21 214236

➜  ~  curl http://localhost:9200/_cat/count/gourmet-v2
1443603804 18:03:24 214236

エイリアスを切り替える

gourmet_alias の向き先を gourmet から gourmet-v2 に切り替えることで,無停止でインデックスの再作成ができたことになる.

➜  ~  curl -X POST http://localhost:9200/_aliases -d '
{
    "actions": [
        {
            "remove": {
                "index": "gourmet",
                "alias": "gourmet_alias"
            }
        },
        {
            "add": {
                "index": "gourmet-v2",
                "alias": "gourmet_alias"
            }
        }
    ]
}
'

elasticsearch-head

切り替えた後の状態を elasticsearch-head Plugin で確認してみた.ちゃんと gourmet-v2エイリアスが付いてるし,ドキュメント数も一致していることがわかる.

f:id:kakku22:20150930185748p:plain

Node.js Client でデータを流し込む

試しに elasticsearch-reindex を使って gourmet-v3 に流し込んでみようとしたけど,エラーになってしまった.詳しく調べずに諦めたけど,データ量が多すぎる?

➜  ~  elasticsearch-reindex -f http://localhost:9200/gourmet -t http://localhost:9200/gourmet-v3
events.js:397
EventEmitter.listenerCount = function(emitter, type) {
                                     ^

RangeError: Maximum call stack size exceeded
(中略)

関連エントリー