Hiveで大きめの結果ファイルをエクスポートして相手に渡す話

いろいろな部署でデータ分析するようになると「うちのデータとおまえんところのデータを結合して解析したいからデータをくれ、もしくはおれのデータをおたくのクラスタにインポートしてくれ」みたいな話が出るようになります、たぶん。

1つのHadoopクラスタにデータが全てあってみんなでそこをいじるのであればこのような話は出ない訳ですが、世の中そう話は単純ではないです。

インポート、エクスポート両方の話があると思いますが、こちらのHadoop上のデータを相手に上げる場合を考えてみます。

データ自体はHiveクエリをちょちょっと投げれば取得できます。

このときHiveクエリの結果が少量なら問題無いですが、10GBとかあったらちょっと面倒です。

というのもhiveでselectした結果をリダイレクトしても遅いですし、ちゃんとリダイレクトできているか怪しいです。

HiveServer経由だとfetchするときにOutOfMemoryになります。

相手もHadoopならdiscp使うとか相手側にもHiveテーブル用意してもらってそのテーブルのlocationでhdfs://僕のhadoopクラスタ のようにする方法もありますが、
こっちはHadoopだけど相手はRDBMSでみたいな話も出てきた場合を考えると結果をファイルでダウンロードしてもらうようにした方がいいですよね。たぶん。

で、どうしたかって話ですが、下記のようにINSERT OVERWRITE LOCAL DIRECTORYで一旦ローカルに書き出します。

INSERT OVERWRITE LOCAL DIRECTORY '...'
SELECT concat_ws('\t', a, b)
FROM …
WHERE ...

concat_wsのところは区切り文字をCtrl+Aではなくタブにするためにやってます。

こうすると出力ディレクトリに000000_0, 000001_0,,,みたいなファイルがmap数分だけ出来ます。
今回の僕のケースだとreduceが無いケースでした。

あとはこの000000_0, 000001_0,,,みたいなファイルをcatで連結しました。
000000_0, 000001_0,,,みたいなファイルを数百個相手に渡してもアレですしね。

Hiveクエリで結果ファイルを1つにするやり方が分からなかったので結局こうしました。

まあそんな感じです。