Elasticsearchへの大量データ登録の効率化(2)
Elasticsearchの起動について
前回の記事と同様に下記でElasticsearchの起動を行います。
cd /usr/share/elasticsearch/ sh shell/elastic_search_setting.sh
並列処理を行うCodeについて
引数にJSONファイルを圧縮したjson.gzファイルを指定し、そのデータをあらかじめ起動しておいたElasticsearchに登録します。
"Content-encoding: gzip"で圧縮したデータの形式を選択しています。
if [ $# -ne 1 ]; then
echo "$0 [data name] "
exit 1
fi
JSON_GZ=$1
# -- Body ---------------------------------------------------------
# SCRIPT LOGIC GOES HERE
# Regist json bulk
curl --compressed -H "Content-encoding: gzip" -XPOST http://localhost:9200/_bulk --data-binary \
"@${JSON_GZ}" > /dev/null
# -----------------------------------------------------------------
今回は並列処理を行った場合と、そうでない場合の登録処理にかかる時間を比較するため、先に並列処理なしで登録処理を行ってみます。
# Regist json bulk
sudo chmod -R 777 ${DATA_DIR}/
ls data/*.json.gz > data/json_gz_list
cat data/json_gz_list | sh shell/elastic_regist_search_json_gz.sh
sleep 10s
# Check the regist data
curl 'localhost:9200/_cat/indices?v'
下記のようにして、実行時間を計測します。
time sh shell/elastic_regist_search_json_sequence.sh python/Data/split_data/
上記のスクリプトの実行結果が下記になります。"docs.count"の部分で登録されたドキュメント数を把握することができます。著者の環境では1分27秒かかりました。
health status index pri rep docs.count docs.deleted store.size pri.store.size green open contents-20160111 1 0 1 0 3.2kb 3.2kb yellow open wikipedia 5 1 1029447 0 410mb 410mb real 1m27.255s user 0m0.892s sys 0m0.977s
次に並列処理を行うスクリプトです。動作させるのに2つの引数を設定しています。
- パイプの数
- 並列ジョブ数
if [ $# -ne 2 ]; then
echo "$0 [PIPE_NUMBER] [PARALLEL_NUMBER]"
exit 1
fi
PIPE_NUMBER=$1
PARALLEL_NUMBER=$2
PARALLEL=/usr/local/bin/parallel
# -- Body ---------------------------------------------------------
# SCRIPT LOGIC GOES HERE
# Regist json bulk
ls data/*.json.gz > data/json_gz_list
cat data/json_gz_list | $PARALLEL --linebuffer --pipe -N $PIPE_NUMBER --round-robin -j${PIPE_NUMBER} $PARALLEL --linebuffer -j $PARALLEL_NUMBER -a - sh shell/elastic_regist_search_json_gz.sh
sleep 10s
# Check the regist data
curl 'localhost:9200/_cat/indices?v'
# -----------------------------------------------------------------
GNU parallelで行っている処理を1つずつ解説していきます。
- "--linebuffer":こちらは並列処理中の動作を確認するために標準出力に結果を出すための設定です。
- "--pipe ":こちらはデータをブロックサイズに分割してパイプ処理で行うための設定です。
- "--round-robin":データの登録順が重要でなければラウンドロビン方式ですべてのプロセスに平等に時間を与えながら動作させることが可能です。
- "-j":ジョブ数の設定です。
- "-a -":インプットのデータにファイルを指定し標準入力から入力をしています。
下記のようにして実行して実行時間を計測します。
time sh shell/elastic_regist_search_json_parallel.sh 1 10 python/Data/split_data/
上記のスクリプトの実行結果が下記になります。
health status index pri rep docs.count docs.deleted store.size pri.store.size green open contents-20160111 1 0 1 0 3.2kb 3.2kb yellow open wikipedia 5 1 1029447 0 418.5mb 418.5mb real 1m10.889s user 0m2.222s sys 0m2.252s
登録処理の実行時間が1分27秒から1分10秒に短縮ができたことを確認できました。
今回はデータのサイズを小さくしてドキュメント数も多くないので劇的な効果を発揮していませんが、ドキュメント数が増え、サイズが大きくなると効果を発揮します。
最後に
以上でElasticsearchへの大量データ登録の効率化は終わります。次回はElasticsearchから少し離れてSlack対応したBot作成を行います。
