■これまでの話

第4回Elasticsearch勉強会でElasticsearch-hadoopについて発表させて頂きましたが、その際、評価としてHiveの実行速度をHDFSをストレージとして利用した場合と比較してお見せしました。


ここらへんです。


で、ちょっといくらなんでも遅すぎるな、と思って調べていたらわかったことがあったのでメモ。

■わかったこと

結論から言うと、elasticsearch-hadoopはRead時はPrimary Shardの数しかMapタスクを生成しない。



これはelasticsearch-hadoopのここら辺のソースを読んでもわかります。

・EsInputFormat.java getSplitsメソッド

1
2
3
4
5
6
7
8
9
10
11
12
    ShardInputSplit[] splits = new ShardInputSplit[targetShards.size()];

    int index = 0;
    for (Entry<Shard, Node> entry : targetShards.entrySet()) {
        Shard shard = entry.getKey();
        Node node = entry.getValue();
        splits[index++] =
                    new ShardInputSplit(node.getIpAddress(), node.getHttpPort(), node.getId(), node.getName(), shard.getName(), savedMapping, savedSettings);
    }

    log.info(String.format("Created [%d] shard-splits", splits.length));
    return splits;

Hadoopは利用するInputFormatのgetSplitsメソッドの返り値の長さで、Mapタスク数を決定します。

このソースを見るとわかるように、Shardのsizeで配列を生成してますね。。

#Hive利用時に実際に利用するInputFormatはEsHiveInputFormatなのですが、EsHiveInputFormatのgetSplitsが内部で上記を呼び出しています。


しかし、そもそもちゃんと公式ホームページ見てみると、elasticsearch-hadoopのトップページに書いてありましたw

■じゃあ、どうすればいいのか

とりあえずは、インデックス生成の際にShardの数を多くすれば解決します。

しかし、ElasticsearchはShardの数をインデックス生成後は変更できない(はず)なので、微妙な感が否めませんが。。。

もっといい方法はないだろうか。。。

次回のElasticearch勉強会でMapRの@nagixさんから聞けたりするといいな。

■追試

前回の評価では、シャード数が6なので、6つのMapタスクしか生成されてないことになります。 実際、ログを確認したところ、生成されたMapタスク数は6でした。

一方、HDFSを利用した場合はMapタスクは12個生成されていました。


TaskTrackerは3台ともmapred.tasktracker.map.tasks.maximumを4に設定しているので、最大で12Mapを並列実行可能です。

また、サーバは4コアマシンですので、CPU的にも3台合わせて12Mapを並列実行できる計算になります。

#実際にはElasticseachとかのプロセスがCPUリソースを消費しますが


よって、HDFS利用時は12コアを使用し、elasticsearch-hadoop利用時は6コアしか使用されていないことになります。

Oh,,,ということで再度評価を行いました。

TaskTrackerとElasticsearchが同居したサーバを3台用意し(上記スライドの3番目の評価環境と同じ)、シャード数を12、レプリカ数を2でインデックスを生成して実行しました。


結果は520ms ➡ 280ms前後にまで短縮できました。

HDFS利用時の速度とはまだまだ差はありますが、少しはマシになりました。。


#そもそも1分でも十分遅いので、1分も5分もそんなに大して変わらないとかなんとか

■お詫びと訂正

スライドの10ページ目で「ドキュメント1件で1Mapタスク」とありますが、正しくはMapReduceでreadする場合もHive同様、生成されるMapタスクの数はPrimary Shardの数でした。

お詫びして訂正します。

#一番最初にドキュメント数を極小で試したのですが、その時のドキュメント数とシャード数が同じだったようです。。