目次
※この記事は次のブログを翻訳したものになります。
原文:Reindex Elasticsearch With Logstash
Thanks David!
マッピングを変更したり、インデックスの設定を変更したり、あるサーバから他のサーバや、 あるクラスタから他のクラスタ(例えば複数のデータセンターのような場合)にデータを再インデックスしたくなることがあるでしょう。
後者のような場合はSnapshotやRestoreの機能を利用することもできますが、インデックスの設定を変更をしたい場合は その他の方法が必要になります。
Logstash 1.5.0で、 elasticsearch inputとelasticsearch outputを使うことで、とても簡単に再インデックスができます。
ではやってみましょう。
古いクラスタ
elasticsearch 1.5.2 はすでにダウンロード済みとして、localhost:9200
でold
という名前のクラスタを起動します。
bin/elasticsearch --cluster.name=old
クラスタにperson
という名前のインデックスが存在します。
これは、5シャードで、100万件のドキュメントを持っています。
新しいクラスタ
次に新しいクラスタを起動します。
localhost:9201
でnew
という名前のクラスタを起動します。
bin/elasticsearch --cluster.name=new
こちらは、空です。
curl -XGET "http://localhost:9201/person"
{
"error": "IndexMissingException[[person] missing]",
"status": 404
}
Logstashのインストール
次に、Logstash 1.5.0をダウンロードして、インストールします。
wget http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz
tar xzf logstash-1.5.0.tar.gz
cd logstash-1.5.0
logstashの設定ファイルlogstash.conf
を次のように設定します。
input {
# We read from the "old" cluster
elasticsearch {
hosts => [ "localhost" ]
port => "9200"
index => "person"
size => 500
scroll => "5m"
docinfo => true
}
}
output {
# We write to the "new" cluster
elasticsearch {
host => "localhost"
port => "9201"
protocol => "http"
index => "%{[@metadata][_index]}"
index_type => "%{[@metadata][_type]}"
document_id => "%{[@metadata][_id]}"
}
# We print dots to see it in action
stdout {
codec => "dots"
}
}
実行と修正
実行します。
bin/logstash -f logstash.conf
ドキュメントのチェックと修正
何が起きたでしょう?
curl -XGET "http://localhost:9200/person/person/AU1wqyQWZJKU8OibfxgH"
{
"_index": "person",
"_type": "person",
"_id": "AU1wqyQWZJKU8OibfxgH",
"_version": 1,
"found": true,
"_source": {
"name": "Tali Elyne",
"dateOfBirth": "1955-05-03",
"gender": "female",
"children": 2,
"marketing": {
"cars": null,
"shoes": null,
"toys": null,
"fashion": null,
"music": null,
"garden": null,
"electronic": null,
"hifi": null,
"food": 846
},
"address": {
"country": "Germany",
"zipcode": "0099",
"city": "Bonn",
"countrycode": "DE",
"location": [
7.075943707068682,
50.72883500730124
]
}
}
}
もう一方のクラスタと比較してみましょう。
curl -XGET "http://localhost:9201/person/person/AU1wqyQWZJKU8OibfxgH"
{
"_index": "person",
"_type": "person",
"_id": "AU1wqyQWZJKU8OibfxgH",
"_version": 1,
"found": true,
"_source": {
"name": "Tali Elyne",
"dateOfBirth": "1955-05-03",
"gender": "female",
"children": 2,
"marketing": {
"cars": null,
"shoes": null,
"toys": null,
"fashion": null,
"music": null,
"garden": null,
"electronic": null,
"hifi": null,
"food": 846
},
"address": {
"country": "Germany",
"zipcode": "0099",
"city": "Bonn",
"countrycode": "DE",
"location": [
7.075943707068682,
50.72883500730124
]
},
"@version": "1",
"@timestamp": "2015-05-20T09:53:44.089Z"
}
}
Logstashは@version
と@timestamp
フィールドを追加してしました。
これらを除去したいので、Mutate filter pluginのremove_field
を使います。
filter {
mutate {
remove_field => [ "@timestamp", "@version" ]
}
}
マッピングのチェックと修正
実際に、logstashは_source
フィールドを既存のドキュメントから読み込み、
それらを新しいクラスタに直接投入しています。
しかし、logstashはマッピングについてはケアしていません。
古いマッピングと新しいマッピングを比較するために、マッピングを取得してみましょう。
curl -XGET "http://localhost:9200/person/person/_mapping"
{
"person": {
"mappings": {
"person": {
"properties": {
"address": {
"properties": {
"city": {
"type": "string",
"index": "not_analyzed"
},
"country": {
"type": "string",
"index": "not_analyzed"
},
"countrycode": {
"type": "string",
"index": "not_analyzed"
},
"location": {
"type": "geo_point"
},
"zipcode": {
"type": "string"
}
}
},
"children": {
"type": "long"
},
"dateOfBirth": {
"type": "date",
"format": "dateOptionalTime"
},
"gender": {
"type": "string",
"index": "not_analyzed"
},
"marketing": {
"properties": {
"cars": {
"type": "long"
},
"electronic": {
"type": "long"
},
"fashion": {
"type": "long"
},
"food": {
"type": "long"
},
"garden": {
"type": "long"
},
"hifi": {
"type": "long"
},
"music": {
"type": "long"
},
"shoes": {
"type": "long"
},
"toys": {
"type": "long"
}
}
},
"name": {
"type": "string"
}
}
}
}
}
}
curl -XGET "http://localhost:9201/person/person/_mapping"
{
"person": {
"mappings": {
"person": {
"properties": {
"address": {
"properties": {
"city": {
"type": "string"
},
"country": {
"type": "string"
},
"countrycode": {
"type": "string"
},
"location": {
"type": "double"
},
"zipcode": {
"type": "string"
}
}
},
"children": {
"type": "long"
},
"dateOfBirth": {
"type": "date",
"format": "dateOptionalTime"
},
"gender": {
"type": "string"
},
"marketing": {
"properties": {
"cars": {
"type": "long"
},
"electronic": {
"type": "long"
},
"fashion": {
"type": "long"
},
"food": {
"type": "long"
},
"garden": {
"type": "long"
},
"hifi": {
"type": "long"
},
"music": {
"type": "long"
},
"shoes": {
"type": "long"
},
"toys": {
"type": "long"
}
}
},
"name": {
"type": "string"
}
}
}
}
}
}
これにより、いくつかの相違を発見できます。
"location": {
"type": "geo_point"
}
"location": {
"type": "double"
}
データをインデックスする「前」に、実際に利用したいマッピングでインデックスを作成しておくことで、 この問題に対処できます。 この時点で、オリジナルのマッピングを望んだ形に変更することができます。例えば、アナライザを変更したりです。 また、インデックスの設定を新しく定義することもできます。 デフォルトでは、Elasticsearchは5つのシャードと各シャードに対して1つのレプリカを作成します。 しかし、この時点でもう一度変更することが可能です。
curl -XDELETE "http://localhost:9201/person"
curl -XPUT "http://localhost:9201/person" -d'
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}'
curl -XPUT "http://localhost:9201/person/person/_mapping" -d'
{
"person": {
"properties": {
"address": {
"properties": {
"city": {
"type": "string",
"index": "not_analyzed"
},
"country": {
"type": "string",
"index": "not_analyzed"
},
"countrycode": {
"type": "string",
"index": "not_analyzed"
},
"location": {
"type": "geo_point"
},
"zipcode": {
"type": "string"
}
}
},
"children": {
"type": "long"
},
"dateOfBirth": {
"type": "date",
"format": "dateOptionalTime"
},
"gender": {
"type": "string",
"index": "not_analyzed"
},
"marketing": {
"properties": {
"cars": {
"type": "long"
},
"electronic": {
"type": "long"
},
"fashion": {
"type": "long"
},
"food": {
"type": "long"
},
"garden": {
"type": "long"
},
"hifi": {
"type": "long"
},
"music": {
"type": "long"
},
"shoes": {
"type": "long"
},
"toys": {
"type": "long"
}
}
},
"name": {
"type": "string"
}
}
}
}'
さて、もう一度再インデックスしましょう!
bin/logstash -f logstash.conf
インデックスやタイプ名の変更
もちろん、インデックス名やタイプ名、IDを変更したい場合も変更が可能です!:)
elasticsearch {
host => "localhost"
port => "9201"
protocol => "http"
index => "europe_people"
index_type => "someone"
document_id => "%{[@metadata][_id]}"
}
comments powered by Disqus
See Also by Hugo
- Elasticsearch unplugged - 2.0におけるネットワークの変更(日本語訳)
- Logstashを利用したApacheアクセスログのインポート
- 第16回Elasticsearch勉強会を開催しました。 #elasticsearchjp
- Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳)
- 第10回Elasticsearch勉強会を開催しました。#elasticsearchjp