ようへいの日々精進XP

よかろうもん

Elasticsearch 上のデータを割と簡単にダンプして他の Elasticsearch にインポート出来る elasticsearch-dump を使ってみた

ti;dr

VPC 内で動いている Amazon Elasticsearch Service (以後, AES) 上の一部のインデックスデータを手元の端末の Elasticsearch でも利用したいと思った時に散々悩んで調査した結果, 以下のようなツールが OSS で提供されていたので使ってみましたのでメモです.

github.com

本来ならば, Logstash を使ったりするのが順当なところなのかもしれませんが, mysqldump みたいなカジュアル利用出来るので気持ち良かったです.

taskrabbit/elasticsearch-dump

セットアップ

github.com

Node.js で実装されていて, npm install でインストールするか, Docker イメージが配布されています.

今回は, Amazon Elasticsearch Service からデータをダンプする環境では Docker イメージを利用しました.

$ docker pull taskrabbit/elasticsearch-dump

ダンプされたデータをインポートする環境では npm install でインストールしました.

$ npm install elasticdump

使い方

詳細は README をご一読頂ければと思いますが, とてもシンプルに使い始めることが出来ると思います. 以下はドキュメントより引用させて頂きました.

elasticdump \
  --input=http://production.es.com:9200/my_index \
  --output=http://staging.es.com:9200/my_index \
  --type=data
  • --input はソースとなる Elasticsearch インデックスのエンドポイント
  • --output はデータをインポートする Elasticsearch インデックスのエンドポイント
  • --type では data を指定するとデータ (Document) そのもの, --mapping を指定すると, その名の通りマッピングもインポートが可能

試しにヘルプを確認してみましたが, かなり多くのオプションが用意されており, プロキシ経由での接続もサポートされたりしているので, プロキシを介してリモートの Elasticsearch からローカルマシン上の Elasticsearch へのデータ移行もカジュアルに行えると思います.

$ elasticdump --help

さて

今回は

以下のようなステップでダンプ, インポートを行いました.

  1. VPC 上の AES にアクセス出来るホストで elasticsearch-dump Docker コンテナを利用してダンプ
  2. ダンプしたデータを SCP でローカルマシンにダウンロード
  3. ローカルマシン上に Elasticsearch を起動
  4. 起動した Elasticsearch にダンプしたデータをインポート
  5. データを確認

ダンプ (松本)

AES にアクセス出来るホスト (EC2 インスタンス) 上にて, 以下のように実行しました.

$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D1 \
  --output=/tmp/cwl-YYYY.MM.D1.json \
  --type=data
$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D2 \
  --output=/tmp/cwl-YYYY.MM.D2.json \
  --type=data
$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D3 \
  --output=/tmp/cwl-YYYY.MM.D3.json \
  --type=data

ホスト上の /tmp/data 以下に cwl-YYYY.MM.D1.json から cwl-YYYY.MM.D3.json が生成されます.

尚, マッピングテンプレートもダンプすることが可能ですので, 必要に応じてダンプしておきましょう.

$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/template \
  --output=/tmp/template.json \
  --type=template

インポート

ホスト上のデータを何らかの方法 (自分は SCP を使いました) で取得し, 以下のようにデータをインポートします. インデックスへのマッピングの適用が必要な場合には, 事前にマッピングもンポートしておきましょう.

$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D1.json --output=http://localhost:9200/cwl-YYYY.MM.D1 --type=data
$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D2.json --output=http://localhost:9200/cwl-YYYY.MM.D2 --type=data
$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D3.json --output=http://localhost:9200/cwl-YYYY.MM.D3 --type=data

データ確認

以下のようにインデックスとして登録されていることを確認しました.

f:id:inokara:20200502073847p:plain

良い感じですね.

hits.total あたりを確認してみます.

$ curl -s -H "Content-Type: application/json" localhost:9200/cwl-YYYY.MM.D1/_search -d '
{
   "query": { "match_all": {} }
}' | jq .hits.total
4184

良い感じですね.

以上

このツールに出会うまで, 色々と試行錯誤しました. 一旦, データを CSV で書き出しておいて, インポートのスクリプトを書こうとしたり, ローカルマシンから直接 VPC 内の AES にアクセスする為にプロキシサーバーを立てようとしたり... だいぶん疲弊したところに出会った elasticsearch-dump はまさに神ツールでした.

作者の方には感謝しかありません. ありがとうございました.