愛と偏屈にまみれたHadoopの話(後編)
はじめに
ものすっごく久しぶりにblogを書こうと思い立ったのは、大好きだったでんぱ組.incの最上もがさんの退職エントリameblo.jp
をようやく受け入れられつつあることときっと無関係ではなくて、でもようやく新しくなったでんぱ組.incのwebサイト*1
からは喪失感しか感じないので、まだまだ立ち直るのには時間がかかるのかもしれない。
さて、そんなこんなで自分のブログみたら
で止まっていて、後編を書くのがBiSHで言うところのプロミスザスター*2なので今日はその後編を書く(下書きに7割くらい書けてたインド旅行記もあったけど、これ日の目見ることあるのかな・・・)。ちなみにこの内容は、半年ほど前に行われたBattle Conference U30というイベントで話したものです。
Hadoopは魔法ではない
ビッグデータ時代をリードするHadoopの世界第4位の開発企業であるNTTデータ様のHadoopの解説ページに記載されているHadoopの特長は
- 単純なサーバの追加によってスケーラビリティを実現
- 非定型データの格納を想定した処理の柔軟性を実現
- コモディティ品を利用した基盤構成・対障害性
で、いろんな資料でこの手の説明を見たり聞いたりすることがあるのだけど、まぁこれはHadoopというか膨大なサーバ群を売りさばくためのセールス文句なので真に受けてはいけない(Hadoopでディスクが沢山売れるようになったのに味をしめたのか、NTTデータに限らずゾウさんベンダー界隈はここ数年、今度は大量のメモリを売ろうとApache Sparkを推すのに夢中だ)。
- 単純にサーバを追加すると、ネットワーク/管理系のノードの処理負荷/予算 のいずれかでサチる
- 結局ためたデータはなんだかんだSQLで使いたくなる(特に分析用途)
- 非定型な大量データだと処理効率が上がらない
- 結果的にニーズに見合う高性能なサーバを並べたほうがトータルで安い
という、考えてみれば至極当然な結果に帰着し、世界中のゾウさん界隈のエンジニアは(能動的な)Hadoopの内部最適化に追われている。Hadoopは音楽と同様に魔法ではない*3のである。
Hadoopの現状と列指向ファイル
前編で考察したように、Hadoopはそもそも意図的にネットワークを含めたI/Oに負荷を寄せたアーキテクチャだ。これを読んでくださっているあなたのHadoopのJobが一向に終わらないのも「CPUが何か頑張る以前の、単なるファイルの読み書き」が原因である可能性が高い。ちなみにこれはHadoopに限った話ではなく、HDDへの読み書きというのはそれだけコストがかかる行為なのだ*4。
ところで、複数人が複数目的に複数回Readすることになる関係上、利用価値の高いデータはWriteよりReadのコストのほうが圧倒的に問題になる(それに対してWriteはどんなデータでも1度だ)。だからHiveやPrestoといった分析目的のSQLでのデータ利用が前提になっている昨今のHadoop界隈では、SequenceFileではなくORCやParquetに代表される列指向のファイルを使うのが常識になっている。
例えば
SELECT col2 FROM foo_table WHERE col2 = “bar”;
というクエリによるファイルアクセスを例に取ると列指向ファイルが圧倒的にREAD時に発生するI/Oを抑えることができることがご理解いただけると思う。
しかし、この列指向のファイルにも
- streamなデータ(無限に発生し続けるデータ)と相性が悪い
- ネストが深い構造のデータだと、効果が薄い
という欠点があり、そしてこれは
- いわゆるビッグデータ(ユーザの行動やサーバのアクセスログ、IoTのセンサデータ等)は典型的なStreamなデータ
- 昨今のHadoopで扱うデータのinputはApache Kafkaに代表されるメッセージ形式
- 業務ロジックを表現できる、ビジネス上活用しやすいデータは多くの場合複雑なネスト構造を持つ
という点で結構致命的だ。今回は特にstreamな入力と列指向データの相性の悪さについて注目してみたいと思う。
Streamな入力とbatch処理
そもそも、streamな入力とHadoopが得意なbatch処理(始まりと終わりのある処理)は相性が悪い。streamな入力はstreamに処理したほうが設計も実装もはるかにシンプルになる。
その一方で、SequenceFileと違い列指向のファイルへの書き込みは純粋な意味でのStreamProcessingで実装し得ない。「列毎に(圧縮しながら)書くためには、複数行をバッファリングして一度に書く」しかないからだ。
そこで、Streamな入力に対して俗に言うMicroBatchというやつが登場してくるわけだが(例えばSpark Streamingがそうだ)、これは「始まりと終りがある」という点では完全にbatchなので、開始・終了処理とかエラー処理で余計な気を回す必要が出てくるうえに、普通のStream Processingと比べlatencyで劣る事が多い。
逆に言えばBatchな入力、例えばすでにHiveのtableとして提供されているデータを加工して分析・集計用のデータマートを作るような場合には、この手の問題を気にせずに列指向フォーマットの恩恵を存分に受けることができるので、その際には積極的に列指向の出力を用いていくべきだと思う。
最後に、愛と偏屈について
結局のところ「こうやればHadoopはもっと便利になる!」みたい特効薬はまだなくて、僕のお仕事も3歩進んで2歩下がる感じがずっと続いていて、だから黄色のゾウさんの一挙一投足に優しくなったりかなしくなったりしちゃう*5んだと思ったりして、そういう意味できいろいゾウさんは最上もがさんに似ている。
ということで今日はこの曲でお別れです、もう2度とライブで聞くことはないであろうでんぱ組.inc『W.W.D 2』。
注釈等
*1:ちなみに長らくこれだった。まじでクソだと思う、21世紀に入ってもう17年も経つのに。
*2:メジャーデビュー以降で一番好きな曲かもしれない。オーケストラの風味も残しながらの、BiSHらしい名曲。このライブ、Zeppで見てたけど最高だったな・・・
*3:正直、最近彼女の歌は僕を卒業しつつある(つまり、より多くの抽象化された観衆に向けて歌っている気がする)が、同時にこれから始まる弾き語りツアーが楽しみで仕方なくはある(中野サンプラザのチケット取った)。
*4:@kumagiさんの資料の5ページ目を見るとがわかりやすいと思うが、HDDからのデータの読み出しは大西洋を往復する通信コストと1桁しか変わらない